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 PatternBasedDeltaVisitor(IProject mainProject, IProject deltaProject, String logName)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 addSet(ChangedFileSet bundle)70 void addSet(ChangedFileSet bundle) { 71 mSets.add(bundle); 72 } 73 checkSet(ChangedFileSet bundle)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 visit(IResourceDelta delta)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