diff options
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java')
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java | 313 |
1 files changed, 0 insertions, 313 deletions
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 deleted file mode 100644 index ab5ae4070..000000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/manager/CompiledResourcesMonitor.java +++ /dev/null @@ -1,313 +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.annotations.NonNull; -import com.android.annotations.Nullable; -import com.android.ide.common.resources.IntArrayWrapper; -import com.android.ide.common.xml.ManifestData; -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; -import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IProjectListener; -import com.android.resources.ResourceType; -import com.android.util.Pair; - -import org.eclipse.core.resources.IFile; -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.runtime.CoreException; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IStatus; - -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; -import java.util.regex.Pattern; - -/** - * A monitor for the compiled resources. This only monitors changes in the resources of type - * {@link ResourceType#ID}. - */ -public final class CompiledResourcesMonitor implements IFileListener, IProjectListener { - - private final static CompiledResourcesMonitor sThis = new CompiledResourcesMonitor(); - - /** - * Sets up the monitoring system. - * @param monitor The main Resource Monitor. - */ - public static void setupMonitor(GlobalProjectMonitor monitor) { - monitor.addFileListener(sThis, IResourceDelta.ADDED | IResourceDelta.CHANGED); - monitor.addProjectListener(sThis); - } - - /** - * private constructor to prevent construction. - */ - private CompiledResourcesMonitor() { - } - - - /* (non-Javadoc) - * Sent when a file changed : if the file is the R class, then it is parsed again to update - * the internal 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 - */ - @Override - public void fileChanged(@NonNull IFile file, @NonNull IMarkerDelta[] markerDeltas, - int kind, @Nullable String extension, int flags, boolean isAndroidProject) { - if (!isAndroidProject || flags == IResourceDelta.MARKERS) { - // Not Android or only the markers changed: not relevant - return; - } - - IProject project = file.getProject(); - - if (file.getName().equals(SdkConstants.FN_COMPILED_RESOURCE_CLASS)) { - // create the classname - String className = getRClassName(project); - if (className == null) { - // We need to abort. - AdtPlugin.log(IStatus.ERROR, - "fileChanged: failed to find manifest package for project %1$s", //$NON-NLS-1$ - project.getName()); - return; - } - // path will begin with /projectName/bin/classes so we'll ignore that - IPath relativeClassPath = file.getFullPath().removeFirstSegments(3); - if (packagePathMatches(relativeClassPath.toString(), className)) { - loadAndParseRClass(project, className); - } - } - } - - /** - * Check to see if the package section of the given path matches the packageName. - * For example, /project/bin/classes/com/foo/app/R.class should match com.foo.app.R - * @param path the pathname of the file to look at - * @param packageName the package qualified name of the class - * @return true if the package section of the path matches the package qualified name - */ - private boolean packagePathMatches(String path, String packageName) { - // First strip the ".class" off the end of the path - String pathWithoutExtension = path.substring(0, path.indexOf(SdkConstants.DOT_CLASS)); - - // then split the components of each path by their separators - String [] pathArray = pathWithoutExtension.split(Pattern.quote(File.separator)); - String [] packageArray = packageName.split(AdtConstants.RE_DOT); - - - int pathIndex = 0; - int packageIndex = 0; - - while (pathIndex < pathArray.length && packageIndex < packageArray.length) { - if (pathArray[pathIndex].equals(packageArray[packageIndex]) == false) { - return false; - } - pathIndex++; - packageIndex++; - } - // We may have matched all the way up to this point, but we're not sure it's a match - // unless BOTH paths done - return (pathIndex == pathArray.length && packageIndex == packageArray.length); - } - - /** - * Processes project close event. - */ - @Override - public void projectClosed(IProject project) { - // the ProjectResources object will be removed by the ResourceManager. - } - - /** - * Processes project delete event. - */ - @Override - public void projectDeleted(IProject project) { - // the ProjectResources object will be removed by the ResourceManager. - } - - /** - * Processes project open event. - */ - @Override - public void projectOpened(IProject project) { - // when the project is opened, we get an ADDED event for each file, so we don't - // need to do anything here. - } - - @Override - public void projectRenamed(IProject project, IPath from) { - // renamed projects also trigger delete/open event, - // so nothing to be done here. - } - - /** - * Processes existing project at init time. - */ - @Override - public void projectOpenedWithWorkspace(IProject project) { - try { - // check this is an android project - if (project.hasNature(AdtConstants.NATURE_DEFAULT)) { - String className = getRClassName(project); - // Find the classname - if (className == null) { - // We need to abort. - AdtPlugin.log(IStatus.ERROR, - "projectOpenedWithWorkspace: failed to find manifest package for project %1$s", //$NON-NLS-1$ - project.getName()); - return; - } - loadAndParseRClass(project, className); - } - } catch (CoreException e) { - // pass - } - } - - @Override - public void allProjectsOpenedWithWorkspace() { - // nothing to do. - } - - - private void loadAndParseRClass(IProject project, String className) { - try { - // first check there's a ProjectResources to store the content - ProjectResources projectResources = ResourceManager.getInstance().getProjectResources( - project); - - if (projectResources != null) { - // create a temporary class loader to load the class - ProjectClassLoader loader = new ProjectClassLoader(null /* parentClassLoader */, - project); - - try { - Class<?> clazz = loader.loadClass(className); - - if (clazz != null) { - // create the maps to store the result of the parsing - Map<ResourceType, Map<String, Integer>> resourceValueMap = - new EnumMap<ResourceType, Map<String, Integer>>(ResourceType.class); - Map<Integer, Pair<ResourceType, String>> genericValueToNameMap = - new HashMap<Integer, Pair<ResourceType, String>>(); - Map<IntArrayWrapper, String> styleableValueToNameMap = - new HashMap<IntArrayWrapper, String>(); - - // parse the class - if (parseClass(clazz, genericValueToNameMap, styleableValueToNameMap, - resourceValueMap)) { - // now we associate the maps to the project. - projectResources.setCompiledResources(genericValueToNameMap, - styleableValueToNameMap, resourceValueMap); - } - } - } catch (Error e) { - // Log this error with the class name we're trying to load and abort. - AdtPlugin.log(e, "loadAndParseRClass failed to find class %1$s", className); //$NON-NLS-1$ - } - } - } catch (ClassNotFoundException e) { - // pass - } - } - - /** - * Parses a R class, and fills maps. - * @param rClass the class to parse - * @param genericValueToNameMap - * @param styleableValueToNameMap - * @param resourceValueMap - * @return True if we managed to parse the R class. - */ - private boolean parseClass(Class<?> rClass, - Map<Integer, Pair<ResourceType, String>> genericValueToNameMap, - Map<IntArrayWrapper, String> styleableValueToNameMap, Map<ResourceType, - Map<String, Integer>> resourceValueMap) { - try { - for (Class<?> inner : rClass.getDeclaredClasses()) { - String resTypeName = inner.getSimpleName(); - ResourceType resType = ResourceType.getEnum(resTypeName); - - if (resType != null) { - Map<String, Integer> fullMap = new HashMap<String, Integer>(); - resourceValueMap.put(resType, fullMap); - - for (Field f : inner.getDeclaredFields()) { - // only process static final fields. - int modifiers = f.getModifiers(); - if (Modifier.isStatic(modifiers)) { - Class<?> type = f.getType(); - if (type.isArray() && type.getComponentType() == int.class) { - // if the object is an int[] we put it in the styleable map - styleableValueToNameMap.put( - new IntArrayWrapper((int[]) f.get(null)), - f.getName()); - } else if (type == int.class) { - Integer value = (Integer) f.get(null); - genericValueToNameMap.put(value, Pair.of(resType, f.getName())); - fullMap.put(f.getName(), value); - } else { - assert false; - } - } - } - } - } - - return true; - } catch (IllegalArgumentException e) { - } catch (IllegalAccessException e) { - } - return false; - } - - /** - * Returns the class name of the R class, based on the project's manifest's package. - * - * @return A class name (e.g. "my.app.R") or null if there's no valid package in the manifest. - */ - private String getRClassName(IProject project) { - IFile manifestFile = ProjectHelper.getManifest(project); - if (manifestFile != null && manifestFile.isSynchronized(IResource.DEPTH_ZERO)) { - ManifestData data = AndroidManifestHelper.parseForData(manifestFile); - if (data != null) { - String javaPackage = data.getPackage(); - return javaPackage + ".R"; //$NON-NLS-1$ - } - } - return null; - } - -} |