Home | History | Annotate | Download | only in builders
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Eclipse Public License, Version 1.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.eclipse.org/org/documents/epl-v10.php
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.ide.eclipse.adt.internal.build.builders;
     18 
     19 import com.android.ide.eclipse.adt.AdtPlugin;
     20 import com.android.ide.eclipse.adt.internal.build.BuildHelper;
     21 
     22 import org.eclipse.core.resources.IFolder;
     23 import org.eclipse.core.resources.IProject;
     24 import org.eclipse.core.resources.IResource;
     25 import org.eclipse.core.resources.IResourceDelta;
     26 import org.eclipse.core.resources.IResourceDeltaVisitor;
     27 import org.eclipse.core.runtime.CoreException;
     28 import org.eclipse.core.runtime.IPath;
     29 import org.eclipse.core.runtime.IStatus;
     30 
     31 import java.util.ArrayList;
     32 import java.util.IdentityHashMap;
     33 import java.util.List;
     34 import java.util.Map;
     35 
     36 /**
     37  * Delta visitor checking changed files against given glob-patterns.
     38  *
     39  * The visitor is given {@link ChangedFileSet} objects which contains patterns to detect change
     40  * in input and output files. (Output files are only tested if the delta indicate the file
     41  * was removed).
     42  *
     43  * After the visitor has visited the whole delta, it can be queried to see which ChangedFileSet
     44  * recognized a file change. (ChangedFileSet are immutable and do not record this info).
     45  */
     46 class PatternBasedDeltaVisitor implements IResourceDeltaVisitor {
     47 
     48     private final static boolean DEBUG_LOG = "1".equals(              //$NON-NLS-1$
     49             System.getenv("ANDROID_VISITOR_DEBUG"));                  //$NON-NLS-1$
     50 
     51     private final IProject mMainProject;
     52     private final IProject mDeltaProject;
     53 
     54     private final List<ChangedFileSet> mSets = new ArrayList<ChangedFileSet>();
     55     private final Map<ChangedFileSet, Boolean> mResults =
     56             new IdentityHashMap<ChangedFileSet, Boolean>();
     57 
     58     private final String mLogName;
     59 
     60     PatternBasedDeltaVisitor(IProject mainProject, IProject deltaProject, String logName) {
     61         mMainProject = mainProject;
     62         mDeltaProject = deltaProject;
     63         mLogName = logName;
     64         if (DEBUG_LOG) {
     65             AdtPlugin.log(IStatus.INFO, "%s (%s): Delta for %s",               //$NON-NLS-1$
     66                     mMainProject.getName(), mLogName, mDeltaProject.getName());
     67         }
     68     }
     69 
     70     void addSet(ChangedFileSet bundle) {
     71         mSets.add(bundle);
     72     }
     73 
     74     boolean checkSet(ChangedFileSet bundle) {
     75         Boolean r = mResults.get(bundle);
     76         if (r != null) {
     77             return r.booleanValue();
     78         }
     79 
     80         return false;
     81     }
     82 
     83     @Override
     84     public boolean visit(IResourceDelta delta) throws CoreException {
     85         IResource resource = delta.getResource();
     86 
     87         if (resource.getType() == IResource.FOLDER) {
     88             // always visit the subfolders, unless the folder is not to be included
     89             return BuildHelper.checkFolderForPackaging((IFolder)resource);
     90 
     91         } else if (resource.getType() == IResource.FILE) {
     92             IPath path = resource.getFullPath().makeRelativeTo(mDeltaProject.getFullPath());
     93             String pathStr = path.toString();
     94 
     95             // FIXME: no need to loop through all the sets once they have all said they need something (return false below and above)
     96             for (ChangedFileSet set : mSets) {
     97                 // FIXME: should ignore sets that have already returned true.
     98 
     99                 if (set.isInput(pathStr, path)) {
    100                     mResults.put(set, Boolean.TRUE);
    101 
    102                     if (DEBUG_LOG) {
    103                         String cfs_logName = set.getLogName();
    104 
    105                         if (cfs_logName != null) {
    106                             AdtPlugin.log(IStatus.INFO, "%s (%s:%s): %s",              //$NON-NLS-1$
    107                                     mMainProject.getName(), mLogName, cfs_logName,
    108                                     resource.getFullPath().toString());
    109                         } else {
    110                             AdtPlugin.log(IStatus.INFO, "%s (%s): %s",                 //$NON-NLS-1$
    111                                     mMainProject.getName(), mLogName,
    112                                     resource.getFullPath().toString());
    113                         }
    114                     }
    115 
    116                 } else if (delta.getKind() == IResourceDelta.REMOVED &&
    117                         set.isOutput(pathStr, path)) {
    118                     mResults.put(set, Boolean.TRUE);
    119 
    120                     if (DEBUG_LOG) {
    121                         String cfs_logName = set.getLogName();
    122 
    123                         if (cfs_logName != null) {
    124                             AdtPlugin.log(IStatus.INFO, "%s (%s:%s): %s",              //$NON-NLS-1$
    125                                     mMainProject.getName(), mLogName, cfs_logName,
    126                                     resource.getFullPath().toString());
    127                         } else {
    128                             AdtPlugin.log(IStatus.INFO, "%s (%s): %s",                 //$NON-NLS-1$
    129                                     mMainProject.getName(), mLogName,
    130                                     resource.getFullPath().toString());
    131                         }
    132                     }
    133                 }
    134             }
    135         }
    136 
    137         return true;
    138     }
    139 }
    140