aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java655
1 files changed, 0 insertions, 655 deletions
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
deleted file mode 100644
index e407b6a78..000000000
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/ResourceManager.java
+++ /dev/null
@@ -1,655 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Eclipse Public License, Version 1.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.eclipse.org/org/documents/epl-v10.php
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.ide.eclipse.adt.internal.resources.manager;
-
-import com.android.SdkConstants;
-import com.android.ide.common.resources.FrameworkResources;
-import com.android.ide.common.resources.ResourceFile;
-import com.android.ide.common.resources.ResourceFolder;
-import com.android.ide.common.resources.ResourceRepository;
-import com.android.ide.common.resources.ScanningContext;
-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.IProjectListener;
-import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IRawDeltaListener;
-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;
-import com.android.ide.eclipse.adt.io.IFolderWrapper;
-import com.android.io.FolderWrapper;
-import com.android.resources.ResourceFolderType;
-import com.android.sdklib.IAndroidTarget;
-
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-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;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.QualifiedName;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * The ResourceManager tracks resources for all opened projects.
- * <p/>
- * It provide direct access to all the resources of a project as a {@link ProjectResources}
- * object that allows accessing the resources through their file representation or as Android
- * resources (similar to what is seen by an Android application).
- * <p/>
- * The ResourceManager automatically tracks file changes to update its internal representation
- * of the resources so that they are always up to date.
- * <p/>
- * It also gives access to a monitor that is more resource oriented than the
- * {@link GlobalProjectMonitor}.
- * This monitor will let you track resource changes by giving you direct access to
- * {@link ResourceFile}, or {@link ResourceFolder}.
- *
- * @see ProjectResources
- */
-public final class ResourceManager {
- public final static boolean DEBUG = false;
-
- private final static ResourceManager sThis = new ResourceManager();
-
- /**
- * Map associating project resource with project objects.
- * <p/><b>All accesses must be inside a synchronized(mMap) block</b>, and do as a little as
- * possible and <b>not call out to other classes</b>.
- */
- private final Map<IProject, ProjectResources> mMap =
- new HashMap<IProject, ProjectResources>();
-
- /**
- * Interface to be notified of resource changes.
- *
- * @see ResourceManager#addListener(IResourceListener)
- * @see ResourceManager#removeListener(IResourceListener)
- */
- public interface IResourceListener {
- /**
- * Notification for resource file change.
- * @param project the project of the file.
- * @param file the {@link ResourceFile} representing the file.
- * @param eventType the type of event. See {@link IResourceDelta}.
- */
- void fileChanged(IProject project, ResourceFile file, int eventType);
- /**
- * Notification for resource folder change.
- * @param project the project of the file.
- * @param folder the {@link ResourceFolder} representing the folder.
- * @param eventType the type of event. See {@link IResourceDelta}.
- */
- void folderChanged(IProject project, ResourceFolder folder, int eventType);
- }
-
- private final ArrayList<IResourceListener> mListeners = new ArrayList<IResourceListener>();
-
- /**
- * Sets up the resource manager with the global project monitor.
- * @param monitor The global project monitor
- */
- public static void setup(GlobalProjectMonitor monitor) {
- monitor.addProjectListener(sThis.mProjectListener);
- monitor.addRawDeltaListener(sThis.mRawDeltaListener);
-
- CompiledResourcesMonitor.setupMonitor(monitor);
- }
-
- /**
- * Returns the singleton instance.
- */
- public static ResourceManager getInstance() {
- return sThis;
- }
-
- /**
- * Adds a new {@link IResourceListener} to be notified of resource changes.
- * @param listener the listener to be added.
- */
- public void addListener(IResourceListener listener) {
- synchronized (mListeners) {
- mListeners.add(listener);
- }
- }
-
- /**
- * Removes an {@link IResourceListener}, so that it's not notified of resource changes anymore.
- * @param listener the listener to be removed.
- */
- public void removeListener(IResourceListener listener) {
- synchronized (mListeners) {
- mListeners.remove(listener);
- }
- }
-
- /**
- * Returns the resources of a project.
- * @param project The project
- * @return a ProjectResources object
- */
- public ProjectResources getProjectResources(IProject project) {
- synchronized (mMap) {
- ProjectResources resources = mMap.get(project);
-
- if (resources == null) {
- resources = ProjectResources.create(project);
- mMap.put(project, resources);
- }
-
- return resources;
- }
- }
-
- /**
- * Update the resource repository with a delta
- *
- * @param delta the resource changed delta to process.
- * @param context a context object with state for the current update, such
- * as a place to stash errors encountered
- */
- public void processDelta(IResourceDelta delta, IdeScanningContext context) {
- doProcessDelta(delta, context);
-
- // when a project is added to the workspace it is possible this is called before the
- // repo is actually created so this will return null.
- ResourceRepository repo = context.getRepository();
- if (repo != null) {
- repo.postUpdateCleanUp();
- }
- }
-
- /**
- * Update the resource repository with a delta
- *
- * @param delta the resource changed delta to process.
- * @param context a context object with state for the current update, such
- * as a place to stash errors encountered
- */
- private void doProcessDelta(IResourceDelta delta, IdeScanningContext context) {
- // 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;
- }
-
- // Process this delta first as we need to make sure new folders are created before
- // we process their content
- IResource r = delta.getResource();
- int type = r.getType();
-
- if (type == IResource.FILE) {
- context.startScanning(r);
- updateFile((IFile)r, delta.getMarkerDeltas(), kind, context);
- context.finishScanning(r);
- } else if (type == IResource.FOLDER) {
- updateFolder((IFolder)r, kind, context);
- } // We only care about files and folders.
- // Project deltas are handled by our project listener
-
- // Now, process children recursively
- IResourceDelta[] children = delta.getAffectedChildren();
- for (IResourceDelta child : children) {
- processDelta(child, context);
- }
- }
-
- /**
- * Update a resource folder that we know about
- * @param folder the folder that was updated
- * @param kind the delta type (added/removed/updated)
- */
- private void updateFolder(IFolder folder, int kind, IdeScanningContext context) {
- ProjectResources resources;
-
- final IProject project = folder.getProject();
-
- try {
- if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
- return;
- }
- } catch (CoreException e) {
- // can't get the project nature? return!
- return;
- }
-
- 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 = ProjectResources.create(project);
- mMap.put(project, resources);
- }
- }
-
- ResourceFolder newFolder = resources.processFolder(
- new IFolderWrapper(folder));
- if (newFolder != null) {
- notifyListenerOnFolderChange(project, newFolder, kind);
- }
- }
- }
- 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());
-
- context.startScanning(folder);
- ResourceFolder removedFolder = resources.removeFolder(type,
- new IFolderWrapper(folder), context);
- context.finishScanning(folder);
- if (removedFolder != null) {
- notifyListenerOnFolderChange(project, removedFolder, kind);
- }
- }
- break;
- }
- }
-
- /**
- * 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)}
- * @param context a context object with state for the current update, such
- * as a place to stash errors encountered
- */
- private void updateFile(IFile file, IMarkerDelta[] markerDeltas, int kind,
- ScanningContext context) {
- final IProject project = file.getProject();
-
- 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);
- }
-
- if (resources == null) {
- return;
- }
-
- // checks if the file is under res/something or bin/res/something
- IPath path = file.getFullPath();
-
- if (path.segmentCount() == 4 || path.segmentCount() == 5) {
- 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), context);
- 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 final IProjectListener mProjectListener = new IProjectListener() {
- @Override
- public void projectClosed(IProject project) {
- synchronized (mMap) {
- mMap.remove(project);
- }
- }
-
- @Override
- public void projectDeleted(IProject project) {
- synchronized (mMap) {
- mMap.remove(project);
- }
- }
-
- @Override
- public void projectOpened(IProject project) {
- createProject(project);
- }
-
- @Override
- public void projectOpenedWithWorkspace(IProject project) {
- createProject(project);
- }
-
- @Override
- public void allProjectsOpenedWithWorkspace() {
- // nothing to do.
- }
-
- @Override
- public void projectRenamed(IProject project, IPath from) {
- // renamed project get a delete/open event too, so this can be ignored.
- }
- };
-
- /**
- * 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() {
- @Override
- public void visitDelta(IResourceDelta workspaceDelta) {
- // If we're auto-building, then PreCompilerBuilder will pass us deltas and
- // they will be processed as part of the build.
- if (isAutoBuilding()) {
- return;
- }
-
- // When *not* auto building, we need to process the deltas immediately on save,
- // even if the user is not building yet, such that for example resource ids
- // are updated in the resource repositories so rendering etc. can work for
- // those new ids.
-
- IResourceDelta[] projectDeltas = workspaceDelta.getAffectedChildren();
- for (IResourceDelta delta : projectDeltas) {
- if (delta.getResource() instanceof IProject) {
- IProject project = (IProject) delta.getResource();
-
- try {
- if (project.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
- continue;
- }
- } catch (CoreException e) {
- // only happens if the project is closed or doesn't exist.
- }
-
- IdeScanningContext context =
- new IdeScanningContext(getProjectResources(project), project, true);
-
- processDelta(delta, context);
-
- Collection<IProject> projects = context.getAaptRequestedProjects();
- if (projects != null) {
- for (IProject p : projects) {
- markAaptRequested(p);
- }
- }
- } else {
- AdtPlugin.log(IStatus.WARNING, "Unexpected delta type: %1$s",
- delta.getResource().toString());
- }
- }
- }
- };
-
- /**
- * Returns the {@link ResourceFolder} for the given file or <code>null</code> if none exists.
- */
- public ResourceFolder getResourceFolder(IFile file) {
- IContainer container = file.getParent();
- if (container.getType() == IResource.FOLDER) {
- IFolder parent = (IFolder)container;
- IProject project = file.getProject();
-
- ProjectResources resources = getProjectResources(project);
- if (resources != null) {
- return resources.getResourceFolder(parent);
- }
- }
-
- return null;
- }
-
- /**
- * Returns the {@link ResourceFolder} for the given folder or <code>null</code> if none exists.
- */
- public ResourceFolder getResourceFolder(IFolder folder) {
- IProject project = folder.getProject();
-
- ProjectResources resources = getProjectResources(project);
- if (resources != null) {
- return resources.getResourceFolder(folder);
- }
-
- return null;
- }
-
- /**
- * Loads and returns the resources for a given {@link IAndroidTarget}
- * @param androidTarget the target from which to load the framework resources
- */
- public ResourceRepository loadFrameworkResources(IAndroidTarget androidTarget) {
- String osResourcesPath = androidTarget.getPath(IAndroidTarget.RESOURCES);
-
- FolderWrapper frameworkRes = new FolderWrapper(osResourcesPath);
- if (frameworkRes.exists()) {
- FrameworkResources resources = new FrameworkResources(frameworkRes);
-
- resources.loadResources();
- resources.loadPublicResources(AdtPlugin.getDefault());
- return resources;
- }
-
- return null;
- }
-
- /**
- * Initial project parsing to gather resource info.
- * @param project
- */
- private void createProject(IProject project) {
- if (project.isOpen()) {
- synchronized (mMap) {
- ProjectResources projectResources = mMap.get(project);
- if (projectResources == null) {
- projectResources = ProjectResources.create(project);
- mMap.put(project, projectResources);
- }
- }
- }
- }
-
-
- /**
- * Returns true if the path is under /project/res/
- * @param path a workspace relative path
- * @return true if the path is under /project res/
- */
- private boolean isInResFolder(IPath path) {
- return SdkConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1));
- }
-
- private void notifyListenerOnFolderChange(IProject project, ResourceFolder folder,
- int eventType) {
- synchronized (mListeners) {
- for (IResourceListener listener : mListeners) {
- try {
- listener.folderChanged(project, folder, eventType);
- } catch (Throwable t) {
- AdtPlugin.log(t,
- "Failed to execute ResourceManager.IResouceListener.folderChanged()"); //$NON-NLS-1$
- }
- }
- }
- }
-
- private void notifyListenerOnFileChange(IProject project, ResourceFile file, int eventType) {
- synchronized (mListeners) {
- for (IResourceListener listener : mListeners) {
- try {
- listener.fileChanged(project, file, eventType);
- } catch (Throwable t) {
- AdtPlugin.log(t,
- "Failed to execute ResourceManager.IResouceListener.fileChanged()"); //$NON-NLS-1$
- }
- }
- }
- }
-
- /**
- * Private constructor to enforce singleton design.
- */
- private ResourceManager() {
- }
-
- // debug only
- @SuppressWarnings("unused")
- private String getKindString(int kind) {
- if (DEBUG) {
- switch (kind) {
- case IResourceDelta.ADDED: return "ADDED";
- case IResourceDelta.REMOVED: return "REMOVED";
- case IResourceDelta.CHANGED: return "CHANGED";
- }
- }
-
- return Integer.toString(kind);
- }
-
- /**
- * Returns true if the Project > Build Automatically option is turned on
- * (default).
- *
- * @return true if the Project > Build Automatically option is turned on
- * (default).
- */
- public static boolean isAutoBuilding() {
- return ResourcesPlugin.getWorkspace().getDescription().isAutoBuilding();
- }
-
- /** Qualified name for the per-project persistent property "needs aapt" */
- private final static QualifiedName NEED_AAPT = new QualifiedName(AdtPlugin.PLUGIN_ID,
- "aapt");//$NON-NLS-1$
-
- /**
- * Mark the given project, and any projects which depend on it as a library
- * project, as needing a full aapt build the next time the project is built.
- *
- * @param project the project to mark as needing aapt
- */
- public static void markAaptRequested(IProject project) {
- try {
- String needsAapt = Boolean.TRUE.toString();
- project.setPersistentProperty(NEED_AAPT, needsAapt);
-
- ProjectState state = Sdk.getProjectState(project);
- if (state.isLibrary()) {
- // For library projects also mark the dependent projects as needing full aapt
- for (ProjectState parent : state.getFullParentProjects()) {
- IProject parentProject = parent.getProject();
- // Mark the project, but only if it's open. Resource#setPersistentProperty
- // only works on open projects.
- if (parentProject.isOpen()) {
- parentProject.setPersistentProperty(NEED_AAPT, needsAapt);
- }
- }
- }
- } catch (CoreException e) {
- AdtPlugin.log(e, null);
- }
- }
-
- /**
- * Clear the "needs aapt" flag set by {@link #markAaptRequested(IProject)}.
- * This is usually called when a project is built. Note that this will only
- * clean the build flag on the given project, not on any downstream projects
- * that depend on this project as a library project.
- *
- * @param project the project to clear from the needs aapt list
- */
- public static void clearAaptRequest(IProject project) {
- try {
- project.setPersistentProperty(NEED_AAPT, null);
- // Note that even if this project is a library project, we -don't- clear
- // the aapt flags on the dependent projects since they may still depend
- // on other dirty projects. When they are built, they will issue their
- // own clear flag requests.
- } catch (CoreException e) {
- AdtPlugin.log(e, null);
- }
- }
-
- /**
- * Returns whether the given project needs a full aapt build.
- *
- * @param project the project to check
- * @return true if the project needs a full aapt run
- */
- public static boolean isAaptRequested(IProject project) {
- try {
- String b = project.getPersistentProperty(NEED_AAPT);
- return b != null && Boolean.valueOf(b);
- } catch (CoreException e) {
- AdtPlugin.log(e, null);
- }
-
- return false;
- }
-}