diff options
author | Josiah Gaskin <josiahgaskin@google.com> | 2011-08-02 13:02:07 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2011-08-02 13:02:07 -0700 |
commit | 8651dc6544f46ef0dc001946c9606d53cb40cab9 (patch) | |
tree | 10e06a1383d8ebf803e7ec395cb547c12ca7e81b /eclipse/plugins/com.android.ide.eclipse.adt | |
parent | 74542d2f169ffc9dd7ad56c1ba6b7b5cf152adcb (diff) | |
parent | 71a45a665af932984fd996027a9df2d09f5068aa (diff) | |
download | sdk-8651dc6544f46ef0dc001946c9606d53cb40cab9.zip sdk-8651dc6544f46ef0dc001946c9606d53cb40cab9.tar.gz sdk-8651dc6544f46ef0dc001946c9606d53cb40cab9.tar.bz2 |
Merge "ADT Resource Repo stores IDs and Called Once"
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt')
5 files changed, 208 insertions, 203 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java index 672995f..0163401 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java @@ -30,6 +30,7 @@ import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; import com.android.ide.eclipse.adt.internal.project.FixLaunchConfig; import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.BasicXmlErrorListener; +import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; import com.android.ide.eclipse.adt.internal.sdk.ProjectState; import com.android.ide.eclipse.adt.internal.sdk.Sdk; import com.android.ide.eclipse.adt.io.IFileWrapper; @@ -253,6 +254,8 @@ public class PreCompilerBuilder extends BaseBuilder { } else { dv = new PreCompilerDeltaVisitor(this, sourceFolderPathList, mProcessors); delta.accept(dv); + // Notify the ResourceManager: + ResourceManager.getInstance().processDelta(delta); // record the state mMustCompileResources |= dv.getCompileResources(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java index 172f471..c917d1c 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java @@ -17,8 +17,8 @@ package com.android.ide.eclipse.adt.internal.resources.manager; import com.android.ide.common.resources.IntArrayWrapper; -import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.AdtConstants; +import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.project.AndroidManifestHelper; import com.android.ide.eclipse.adt.internal.project.ProjectHelper; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener; @@ -32,6 +32,7 @@ import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; @@ -78,7 +79,9 @@ public final class CompiledResourcesMonitor implements IFileListener, IProjectLi * @see IFileListener#fileChanged */ public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) { - if (file.getName().equals(AdtConstants.FN_COMPILED_RESOURCE_CLASS)) { + // Don't execute if we're autobuilding, let the precompiler take care of the delta + if (file.getName().equals(AdtConstants.FN_COMPILED_RESOURCE_CLASS) + && ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding() == false) { loadAndParseRClass(file.getProject()); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/GlobalProjectMonitor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/GlobalProjectMonitor.java index cc615ec..f2e6485 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/GlobalProjectMonitor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/GlobalProjectMonitor.java @@ -131,6 +131,14 @@ public final class GlobalProjectMonitor { } /** + * Interface for a listener that gets passed the raw delta without processing. + * + */ + public interface IRawDeltaListener { + public void visitDelta(IResourceDelta delta); + } + + /** * Base listener bundle to associate a listener to an event mask. */ private static class ListenerBundle { @@ -176,6 +184,9 @@ public final class GlobalProjectMonitor { private final ArrayList<IResourceEventListener> mEventListeners = new ArrayList<IResourceEventListener>(); + private final ArrayList<IRawDeltaListener> mRawDeltaListeners = + new ArrayList<IRawDeltaListener>(); + private IWorkspace mWorkspace; /** @@ -184,6 +195,11 @@ public final class GlobalProjectMonitor { private final class DeltaVisitor implements IResourceDeltaVisitor { public boolean visit(IResourceDelta delta) { + // notify the raw delta listeners + for (IRawDeltaListener listener : mRawDeltaListeners) { + listener.visitDelta(delta); + } + // Find the other resource listeners to notify IResource r = delta.getResource(); int type = r.getType(); if (type == IResource.FILE) { @@ -395,7 +411,23 @@ public final class GlobalProjectMonitor { mEventListeners.remove(listener); } - private IResourceChangeListener mResourceChangeListener = new IResourceChangeListener() { + /** + * Adds a raw delta listener. + * @param listener The listener to receive the deltas. + */ + public synchronized void addRawDeltaListener(IRawDeltaListener listener) { + mRawDeltaListeners.add(listener); + } + + /** + * Removes an existing Raw Delta listener. + * @param listener the listener to remove. + */ + public synchronized void removeRawDeltaListener(IRawDeltaListener listener) { + mRawDeltaListeners.remove(listener); + } + + private final IResourceChangeListener mResourceChangeListener = new IResourceChangeListener() { /** * Processes the workspace resource change events. * diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java index ec8b717..6d15f89 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java @@ -17,7 +17,6 @@ package com.android.ide.eclipse.adt.internal.resources.manager; import com.android.ide.common.rendering.api.ResourceValue; -import com.android.ide.common.resources.InlineResourceItem; import com.android.ide.common.resources.IntArrayWrapper; import com.android.ide.common.resources.ResourceFolder; import com.android.ide.common.resources.ResourceItem; @@ -32,7 +31,6 @@ import com.android.util.Pair; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; -import java.util.ArrayList; import java.util.EnumMap; import java.util.HashMap; import java.util.List; @@ -290,74 +288,5 @@ public class ProjectResources extends ResourceRepository { mResourceValueMap = resourceValueMap; mResIdValueToNameMap = resIdValueToNameMap; mStyleableValueToNameMap = styleableValueMap; - mergeIdResources(); - } - - @Override - protected void postUpdate() { - super.postUpdate(); - mergeIdResources(); - } - - /** - * Merges the list of ID resource coming from R.java and the list of ID resources - * coming from XML declaration into the cached list {@link #mIdResourceList}. - */ - void mergeIdResources() { - if (mResourceValueMap == null) { - return; - } - - // get the current ID values - List<ResourceItem> resources = mResourceMap.get(ResourceType.ID); - - // get the ID values coming from the R class. - Map<String, Integer> rResources = mResourceValueMap.get(ResourceType.ID); - - if (rResources != null) { - Map<String, Integer> copy; - - if (resources == null) { - resources = new ArrayList<ResourceItem>(rResources.entrySet().size()); - mResourceMap.put(ResourceType.ID, resources); - copy = rResources; - } else { - // make a copy of the compiled Resources. - // As we loop on the full resources, we'll check with this copy map and remove - // from it all the resources we find in the full list. - // At the end, whatever is in the copy of the compile list is not in the full map, - // and should be added as inlined resource items. - copy = new HashMap<String, Integer>(rResources); - - for (int i = 0 ; i < resources.size(); ) { - ResourceItem item = resources.get(i); - String name = item.getName(); - if (item.isDeclaredInline()) { - // This ID is declared inline in the full resource map. - // Check if it's also in the compiled version, in which case we can keep it. - // Otherwise, if it doesn't exist in the compiled map, remove it from the - // full map. - // Since we're going to remove it from the copy map either way, we can use - // remove to test if it's there - if (copy.remove(name) != null) { - // there is a match in the compiled list, do nothing, keep current one. - i++; - } else { - // the ID is now gone, remove it from the list - resources.remove(i); - } - } else { - // not an inline item, remove it from the copy. - copy.remove(name); - i++; - } - } - } - - // now add what's left in copy to the list - for (String name : copy.keySet()) { - resources.add(new InlineResourceItem(name)); - } - } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java index 7935800..c014601 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java @@ -23,9 +23,8 @@ import com.android.ide.common.resources.ResourceRepository; import com.android.ide.eclipse.adt.AdtConstants; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.internal.resources.ResourceHelper; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFolderListener; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IProjectListener; +import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IRawDeltaListener; import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IResourceEventListener; import com.android.ide.eclipse.adt.io.IFileWrapper; import com.android.ide.eclipse.adt.io.IFolderWrapper; @@ -41,6 +40,8 @@ import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IResourceDeltaVisitor; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -111,10 +112,7 @@ public final class ResourceManager { public static void setup(GlobalProjectMonitor monitor) { monitor.addResourceEventListener(sThis.mResourceEventListener); monitor.addProjectListener(sThis.mProjectListener); - - int mask = IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED; - monitor.addFolderListener(sThis.mFolderListener, mask); - monitor.addFileListener(sThis.mFileListener, mask); + monitor.addRawDeltaListener(sThis.mRawDeltaListener); CompiledResourcesMonitor.setupMonitor(monitor); } @@ -157,6 +155,45 @@ public final class ResourceManager { } } + /** + * Update the resource repository with a delta + * @param delta the resource changed delta to process. + */ + public void processDelta(IResourceDelta delta) { + // Skip over deltas that don't fit our mask + int mask = IResourceDelta.ADDED | IResourceDelta.REMOVED | IResourceDelta.CHANGED; + int kind = delta.getKind(); + if ( (mask & kind) == 0) { + return; + } + // If our delta was handed to us from the PreCompiler then it's a single delta + // with lots of children. GlobalProjectMonitor will hand us a delta for each + // item in the tree of modifications so we only need to recurse into delta + // children if we're autobuilding. + if (ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding()) { + IResourceDelta[] children = delta.getAffectedChildren(); + for (IResourceDelta child : children) { + processDelta(child); + } + } + + // Process this delta + IResource r = delta.getResource(); + int type = r.getType(); + + if (type == IResource.FILE) { + updateFile((IFile)r, delta.getMarkerDeltas(), kind); + } else if (type == IResource.FOLDER) { + updateFolder((IFolder)r, kind); + } // We only care about files and folders. + // Project deltas are handled by our project listener + } + + /** + * Private implementation of a resource event listener that registers with + * GlobalProjectMonitor. + * + */ private class ResourceEventListener implements IResourceEventListener { private final List<IProject> mChangedProjects = new ArrayList<IProject>(); @@ -166,8 +203,6 @@ public final class ResourceManager { synchronized (mMap) { resources = mMap.get(project); } - - resources.postUpdate(); } mChangedProjects.clear(); @@ -188,160 +223,150 @@ public final class ResourceManager { * Delegate listener for resource changes. This is called before and after any calls to the * project and file listeners (for a given resource change event). */ - private ResourceEventListener mResourceEventListener = new ResourceEventListener(); - + private final ResourceEventListener mResourceEventListener = new ResourceEventListener(); /** - * Implementation of the {@link IFolderListener} as an internal class so that the methods - * do not appear in the public API of {@link ResourceManager}. + * Update a resource folder that we know about + * @param folder the folder that was updated + * @param kind the delta type (added/removed/updated) */ - private IFolderListener mFolderListener = new IFolderListener() { - public void folderChanged(IFolder folder, int kind) { - ProjectResources resources; + private void updateFolder(IFolder folder, int kind) { + ProjectResources resources; - final IProject project = folder.getProject(); + final IProject project = folder.getProject(); - try { - if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) { - return; - } - } catch (CoreException e) { - // can't get the project nature? return! + try { + if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) { return; } + } catch (CoreException e) { + // can't get the project nature? return! + return; + } - mResourceEventListener.addProject(project); + mResourceEventListener.addProject(project); - switch (kind) { - case IResourceDelta.ADDED: - // checks if the folder is under res. - IPath path = folder.getFullPath(); - - // the path will be project/res/<something> - if (path.segmentCount() == 3) { - if (isInResFolder(path)) { - // get the project and its resource object. - synchronized (mMap) { - resources = mMap.get(project); - - // if it doesn't exist, we create it. - if (resources == null) { - resources = new ProjectResources(project); - mMap.put(project, resources); - } - } + switch (kind) { + case IResourceDelta.ADDED: + // checks if the folder is under res. + IPath path = folder.getFullPath(); - ResourceFolder newFolder = resources.processFolder( - new IFolderWrapper(folder)); - if (newFolder != null) { - notifyListenerOnFolderChange(project, newFolder, kind); + // the path will be project/res/<something> + if (path.segmentCount() == 3) { + if (isInResFolder(path)) { + // get the project and its resource object. + synchronized (mMap) { + resources = mMap.get(project); + + // if it doesn't exist, we create it. + if (resources == null) { + resources = new ProjectResources(project); + mMap.put(project, resources); } } - } - break; - case IResourceDelta.CHANGED: - // only call the listeners. - synchronized (mMap) { - resources = mMap.get(folder.getProject()); - } - if (resources != null) { - ResourceFolder resFolder = resources.getResourceFolder(folder); - if (resFolder != null) { - notifyListenerOnFolderChange(project, resFolder, kind); - } - } - break; - case IResourceDelta.REMOVED: - synchronized (mMap) { - resources = mMap.get(folder.getProject()); - } - if (resources != null) { - // lets get the folder type - ResourceFolderType type = ResourceFolderType.getFolderType( - folder.getName()); - ResourceFolder removedFolder = resources.removeFolder(type, + ResourceFolder newFolder = resources.processFolder( new IFolderWrapper(folder)); - if (removedFolder != null) { - notifyListenerOnFolderChange(project, removedFolder, kind); + if (newFolder != null) { + notifyListenerOnFolderChange(project, newFolder, kind); } } - break; - } + } + break; + case IResourceDelta.CHANGED: + // only call the listeners. + synchronized (mMap) { + resources = mMap.get(folder.getProject()); + } + if (resources != null) { + ResourceFolder resFolder = resources.getResourceFolder(folder); + if (resFolder != null) { + notifyListenerOnFolderChange(project, resFolder, kind); + } + } + break; + case IResourceDelta.REMOVED: + synchronized (mMap) { + resources = mMap.get(folder.getProject()); + } + if (resources != null) { + // lets get the folder type + ResourceFolderType type = ResourceFolderType.getFolderType( + folder.getName()); + + ResourceFolder removedFolder = resources.removeFolder(type, + new IFolderWrapper(folder)); + if (removedFolder != null) { + notifyListenerOnFolderChange(project, removedFolder, kind); + } + } + break; } - }; + } /** - * Implementation of the {@link IFileListener} as an internal class so that the methods - * do not appear in the public API of {@link ResourceManager}. + * Called when a delta indicates that a file has changed. + * Depending on the file being changed, and the type of change + * (ADDED, REMOVED, CHANGED), the file change is processed to update the resource + * manager data. + * + * @param file The file that changed. + * @param markerDeltas The marker deltas for the file. + * @param kind The change kind. This is equivalent to + * {@link IResourceDelta#accept(IResourceDeltaVisitor)} */ - private IFileListener mFileListener = new IFileListener() { - /* (non-Javadoc) - * Sent when a file changed. Depending on the file being changed, and the type of change - * (ADDED, REMOVED, CHANGED), the file change is processed to update the resource - * manager data. - * - * @param file The file that changed. - * @param markerDeltas The marker deltas for the file. - * @param kind The change kind. This is equivalent to - * {@link IResourceDelta#accept(IResourceDeltaVisitor)} - * - * @see IFileListener#fileChanged - */ - public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) { - final IProject project = file.getProject(); + private void updateFile(IFile file, IMarkerDelta[] markerDeltas, int kind) { + final IProject project = file.getProject(); - try { - if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) { - return; - } - } catch (CoreException e) { - // can't get the project nature? return! + try { + if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) { return; } + } catch (CoreException e) { + // can't get the project nature? return! + return; + } - // get the project resources - ProjectResources resources; - synchronized (mMap) { - resources = mMap.get(project); - } + // get the project resources + ProjectResources resources; + synchronized (mMap) { + resources = mMap.get(project); + } - if (resources == null) { - return; - } + if (resources == null) { + return; + } - // checks if the file is under res/something. - IPath path = file.getFullPath(); - - if (path.segmentCount() == 4) { - if (isInResFolder(path)) { - IContainer container = file.getParent(); - if (container instanceof IFolder) { - - ResourceFolder folder = resources.getResourceFolder( - (IFolder)container); - - // folder can be null as when the whole folder is deleted, the - // REMOVED event for the folder comes first. In this case, the - // folder will have taken care of things. - if (folder != null) { - ResourceFile resFile = folder.processFile( - new IFileWrapper(file), - ResourceHelper.getResourceDeltaKind(kind)); - notifyListenerOnFileChange(project, resFile, kind); - } + // checks if the file is under res/something. + IPath path = file.getFullPath(); + + if (path.segmentCount() == 4) { + if (isInResFolder(path)) { + IContainer container = file.getParent(); + if (container instanceof IFolder) { + + ResourceFolder folder = resources.getResourceFolder( + (IFolder)container); + + // folder can be null as when the whole folder is deleted, the + // REMOVED event for the folder comes first. In this case, the + // folder will have taken care of things. + if (folder != null) { + ResourceFile resFile = folder.processFile( + new IFileWrapper(file), + ResourceHelper.getResourceDeltaKind(kind)); + notifyListenerOnFileChange(project, resFile, kind); } } } } - }; - + } /** * Implementation of the {@link IProjectListener} as an internal class so that the methods * do not appear in the public API of {@link ResourceManager}. */ - private IProjectListener mProjectListener = new IProjectListener() { + private final IProjectListener mProjectListener = new IProjectListener() { public void projectClosed(IProject project) { synchronized (mMap) { mMap.remove(project); @@ -368,6 +393,21 @@ public final class ResourceManager { }; /** + * Implementation of {@link IRawDeltaListener} as an internal class so that the methods + * do not appear in the public API of {@link ResourceManager}. Delta processing can be + * accessed through the {@link ResourceManager#visitDelta(IResourceDelta delta)} method. + */ + private final IRawDeltaListener mRawDeltaListener = new IRawDeltaListener() { + public void visitDelta(IResourceDelta delta) { + // If we're autobuilding, then PreCompilerBuilder will pass us deltas + if (ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding()) { + return; + } + processDelta(delta); + } + }; + + /** * Returns the {@link ResourceFolder} for the given file or <code>null</code> if none exists. */ public ResourceFolder getResourceFolder(IFile file) { @@ -475,8 +515,6 @@ public final class ResourceManager { } } } - - projectResources.postUpdate(); } catch (CoreException e) { // This happens if the project is closed or if the folder doesn't exist. // Since we already test for that, we can ignore this exception. |