diff options
author | Tor Norbye <tnorbye@google.com> | 2011-09-02 10:40:57 -0700 |
---|---|---|
committer | Tor Norbye <tnorbye@google.com> | 2011-09-02 12:25:51 -0700 |
commit | 6a41615061dab508e87cbb18f005c5f7edb79dbd (patch) | |
tree | 86f1ae41cb5868491589fe2bae77516872527973 /ide_common/src/com/android/ide/common/resources/ResourceRepository.java | |
parent | 0c96c744e157c450f7d66bf62f9d569b9514e747 (diff) | |
download | sdk-6a41615061dab508e87cbb18f005c5f7edb79dbd.zip sdk-6a41615061dab508e87cbb18f005c5f7edb79dbd.tar.gz sdk-6a41615061dab508e87cbb18f005c5f7edb79dbd.tar.bz2 |
Clean up layout and menu file scanning code
This changeset fixes some issues around the new lazy scanning of
layout and menu files.
First, it partly fixes "19657: AAPT errors aren't shown when adding an
error to a valid XML file". With the new optimization of not running
aapt on layout files where no ids have changed, we would no longer
pick up changes where an invalid or nonexistent resource is added. We
now perform some basic validation of resources as well as XML parsing
errors.
Second, it fixes a bug in the id before and after comparison used to
determine if aapt needs to run: The code would call map.keySet()
before and after the ids were added, but this resolved to the same
keyset so the equals comparison was always true regardless of the
content.
Third, it fixes an infinite loop issue with library projects, and
avoids doing unnecessary classpath modifications when there are no
changed projects.
Finally, it changes the "needsId" flag. The state of whether aapt
needs to be run was stored per repository, and there is a bug where it
does not get cleared properly which can yield a compilation loop. This
changeset introduces a new "ScanningContext" object which is passed
down to the various resource file updater methods. This context object
now holds the needsId state object (which is renamed to
"needsFullAapt"), and it is also the object where errors can be
registered.
Change-Id: I5632612c2d93e2f10f0803e9223921adb67602be
Diffstat (limited to 'ide_common/src/com/android/ide/common/resources/ResourceRepository.java')
-rw-r--r-- | ide_common/src/com/android/ide/common/resources/ResourceRepository.java | 88 |
1 files changed, 60 insertions, 28 deletions
diff --git a/ide_common/src/com/android/ide/common/resources/ResourceRepository.java b/ide_common/src/com/android/ide/common/resources/ResourceRepository.java index 4af4a1a..d78f1d1 100644 --- a/ide_common/src/com/android/ide/common/resources/ResourceRepository.java +++ b/ide_common/src/com/android/ide/common/resources/ResourceRepository.java @@ -68,8 +68,6 @@ public abstract class ResourceRepository { protected final IntArrayWrapper mWrapper = new IntArrayWrapper(null); - private boolean mNeedsIdRefresh; - /** * Makes a resource repository * @param isFrameworkRepository whether the repository is for framework resources. @@ -129,7 +127,8 @@ public abstract class ResourceRepository { * @param removedFolder the IAbstractFolder object. * @return the {@link ResourceFolder} that was removed, or null if no matches were found. */ - public ResourceFolder removeFolder(ResourceFolderType type, IAbstractFolder removedFolder) { + public ResourceFolder removeFolder(ResourceFolderType type, IAbstractFolder removedFolder, + ScanningContext context) { // get the list of folders for the resource type. List<ResourceFolder> list = mFolderMap.get(type); @@ -143,7 +142,7 @@ public abstract class ResourceRepository { list.remove(i); // remove its content - resFolder.dispose(); + resFolder.dispose(context); return resFolder; } @@ -154,6 +153,60 @@ public abstract class ResourceRepository { } /** + * Returns true if this resource repository contains a resource of the given + * name. + * + * @param url the resource URL + * @return true if the resource is known + */ + public boolean hasResourceItem(String url) { + assert url.startsWith("@") : url; + + int typeEnd = url.indexOf('/', 1); + if (typeEnd != -1) { + int nameBegin = typeEnd + 1; + + // Skip @ and @+ + int typeBegin = url.startsWith("@+") ? 2 : 1; //$NON-NLS-1$ + + int colon = url.lastIndexOf(':', typeEnd); + if (colon != -1) { + typeBegin = colon + 1; + } + String typeName = url.substring(typeBegin, typeEnd); + ResourceType type = ResourceType.getEnum(typeName); + if (type != null) { + String name = url.substring(nameBegin); + return hasResourceItem(type, name); + } + } + + return false; + } + + /** + * Returns true if this resource repository contains a resource of the given + * name. + * + * @param type the type of resource to look up + * @param name the name of the resource + * @return true if the resource is known + */ + public boolean hasResourceItem(ResourceType type, String name) { + List<ResourceItem> list = mResourceMap.get(type); + + if (list != null) { + for (ResourceItem item : list) { + if (name.equals(item.getName())) { + return true; + } + } + } + + return false; + } + + /** * Returns a {@link ResourceItem} matching the given {@link ResourceType} and name. If none * exist, it creates one. * @@ -196,29 +249,6 @@ public abstract class ResourceRepository { protected abstract ResourceItem createResourceItem(String name); /** - * Sets a flag which determines whether aapt needs to be run to regenerate resource IDs - */ - protected void markForIdRefresh() { - mNeedsIdRefresh = true; - } - - /** - * Returns whether this repository has been marked as "dirty"; if one or more of the constituent - * files have declared that the resource item names that they provide have changed. - */ - public boolean needsIdRefresh() { - return mNeedsIdRefresh; - } - - /** - * Indicates that the resources IDs have been regenerated, so the repository is now in a clean - * state - */ - public void setIdsRefreshed() { - mNeedsIdRefresh = false; - } - - /** * Processes a folder and adds it to the list of existing folders. * @param folder the folder to process * @return the ResourceFolder created from this folder, or null if the process failed. @@ -496,6 +526,8 @@ public abstract class ResourceRepository { */ public void loadResources(IAbstractFolder rootFolder) throws IOException { + ScanningContext context = new ScanningContext(this); + IAbstractResource[] files = rootFolder.listMembers(); for (IAbstractResource file : files) { if (file instanceof IAbstractFolder) { @@ -509,7 +541,7 @@ public abstract class ResourceRepository { for (IAbstractResource childRes : children) { if (childRes instanceof IAbstractFile) { resFolder.processFile((IAbstractFile) childRes, - ResourceDeltaKind.ADDED); + ResourceDeltaKind.ADDED, context); } } } |