aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2012-10-10 12:37:54 -0700
committerXavier Ducrohet <xav@android.com>2012-10-10 13:24:05 -0700
commit0072bac9da2f60fec9c7f48b17aafd1705094505 (patch)
tree6fa5a2d6763064124b236094817f4ccc1d693259
parentc5fce2e12268c60332b7011cee8c1081ad424950 (diff)
downloadsdk-0072bac9da2f60fec9c7f48b17aafd1705094505.tar.gz
Lazy loading (and reloading) of project resources.
Change-Id: I4a725d523ae14ba8b487076e230fe9d622d5d281
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/builders/PreCompilerBuilder.java15
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ProjectResources.java14
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java75
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java11
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/resources/platform/AttributeInfoTest.java15
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java16
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/Mocks.java13
-rwxr-xr-xsdk_common/src/com/android/ide/common/resources/FrameworkResources.java8
-rwxr-xr-xsdk_common/src/com/android/ide/common/resources/ResourceRepository.java148
9 files changed, 188 insertions, 127 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 5183658bf..73d183cec 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
@@ -323,17 +323,22 @@ public class PreCompilerBuilder extends BaseBuilder {
// Notify the ResourceManager:
ResourceManager resManager = ResourceManager.getInstance();
- ProjectResources projectResources = resManager.getProjectResources(project);
if (ResourceManager.isAutoBuilding()) {
+ ProjectResources projectResources = resManager.getProjectResources(project);
+
IdeScanningContext context = new IdeScanningContext(projectResources,
project, true);
- resManager.processDelta(delta, context);
+ boolean wasCleared = projectResources.ensureInitialized();
+
+ if (!wasCleared) {
+ resManager.processDelta(delta, context);
+ }
// Check whether this project or its dependencies (libraries) have
// resources that need compilation
- if (context.needsFullAapt()) {
+ if (wasCleared || context.needsFullAapt()) {
mMustCompileResources = true;
// Must also call markAaptRequested on the project to not just
@@ -735,6 +740,10 @@ public class PreCompilerBuilder extends BaseBuilder {
// Also clean up lint
EclipseLintClient.clearMarkers(project);
+
+ // clean the project repo
+ ProjectResources res = ResourceManager.getInstance().getProjectResources(project);
+ res.clear();
}
@Override
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 ccd16664a..68c225712 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
@@ -16,6 +16,7 @@
package com.android.ide.eclipse.adt.internal.resources.manager;
+import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.resources.IntArrayWrapper;
@@ -26,6 +27,7 @@ import com.android.ide.common.resources.configuration.FolderConfiguration;
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.IFolderWrapper;
+import com.android.io.IAbstractFolder;
import com.android.resources.ResourceType;
import com.android.util.Pair;
@@ -48,6 +50,7 @@ import java.util.Map.Entry;
* on the fly.</li>
*</ul>
*/
+@SuppressWarnings("deprecation")
public class ProjectResources extends ResourceRepository {
// project resources are defined as 0x7FXX#### where XX is the resource type (layout, drawable,
// etc...). Using FF as the type allows for 255 resource types before we get a collision
@@ -65,12 +68,18 @@ public class ProjectResources extends ResourceRepository {
private final IProject mProject;
+ public static ProjectResources create(IProject project) {
+ IFolder resFolder = project.getFolder(SdkConstants.FD_RESOURCES);
+
+ return new ProjectResources(project, new IFolderWrapper(resFolder));
+ }
+
/**
* Makes a ProjectResources for a given <var>project</var>.
* @param project the project.
*/
- public ProjectResources(IProject project) {
- super(false /*isFrameworkRepository*/);
+ private ProjectResources(IProject project, IAbstractFolder resFolder) {
+ super(resFolder, false /*isFrameworkRepository*/);
mProject = project;
}
@@ -85,6 +94,7 @@ public class ProjectResources extends ResourceRepository {
@NonNull
public Map<ResourceType, Map<String, ResourceValue>> getConfiguredResources(
@NonNull FolderConfiguration referenceConfig) {
+ ensureInitialized();
Map<ResourceType, Map<String, ResourceValue>> resultMap =
new EnumMap<ResourceType, Map<String, ResourceValue>>(ResourceType.class);
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 1e12861d9..e407b6a78 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
@@ -49,7 +49,6 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.QualifiedName;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@@ -151,14 +150,14 @@ public final class ResourceManager {
/**
* Returns the resources of a project.
* @param project The project
- * @return a ProjectResources object or null if none was found.
+ * @return a ProjectResources object
*/
public ProjectResources getProjectResources(IProject project) {
synchronized (mMap) {
ProjectResources resources = mMap.get(project);
if (resources == null) {
- resources = new ProjectResources(project);
+ resources = ProjectResources.create(project);
mMap.put(project, resources);
}
@@ -253,7 +252,7 @@ public final class ResourceManager {
// if it doesn't exist, we create it.
if (resources == null) {
- resources = new ProjectResources(project);
+ resources = ProjectResources.create(project);
mMap.put(project, resources);
}
}
@@ -491,16 +490,11 @@ public final class ResourceManager {
FolderWrapper frameworkRes = new FolderWrapper(osResourcesPath);
if (frameworkRes.exists()) {
- FrameworkResources resources = new FrameworkResources();
-
- try {
- resources.loadResources(frameworkRes);
- resources.loadPublicResources(frameworkRes, AdtPlugin.getDefault());
- return resources;
- } catch (IOException e) {
- // since we test that folders are folders, and files are files, this shouldn't
- // happen. We can ignore it.
- }
+ FrameworkResources resources = new FrameworkResources(frameworkRes);
+
+ resources.loadResources();
+ resources.loadPublicResources(AdtPlugin.getDefault());
+ return resources;
}
return null;
@@ -512,62 +506,13 @@ public final class ResourceManager {
*/
private void createProject(IProject project) {
if (project.isOpen()) {
- try {
- if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
- return;
- }
- } catch (CoreException e1) {
- // can't check the nature of the project? ignore it.
- return;
- }
-
- IFolder resourceFolder = project.getFolder(SdkConstants.FD_RESOURCES);
-
- ProjectResources projectResources;
synchronized (mMap) {
- projectResources = mMap.get(project);
+ ProjectResources projectResources = mMap.get(project);
if (projectResources == null) {
- projectResources = new ProjectResources(project);
+ projectResources = ProjectResources.create(project);
mMap.put(project, projectResources);
}
}
- IdeScanningContext context = new IdeScanningContext(projectResources, project, true);
-
- if (resourceFolder != null && resourceFolder.exists()) {
- try {
- IResource[] resources = resourceFolder.members();
-
- for (IResource res : resources) {
- if (res.getType() == IResource.FOLDER) {
- IFolder folder = (IFolder)res;
- ResourceFolder resFolder = projectResources.processFolder(
- new IFolderWrapper(folder));
-
- if (resFolder != null) {
- // now we process the content of the folder
- IResource[] files = folder.members();
-
- for (IResource fileRes : files) {
- if (fileRes.getType() == IResource.FILE) {
- IFile file = (IFile)fileRes;
-
- context.startScanning(file);
-
- resFolder.processFile(new IFileWrapper(file),
- ResourceHelper.getResourceDeltaKind(
- IResourceDelta.ADDED), context);
-
- context.finishScanning(file);
- }
- }
- }
- }
- }
- } 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.
- }
- }
}
}
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
index 5cb56473a..30f23de05 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/tests/functests/layoutRendering/ApiDemosRenderingTest.java
@@ -26,6 +26,7 @@ import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.SessionParams;
import com.android.ide.common.rendering.api.SessionParams.RenderingMode;
+import com.android.ide.common.resources.ResourceItem;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.resources.configuration.DensityQualifier;
@@ -43,7 +44,6 @@ import com.android.ide.common.resources.configuration.SmallestScreenWidthQualifi
import com.android.ide.common.resources.configuration.TextInputMethodQualifier;
import com.android.ide.common.resources.configuration.TouchScreenQualifier;
import com.android.ide.common.sdk.LoadStatus;
-import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.tests.SdkTestCase;
@@ -215,8 +215,13 @@ public class ApiDemosRenderingTest extends SdkTestCase {
ResourceRepository framework = ResourceManager.getInstance().loadFrameworkResources(target);
// now load the project resources
- ProjectResources project = new ProjectResources(null /*project*/);
- project.loadResources(resFolder);
+ ResourceRepository project = new ResourceRepository(resFolder, false) {
+ @Override
+ protected ResourceItem createResourceItem(String name) {
+ return new ResourceItem(name);
+ }
+
+ };
// Create a folder configuration that will be used for the rendering:
FolderConfiguration config = getConfiguration();
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/resources/platform/AttributeInfoTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/resources/platform/AttributeInfoTest.java
index 7ae96a8a2..cde12e597 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/resources/platform/AttributeInfoTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/common/resources/platform/AttributeInfoTest.java
@@ -18,11 +18,15 @@ package com.android.ide.common.resources.platform;
import static com.android.SdkConstants.ANDROID_URI;
import static com.android.SdkConstants.DOT_XML;
+import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.ide.common.api.IAttributeInfo.Format;
import com.android.ide.common.resources.ResourceItem;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.DomUtilities;
+import com.android.ide.eclipse.mock.Mocks;
+import com.android.io.IAbstractFolder;
+import com.android.io.IAbstractResource;
import com.android.resources.ResourceType;
import com.android.utils.StdLogger;
import com.google.common.base.Charsets;
@@ -219,11 +223,14 @@ public class AttributeInfoTest extends TestCase {
}
public void testResourcesExist() throws Exception {
+ IAbstractFolder folder = Mocks.createAbstractFolder(
+ SdkConstants.FD_RESOURCES, new IAbstractResource[0]);
+
AttributeInfo info = new AttributeInfo("test", Format.REFERENCE_SET);
- TestResourceRepository projectResources = new TestResourceRepository(false);
+ TestResourceRepository projectResources = new TestResourceRepository(folder,false);
projectResources.addResource(ResourceType.STRING, "mystring");
projectResources.addResource(ResourceType.DIMEN, "mydimen");
- TestResourceRepository frameworkResources = new TestResourceRepository(true);
+ TestResourceRepository frameworkResources = new TestResourceRepository(folder, true);
frameworkResources.addResource(ResourceType.LAYOUT, "mylayout");
assertTrue(info.isValid("@string/mystring", null, null));
@@ -247,8 +254,8 @@ public class AttributeInfoTest extends TestCase {
private class TestResourceRepository extends ResourceRepository {
private Multimap<ResourceType, String> mResources = ArrayListMultimap.create();
- protected TestResourceRepository(boolean isFrameworkRepository) {
- super(isFrameworkRepository);
+ protected TestResourceRepository(IAbstractFolder resFolder, boolean isFrameworkRepository) {
+ super(resFolder, isFrameworkRepository);
}
void addResource(ResourceType type, String name) {
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java
index b45242b79..a6da135b6 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/internal/editors/resources/manager/ConfigMatchTest.java
@@ -16,8 +16,10 @@
package com.android.ide.eclipse.adt.internal.editors.resources.manager;
+import com.android.SdkConstants;
import com.android.ide.common.resources.ResourceFile;
import com.android.ide.common.resources.ResourceFolder;
+import com.android.ide.common.resources.ResourceItem;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.SingleResourceFile;
import com.android.ide.common.resources.configuration.FolderConfiguration;
@@ -25,6 +27,8 @@ import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.ide.eclipse.adt.io.IFolderWrapper;
import com.android.ide.eclipse.mock.Mocks;
+import com.android.io.IAbstractFolder;
+import com.android.io.IAbstractResource;
import com.android.resources.Keyboard;
import com.android.resources.KeyboardState;
import com.android.resources.Navigation;
@@ -46,7 +50,7 @@ public class ConfigMatchTest extends TestCase {
private static final String MISC2_FILENAME = "bar.xml"; //$NON-NLS-1$
private FolderConfiguration mDefaultConfig;
- private ProjectResources mResources;
+ private ResourceRepository mResources;
private FolderConfiguration config4;
private FolderConfiguration config3;
private FolderConfiguration config2;
@@ -60,8 +64,16 @@ public class ConfigMatchTest extends TestCase {
mDefaultConfig = new FolderConfiguration();
mDefaultConfig.createDefault();
+ IAbstractFolder folder = Mocks.createAbstractFolder(
+ SdkConstants.FD_RESOURCES, new IAbstractResource[0]);
+
// create the project resources.
- mResources = new ProjectResources(null /*project*/);
+ mResources = new ResourceRepository(folder, false) {
+ @Override
+ protected ResourceItem createResourceItem(String name) {
+ return new ResourceItem(name);
+ }
+ };
// create 2 arrays of IResource. one with the filename being looked up, and one without.
// Since the required API uses IResource, we can use MockFolder for them.
diff --git a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/Mocks.java b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/Mocks.java
index b57f3da29..65e2144be 100644
--- a/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/Mocks.java
+++ b/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/mock/Mocks.java
@@ -25,6 +25,9 @@ import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isA;
import static org.easymock.EasyMock.replay;
+import com.android.io.IAbstractFolder;
+import com.android.io.IAbstractResource;
+
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
@@ -145,6 +148,16 @@ public class Mocks {
return file;
}
+ public static IAbstractFolder createAbstractFolder(String name, IAbstractResource[] members) {
+ IAbstractFolder folder = createNiceMock(IAbstractFolder.class);
+ expect(folder.getName()).andReturn(name).anyTimes();
+ // expect(file.getLocation()).andReturn(new Path(name)).anyTimes();
+ expect(folder.listMembers()).andReturn(members).anyTimes();
+ replay(folder);
+
+ return folder;
+ }
+
/**
* Mock implementation of {@link IProject}.
* <p/>
diff --git a/sdk_common/src/com/android/ide/common/resources/FrameworkResources.java b/sdk_common/src/com/android/ide/common/resources/FrameworkResources.java
index fbf592669..0e7e58a4f 100755
--- a/sdk_common/src/com/android/ide/common/resources/FrameworkResources.java
+++ b/sdk_common/src/com/android/ide/common/resources/FrameworkResources.java
@@ -59,8 +59,8 @@ public class FrameworkResources extends ResourceRepository {
protected final Map<ResourceType, List<ResourceItem>> mPublicResourceMap =
new EnumMap<ResourceType, List<ResourceItem>>(ResourceType.class);
- public FrameworkResources() {
- super(true /*isFrameworkRepository*/);
+ public FrameworkResources(@NonNull IAbstractFolder resFolder) {
+ super(resFolder, true /*isFrameworkRepository*/);
}
/**
@@ -102,8 +102,8 @@ public class FrameworkResources extends ResourceRepository {
* @param resFolder The root folder of the resources
* @param logger a logger to report issues to
*/
- public void loadPublicResources(@NonNull IAbstractFolder resFolder, @Nullable ILogger logger) {
- IAbstractFolder valueFolder = resFolder.getFolder(SdkConstants.FD_RES_VALUES);
+ public void loadPublicResources(@Nullable ILogger logger) {
+ IAbstractFolder valueFolder = getResFolder().getFolder(SdkConstants.FD_RES_VALUES);
if (valueFolder.exists() == false) {
return;
}
diff --git a/sdk_common/src/com/android/ide/common/resources/ResourceRepository.java b/sdk_common/src/com/android/ide/common/resources/ResourceRepository.java
index 4f50f63ac..02c61d188 100755
--- a/sdk_common/src/com/android/ide/common/resources/ResourceRepository.java
+++ b/sdk_common/src/com/android/ide/common/resources/ResourceRepository.java
@@ -31,7 +31,6 @@ import com.android.resources.FolderTypeRelationship;
import com.android.resources.ResourceFolderType;
import com.android.resources.ResourceType;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -59,32 +58,95 @@ import java.util.TreeSet;
*/
public abstract class ResourceRepository {
- protected final Map<ResourceFolderType, List<ResourceFolder>> mFolderMap =
+ private final IAbstractFolder mResourceFolder;
+
+ protected Map<ResourceFolderType, List<ResourceFolder>> mFolderMap =
new EnumMap<ResourceFolderType, List<ResourceFolder>>(ResourceFolderType.class);
- protected final Map<ResourceType, Map<String, ResourceItem>> mResourceMap =
+ protected Map<ResourceType, Map<String, ResourceItem>> mResourceMap =
new EnumMap<ResourceType, Map<String, ResourceItem>>(
- ResourceType.class);
+ ResourceType.class);
- private final Map<Map<String, ResourceItem>, Collection<ResourceItem>> mReadOnlyListMap =
+ private Map<Map<String, ResourceItem>, Collection<ResourceItem>> mReadOnlyListMap =
new IdentityHashMap<Map<String, ResourceItem>, Collection<ResourceItem>>();
private final boolean mFrameworkRepository;
+ private boolean mCleared = true;
+ private boolean mInitializing = false;
protected final IntArrayWrapper mWrapper = new IntArrayWrapper(null);
/**
* Makes a resource repository
+ * @param resFolder the resource folder of the repository.
* @param isFrameworkRepository whether the repository is for framework resources.
*/
- protected ResourceRepository(boolean isFrameworkRepository) {
+ protected ResourceRepository(@NonNull IAbstractFolder resFolder,
+ boolean isFrameworkRepository) {
+ mResourceFolder = resFolder;
mFrameworkRepository = isFrameworkRepository;
}
+ public IAbstractFolder getResFolder() {
+ return mResourceFolder;
+ }
+
public boolean isFrameworkRepository() {
return mFrameworkRepository;
}
+ public synchronized void clear() {
+ mCleared = true;
+ mFolderMap = new EnumMap<ResourceFolderType, List<ResourceFolder>>(
+ ResourceFolderType.class);
+ mResourceMap = new EnumMap<ResourceType, Map<String, ResourceItem>>(
+ ResourceType.class);
+
+ mReadOnlyListMap =
+ new IdentityHashMap<Map<String, ResourceItem>, Collection<ResourceItem>>();
+ }
+
+ /**
+ * Ensures that the repository has been initialized again after a call to
+ * {@link ResourceRepository#clear()}
+ *
+ * @return true if the repository was just re-initialized.
+ */
+ public synchronized boolean ensureInitialized() {
+ if (mCleared && !mInitializing) {
+ ScanningContext context = new ScanningContext(this);
+ mInitializing = true;
+
+ IAbstractResource[] resources = mResourceFolder.listMembers();
+
+ for (IAbstractResource res : resources) {
+ if (res instanceof IAbstractFolder) {
+ IAbstractFolder folder = (IAbstractFolder)res;
+ ResourceFolder resFolder = processFolder(folder);
+
+ if (resFolder != null) {
+ // now we process the content of the folder
+ IAbstractResource[] files = folder.listMembers();
+
+ for (IAbstractResource fileRes : files) {
+ if (fileRes instanceof IAbstractFile) {
+ IAbstractFile file = (IAbstractFile)fileRes;
+
+ resFolder.processFile(file, ResourceDeltaKind.ADDED, context);
+ }
+ }
+ }
+ }
+ }
+
+ mInitializing = false;
+ mCleared = false;
+ return true;
+ }
+
+ return false;
+ }
+
/**
* Adds a Folder Configuration to the project.
* @param type The resource type.
@@ -140,6 +202,8 @@ public abstract class ResourceRepository {
@NonNull ResourceFolderType type,
@NonNull IAbstractFolder removedFolder,
@Nullable ScanningContext context) {
+ ensureInitialized();
+
// get the list of folders for the resource type.
List<ResourceFolder> list = mFolderMap.get(type);
@@ -173,6 +237,8 @@ public abstract class ResourceRepository {
public boolean hasResourceItem(@NonNull String url) {
assert url.startsWith("@") || url.startsWith("?") : url;
+ ensureInitialized();
+
int typeEnd = url.indexOf('/', 1);
if (typeEnd != -1) {
int nameBegin = typeEnd + 1;
@@ -204,6 +270,8 @@ public abstract class ResourceRepository {
* @return true if the resource is known
*/
public boolean hasResourceItem(@NonNull ResourceType type, @NonNull String name) {
+ ensureInitialized();
+
Map<String, ResourceItem> map = mResourceMap.get(type);
if (map != null) {
@@ -227,6 +295,8 @@ public abstract class ResourceRepository {
*/
@NonNull
protected ResourceItem getResourceItem(@NonNull ResourceType type, @NonNull String name) {
+ ensureInitialized();
+
// looking for an existing ResourceItem with this type and name
ResourceItem item = findDeclaredResourceItem(type, name);
@@ -308,6 +378,8 @@ public abstract class ResourceRepository {
*/
@Nullable
public ResourceFolder processFolder(@NonNull IAbstractFolder folder) {
+ ensureInitialized();
+
// split the name of the folder in segments.
String[] folderSegments = folder.getName().split(SdkConstants.RES_QUALIFIER_SEP);
@@ -332,11 +404,15 @@ public abstract class ResourceRepository {
*/
@Nullable
public List<ResourceFolder> getFolders(@NonNull ResourceFolderType type) {
+ ensureInitialized();
+
return mFolderMap.get(type);
}
@NonNull
public List<ResourceType> getAvailableResourceTypes() {
+ ensureInitialized();
+
List<ResourceType> list = new ArrayList<ResourceType>();
// For each key, we check if there's a single ResourceType match.
@@ -381,6 +457,8 @@ public abstract class ResourceRepository {
*/
@NonNull
public Collection<ResourceItem> getResourceItemsOfType(@NonNull ResourceType type) {
+ ensureInitialized();
+
Map<String, ResourceItem> map = mResourceMap.get(type);
if (map == null) {
@@ -402,6 +480,8 @@ public abstract class ResourceRepository {
* @return true if the repository contains resources of the given type, false otherwise.
*/
public boolean hasResourcesOfType(@NonNull ResourceType type) {
+ ensureInitialized();
+
Map<String, ResourceItem> items = mResourceMap.get(type);
return (items != null && items.size() > 0);
}
@@ -413,15 +493,9 @@ public abstract class ResourceRepository {
*/
@Nullable
public ResourceFolder getResourceFolder(@NonNull IAbstractFolder folder) {
- Collection<List<ResourceFolder>> values = mFolderMap.values();
+ ensureInitialized();
- if (values.isEmpty()) { // This shouldn't be necessary, but has been observed
- try {
- loadResources(folder.getParentFolder());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ Collection<List<ResourceFolder>> values = mFolderMap.values();
for (List<ResourceFolder> list : values) {
for (ResourceFolder resFolder : list) {
@@ -445,6 +519,8 @@ public abstract class ResourceRepository {
@Nullable
public ResourceFile getMatchingFile(@NonNull String name, @NonNull ResourceFolderType type,
@NonNull FolderConfiguration config) {
+ ensureInitialized();
+
// get the folders for the given type
List<ResourceFolder> folders = mFolderMap.get(type);
@@ -486,6 +562,7 @@ public abstract class ResourceRepository {
@Nullable
public List<ResourceFile> getSourceFiles(@NonNull ResourceType type, @NonNull String name,
@Nullable FolderConfiguration referenceConfig) {
+ ensureInitialized();
Collection<ResourceItem> items = getResourceItemsOfType(type);
@@ -517,6 +594,8 @@ public abstract class ResourceRepository {
@NonNull
public Map<ResourceType, Map<String, ResourceValue>> getConfiguredResources(
@NonNull FolderConfiguration referenceConfig) {
+ ensureInitialized();
+
return doGetConfiguredResources(referenceConfig);
}
@@ -530,6 +609,7 @@ public abstract class ResourceRepository {
@NonNull
protected final Map<ResourceType, Map<String, ResourceValue>> doGetConfiguredResources(
@NonNull FolderConfiguration referenceConfig) {
+ ensureInitialized();
Map<ResourceType, Map<String, ResourceValue>> map =
new EnumMap<ResourceType, Map<String, ResourceValue>>(ResourceType.class);
@@ -547,6 +627,8 @@ public abstract class ResourceRepository {
*/
@NonNull
public SortedSet<String> getLanguages() {
+ ensureInitialized();
+
SortedSet<String> set = new TreeSet<String>();
Collection<List<ResourceFolder>> folderList = mFolderMap.values();
@@ -569,6 +651,8 @@ public abstract class ResourceRepository {
*/
@NonNull
public SortedSet<String> getRegions(@NonNull String currentLanguage) {
+ ensureInitialized();
+
SortedSet<String> set = new TreeSet<String>();
Collection<List<ResourceFolder>> folderList = mFolderMap.values();
@@ -591,41 +675,17 @@ public abstract class ResourceRepository {
}
/**
- * Loads the resources from a resource folder.
- * <p/>
- *
- * @param rootFolder The folder to read the resources from. This is the top level
- * resource folder (res/)
- * @throws IOException
+ * Loads the resources.
*/
- public void loadResources(@NonNull IAbstractFolder rootFolder)
- throws IOException {
- ScanningContext context = new ScanningContext(this);
-
- IAbstractResource[] files = rootFolder.listMembers();
- for (IAbstractResource file : files) {
- if (file instanceof IAbstractFolder) {
- IAbstractFolder folder = (IAbstractFolder) file;
- ResourceFolder resFolder = processFolder(folder);
-
- if (resFolder != null) {
- // now we process the content of the folder
- IAbstractResource[] children = folder.listMembers();
-
- for (IAbstractResource childRes : children) {
- if (childRes instanceof IAbstractFile) {
- resFolder.processFile((IAbstractFile) childRes,
- ResourceDeltaKind.ADDED, context);
- }
- }
- }
- }
- }
+ public void loadResources() {
+ clear();
+ ensureInitialized();
}
-
protected void removeFile(@NonNull Collection<ResourceType> types,
@NonNull ResourceFile file) {
+ ensureInitialized();
+
for (ResourceType type : types) {
removeFile(type, file);
}