diff --git a/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java b/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java index aa5db7e53521..d47c86d4c677 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java +++ b/plugins/android/src/org/jetbrains/android/AndroidGotoDeclarationHandler.java @@ -25,7 +25,6 @@ import com.intellij.psi.xml.XmlAttributeValue; import org.jetbrains.android.dom.wrappers.FileResourceElementWrapper; import org.jetbrains.android.dom.wrappers.ValueResourceElementWrapper; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import java.util.List; @@ -82,8 +81,7 @@ public class AndroidGotoDeclarationHandler implements GotoDeclarationHandler { return null; } - final List resourceList = - AndroidResourceUtil.findResourcesByFieldName(facet.getLocalResourceManager(), resClassName, resFieldName); + final List resourceList = facet.getLocalResourceManager().findResourcesByFieldName(resClassName, resFieldName); final PsiElement[] resources = resourceList.toArray(new PsiElement[resourceList.size()]); final PsiElement[] wrappedResources = new PsiElement[resources.length]; diff --git a/plugins/android/src/org/jetbrains/android/AndroidProblemFileHighlightingFilter.java b/plugins/android/src/org/jetbrains/android/AndroidProblemFileHighlightingFilter.java index 3711c925ba59..72c06126319c 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidProblemFileHighlightingFilter.java +++ b/plugins/android/src/org/jetbrains/android/AndroidProblemFileHighlightingFilter.java @@ -20,7 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.resourceManagers.ResourceManager; +import org.jetbrains.android.util.AndroidResourceUtil; /** * @author Eugene.Kudelevsky @@ -46,6 +46,6 @@ public class AndroidProblemFileHighlightingFilter implements Condition() { public Boolean compute() { if (element instanceof PsiFile) { - return AndroidFacet.getInstance(element) != null && ResourceManager.isInResourceSubdirectory((PsiFile)element, null); + return AndroidFacet.getInstance(element) != null && AndroidResourceUtil.isInResourceSubdirectory((PsiFile)element, null); } else if (element instanceof PsiField) { PsiField field = (PsiField)element; @@ -203,11 +203,11 @@ public class AndroidRenameResourceProcessor extends RenamePsiElementProcessor { if (type == null) return; String name = file.getName(); - if (ResourceManager.getResourceName(type, name).equals(ResourceManager.getResourceName(type, newName))) { + if (AndroidResourceUtil.getResourceName(type, name).equals(AndroidResourceUtil.getResourceName(type, newName))) { return; } - List resourceFiles = manager.findResourceFiles(type, ResourceManager.getResourceName(type, name)); + List resourceFiles = manager.findResourceFiles(type, AndroidResourceUtil.getResourceName(type, name)); List alternativeResources = new ArrayList(); for (PsiFile resourceFile : resourceFiles) { if (!resourceFile.getManager().areElementsEquivalent(file, resourceFile) && resourceFile.getName().equals(name)) { @@ -231,7 +231,7 @@ public class AndroidRenameResourceProcessor extends RenamePsiElementProcessor { } PsiField[] resFields = AndroidResourceUtil.findResourceFieldsForFileResource(file, false); for (PsiField resField : resFields) { - String newFieldName = ResourceManager.getResourceName(type, newName); + String newFieldName = AndroidResourceUtil.getResourceName(type, newName); allRenames.put(resField, newFieldName); } } diff --git a/plugins/android/src/org/jetbrains/android/AndroidResourcesLineMarkerProvider.java b/plugins/android/src/org/jetbrains/android/AndroidResourcesLineMarkerProvider.java index f2df753a4392..9aa4e5f20c61 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidResourcesLineMarkerProvider.java +++ b/plugins/android/src/org/jetbrains/android/AndroidResourcesLineMarkerProvider.java @@ -40,7 +40,6 @@ import org.jetbrains.android.dom.resources.ResourceElement; import org.jetbrains.android.dom.resources.Resources; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.resourceManagers.LocalResourceManager; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NotNull; @@ -120,7 +119,8 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider { if (attr.getLocalName().equals("name")) { final XmlTag tag = PsiTreeUtil.getParentOfType(attr, XmlTag.class); if (tag != null) { - final String resType = AndroidResourceUtil.getResClassNameByValueResourceTag(facet, tag); + String fileResType = facet.getLocalResourceManager().getFileResourceType(tag.getContainingFile()); + final String resType = "values".equals(fileResType) ? AndroidResourceUtil.getResourceTypeByValueResourceTag(tag) : null; if (resType != null) { result.add(createLazyLineMarkerInfo(tag, new Computable() { @Override @@ -170,8 +170,8 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider { final Map> result = new HashMap>(); Collection resourceFiles = resManager.getResourceElements(); for (Resources res : resourceFiles) { - for (String valueResourceType : ResourceManager.VALUE_RESOURCE_TYPES) { - for (ResourceElement valueResource : ResourceManager.getValueResourcesFromElement(valueResourceType, res)) { + for (String valueResourceType : AndroidResourceUtil.VALUE_RESOURCE_TYPES) { + for (ResourceElement valueResource : AndroidResourceUtil.getValueResourcesFromElement(valueResourceType, res)) { addResource(valueResourceType, valueResource, result); } } @@ -203,7 +203,7 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider { if (!resourceFile.isDirectory()) { PsiFile resourcePsiFile = psiManager.findFile(resourceFile); if (resourcePsiFile != null) { - String resName = ResourceManager.getResourceName(resType, resourceFile.getName()); + String resName = AndroidResourceUtil.getResourceName(resType, resourceFile.getName()); MyResourceEntry key = new MyResourceEntry(resName, resType); List list = result.get(key); if (list == null) { @@ -264,7 +264,7 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider { if (resourceMap != null) { targets = new ArrayList(); if (resType.equals("id")) { - manager.collectIdDeclarations(fieldName, targets); + targets.addAll(manager.findIdDeclarations(fieldName)); } List resources = resourceMap.get(new MyResourceEntry(fieldName, resType)); if (resources != null) { @@ -272,7 +272,7 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider { } } else { - targets = AndroidResourceUtil.findResourcesByField(manager, resField); + targets = manager.findResourcesByField(resField); } return PsiUtilCore.toPsiElementArray(targets); } @@ -306,7 +306,7 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider { MyResourceEntry that = (MyResourceEntry)o; - if (!ResourceManager.equal(myName, that.myName, false)) return false; + if (!AndroidUtils.equal(myName, that.myName, false)) return false; if (!myType.equals(that.myType)) return false; return true; diff --git a/plugins/android/src/org/jetbrains/android/AndroidUsagesTargetProvider.java b/plugins/android/src/org/jetbrains/android/AndroidUsagesTargetProvider.java index da7bad1164e4..2920d85472a5 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidUsagesTargetProvider.java +++ b/plugins/android/src/org/jetbrains/android/AndroidUsagesTargetProvider.java @@ -11,7 +11,7 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.usages.UsageTarget; import com.intellij.usages.UsageTargetProvider; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.resourceManagers.ResourceManager; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -47,7 +47,7 @@ public class AndroidUsagesTargetProvider implements UsageTargetProvider { return null; } - if (!ResourceManager.isInResourceSubdirectory(file, ResourceFolderType.VALUES.getName())) { + if (!AndroidResourceUtil.isInResourceSubdirectory(file, ResourceFolderType.VALUES.getName())) { return null; } diff --git a/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java b/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java index 5652e9862fdb..3b26ce5537a0 100644 --- a/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java +++ b/plugins/android/src/org/jetbrains/android/AndroidXmlSchemaProvider.java @@ -35,7 +35,6 @@ import com.intellij.xml.XmlSchemaProvider; import gnu.trove.THashMap; import org.jetbrains.android.dom.manifest.ManifestDomFileDescription; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NonNls; @@ -99,7 +98,7 @@ public class AndroidXmlSchemaProvider extends XmlSchemaProvider { } private static boolean isXmlResourceFile(XmlFile file) { - if (!ResourceManager.isInResourceSubdirectory(file, null)) { + if (!AndroidResourceUtil.isInResourceSubdirectory(file, null)) { return false; } diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateResourceDirectoryAction.java b/plugins/android/src/org/jetbrains/android/actions/CreateResourceDirectoryAction.java index 40283fc74e11..11cda9efb863 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateResourceDirectoryAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateResourceDirectoryAction.java @@ -11,8 +11,8 @@ import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.util.PlatformIcons; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -81,7 +81,7 @@ public class CreateResourceDirectoryAction extends CreateElementActionBase { } return ApplicationManager.getApplication().runReadAction(new Computable() { public Boolean compute() { - return ResourceManager.isResourceDirectory((PsiDirectory)element); + return AndroidResourceUtil.isResourceDirectory((PsiDirectory)element); } }); } diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java b/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java index 2ef70b3d4666..74f064334916 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateResourceFileAction.java @@ -33,8 +33,8 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -78,7 +78,7 @@ public class CreateResourceFileAction extends CreateElementActionBase { } return ApplicationManager.getApplication().runReadAction(new Computable() { public Boolean compute() { - return ResourceManager.isResourceDirectory((PsiDirectory)element); + return AndroidResourceUtil.isResourceDirectory((PsiDirectory)element); } }); } diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java b/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java index 0a8ab6765272..604fced099e3 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateTypedResourceFileAction.java @@ -39,8 +39,8 @@ import com.intellij.psi.xml.XmlTag; import com.intellij.util.PsiNavigateUtil; import com.intellij.xml.refactoring.XmlTagInplaceRenamer; import org.jetbrains.android.AndroidFileTemplateProvider; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -138,7 +138,7 @@ public class CreateTypedResourceFileAction extends CreateElementActionBase { public Boolean compute() { PsiElement e = element; while (e != null) { - if (e instanceof PsiDirectory && ResourceManager.isResourceSubdirectory((PsiDirectory)e, myResourceType)) { + if (e instanceof PsiDirectory && AndroidResourceUtil.isResourceSubdirectory((PsiDirectory)e, myResourceType)) { return true; } e = e.getParent(); diff --git a/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java b/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java index 00efd1826104..13c6a3406be8 100644 --- a/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java +++ b/plugins/android/src/org/jetbrains/android/actions/CreateXmlResourceDialog.java @@ -20,7 +20,6 @@ import org.jetbrains.android.dom.resources.ResourceElement; import org.jetbrains.android.dom.resources.Resources; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.facet.AndroidRootUtil; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.uipreview.DeviceConfiguratorPanel; import org.jetbrains.android.uipreview.InvalidOptionValueException; import org.jetbrains.android.util.AndroidBundle; @@ -112,7 +111,7 @@ public class CreateXmlResourceDialog extends DialogWrapper { }; myDeviceConfigurationWrapper.add(myDeviceConfiguratorPanel, BorderLayout.CENTER); - final String defaultResFileName = ResourceManager.getDefaultResourceFileName(resourceType.getName()); + final String defaultResFileName = AndroidResourceUtil.getDefaultResourceFileName(resourceType.getName()); if (defaultResFileName != null) { myFileNameField.setText(defaultResFileName); } @@ -197,7 +196,7 @@ public class CreateXmlResourceDialog extends DialogWrapper { return new ValidationInfo(AndroidBundle.message("not.resource.file.error", FileUtil.toSystemDependentName(resFile.getPath()))); } - for (ResourceElement element : ResourceManager.getValueResourcesFromElement(resourceType.getName(), resources)) { + for (ResourceElement element : AndroidResourceUtil.getValueResourcesFromElement(resourceType.getName(), resources)) { if (resourceName.equals(element.getName().getValue())) { return new ValidationInfo("resource '" + resourceName + "' already exists in " + FileUtil.toSystemDependentName( resFile.getPath())); diff --git a/plugins/android/src/org/jetbrains/android/actions/GotoResourceAction.java b/plugins/android/src/org/jetbrains/android/actions/GotoResourceAction.java index 25c5d119889b..807fe88639b6 100644 --- a/plugins/android/src/org/jetbrains/android/actions/GotoResourceAction.java +++ b/plugins/android/src/org/jetbrains/android/actions/GotoResourceAction.java @@ -29,7 +29,6 @@ import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlTag; import com.intellij.ui.awt.RelativePoint; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.util.AndroidBundle; import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; @@ -37,6 +36,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.*; +import java.util.List; /** * @author Eugene.Kudelevsky @@ -66,7 +66,7 @@ public class GotoResourceAction extends AnAction { if (element != null) { PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class); if (field != null) { - if (AndroidResourceUtil.isRJavaField(file, field)) { + if (isRJavaField(file, field)) { enabled = true; } } @@ -75,14 +75,14 @@ public class GotoResourceAction extends AnAction { if (element != null) { PsiElement targetElement = ((PsiReferenceExpression)element).resolve(); if (targetElement instanceof PsiField) { - if (AndroidResourceUtil.isRJavaField(targetElement.getContainingFile(), (PsiField)targetElement)) { + if (isRJavaField(targetElement.getContainingFile(), (PsiField)targetElement)) { enabled = true; } } } } } - presentation.setEnabled(enabled || ResourceManager.isInResourceSubdirectory(file, null)); + presentation.setEnabled(enabled || AndroidResourceUtil.isInResourceSubdirectory(file, null)); return; } } @@ -90,7 +90,7 @@ public class GotoResourceAction extends AnAction { else if (PlatformDataKeys.FILE_EDITOR.getData(dataContext) != null) { PsiFile psiFile = getPsiFileByVirtualFileKey(project, dataContext); if (psiFile != null) { - boolean enabled = AndroidFacet.getInstance(psiFile) != null && ResourceManager.isInResourceSubdirectory(psiFile, null); + boolean enabled = AndroidFacet.getInstance(psiFile) != null && AndroidResourceUtil.isInResourceSubdirectory(psiFile, null); presentation.setEnabled(enabled); return; } @@ -145,14 +145,16 @@ public class GotoResourceAction extends AnAction { } PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class, false); if (field != null) { - return AndroidResourceUtil.findResources(field); + final List elements = AndroidResourceUtil.findResourcesByField(field); + return elements.toArray(new PsiElement[elements.size()]); } while (element != null) { element = PsiTreeUtil.getParentOfType(element, PsiReferenceExpression.class); if (element != null) { PsiElement targetElement = ((PsiReferenceExpression)element).resolve(); if (targetElement instanceof PsiField) { - return AndroidResourceUtil.findResources((PsiField)targetElement); + final List elements = AndroidResourceUtil.findResourcesByField((PsiField)targetElement); + return elements.toArray(new PsiElement[elements.size()]); } } } @@ -184,4 +186,17 @@ public class GotoResourceAction extends AnAction { AndroidUtils.navigateTo(targets, getRelativePointToShowPopup(context)); } } + + private static boolean isRJavaField(@NotNull PsiFile file, @NotNull PsiField field) { + PsiClass c = field.getContainingClass(); + if (c == null) return false; + c = c.getContainingClass(); + if (c != null && AndroidUtils.R_CLASS_NAME.equals(c.getName())) { + AndroidFacet facet = AndroidFacet.getInstance(file); + if (facet != null) { + return AndroidUtils.isRClassFile(facet, file); + } + } + return false; + } } diff --git a/plugins/android/src/org/jetbrains/android/dom/AndroidDomUtil.java b/plugins/android/src/org/jetbrains/android/dom/AndroidDomUtil.java index 2ef27684c52c..c3f28df316d1 100644 --- a/plugins/android/src/org/jetbrains/android/dom/AndroidDomUtil.java +++ b/plugins/android/src/org/jetbrains/android/dom/AndroidDomUtil.java @@ -42,6 +42,7 @@ import org.jetbrains.android.dom.xml.PreferenceElement; import org.jetbrains.android.dom.xml.XmlResourceElement; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.resourceManagers.ResourceManager; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -127,7 +128,7 @@ public class AndroidDomUtil { if (containsReference) { if (resourceTypes.contains("color")) resourceTypes.add("drawable"); if (resourceTypes.size() == 0) { - resourceTypes.addAll(ResourceManager.REFERABLE_RESOURCE_TYPES); + resourceTypes.addAll(AndroidResourceUtil.REFERABLE_RESOURCE_TYPES); } } if (resourceTypes.size() > 0) { diff --git a/plugins/android/src/org/jetbrains/android/dom/AndroidResourceDomFileDescription.java b/plugins/android/src/org/jetbrains/android/dom/AndroidResourceDomFileDescription.java index bf2d4caf3e2f..fef6754978a0 100644 --- a/plugins/android/src/org/jetbrains/android/dom/AndroidResourceDomFileDescription.java +++ b/plugins/android/src/org/jetbrains/android/dom/AndroidResourceDomFileDescription.java @@ -23,7 +23,7 @@ import com.intellij.openapi.util.Computable; import com.intellij.psi.xml.XmlFile; import com.intellij.util.xml.DomElement; import com.intellij.util.xml.DomFileDescription; -import org.jetbrains.android.resourceManagers.ResourceManager; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.annotations.NonNls; @@ -59,7 +59,7 @@ public abstract class AndroidResourceDomFileDescription ex return false; } for (String resourceType : resourceTypes) { - if (ResourceManager.isInResourceSubdirectory(file, resourceType)) { + if (AndroidResourceUtil.isInResourceSubdirectory(file, resourceType)) { return AndroidFacet.getInstance(file) != null; } } diff --git a/plugins/android/src/org/jetbrains/android/dom/AndroidXmlExtension.java b/plugins/android/src/org/jetbrains/android/dom/AndroidXmlExtension.java index c5382783395f..bf892f4fab03 100644 --- a/plugins/android/src/org/jetbrains/android/dom/AndroidXmlExtension.java +++ b/plugins/android/src/org/jetbrains/android/dom/AndroidXmlExtension.java @@ -24,7 +24,7 @@ import com.intellij.psi.impl.source.xml.TagNameReference; import com.intellij.psi.xml.XmlFile; import com.intellij.xml.DefaultXmlExtension; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.resourceManagers.ResourceManager; +import org.jetbrains.android.util.AndroidResourceUtil; /** * @author Eugene.Kudelevsky @@ -47,7 +47,7 @@ public class AndroidXmlExtension extends DefaultXmlExtension { } return ApplicationManager.getApplication().runReadAction(new Computable() { public Boolean compute() { - return ResourceManager.isInResourceSubdirectory(file, null); + return AndroidResourceUtil.isInResourceSubdirectory(file, null); } }); } diff --git a/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReference.java b/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReference.java index 552784f5432a..b7f73cfae8fc 100644 --- a/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReference.java +++ b/plugins/android/src/org/jetbrains/android/dom/converters/AndroidResourceReference.java @@ -86,7 +86,7 @@ public class AndroidResourceReference extends PsiReferenceBase.Poly String resType = value.getResourceType(); if (resType != null && newElementName != null) { myValue.setValue(ResourceValue.referenceTo(value.getPrefix(), value.getPackage(), resType, - ResourceManager.getResourceName(resType, newElementName))); + AndroidResourceUtil.getResourceName(resType, newElementName))); } return myValue.getXmlTag(); } diff --git a/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java b/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java index 4e2d2eee87a4..6c14aa0600cc 100644 --- a/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java +++ b/plugins/android/src/org/jetbrains/android/dom/converters/ResourceReferenceConverter.java @@ -144,7 +144,7 @@ public class ResourceReferenceConverter extends ResolvingConverter= 0) { - containerName = ResourceManager.getDefaultResourceFileName(myResourceType); + if (ArrayUtil.find(AndroidResourceUtil.VALUE_RESOURCE_TYPES, myResourceType) >= 0) { + containerName = AndroidResourceUtil.getDefaultResourceFileName(myResourceType); } else { containerName = '"' + myResourceType + "\" directory"; @@ -358,7 +358,7 @@ public class ResourceReferenceConverter extends ResolvingConverter= 0) { + if (ArrayUtil.find(AndroidResourceUtil.VALUE_RESOURCE_TYPES, myResourceType) >= 0) { String initialValue = !myResourceType.equals("id") ? "value" : null; ResourceElement resElement = manager.addValueResource(myResourceType, myResourceName, initialValue); if (resElement != null) { diff --git a/plugins/android/src/org/jetbrains/android/dom/resources/Item.java b/plugins/android/src/org/jetbrains/android/dom/resources/Item.java index 8b6a01350bc2..b2472ff5801d 100644 --- a/plugins/android/src/org/jetbrains/android/dom/resources/Item.java +++ b/plugins/android/src/org/jetbrains/android/dom/resources/Item.java @@ -23,7 +23,7 @@ import org.jetbrains.android.dom.attrs.AttributeFormat; import org.jetbrains.android.dom.converters.FormatConverter; import org.jetbrains.android.dom.converters.QuietResourceReferenceConverter; import org.jetbrains.android.dom.converters.StaticEnumConverter; -import org.jetbrains.android.resourceManagers.ResourceManager; +import org.jetbrains.android.util.AndroidResourceUtil; import java.util.List; @@ -38,7 +38,7 @@ import java.util.List; public interface Item extends ResourceElement { class TypeConverter extends StaticEnumConverter { public TypeConverter() { - super(ArrayUtil.toStringArray(ResourceManager.REFERABLE_RESOURCE_TYPES)); + super(ArrayUtil.toStringArray(AndroidResourceUtil.REFERABLE_RESOURCE_TYPES)); } } diff --git a/plugins/android/src/org/jetbrains/android/dom/resources/ResourcesDomFileDescription.java b/plugins/android/src/org/jetbrains/android/dom/resources/ResourcesDomFileDescription.java index f5a0d30398ec..5f11bca17612 100644 --- a/plugins/android/src/org/jetbrains/android/dom/resources/ResourcesDomFileDescription.java +++ b/plugins/android/src/org/jetbrains/android/dom/resources/ResourcesDomFileDescription.java @@ -20,9 +20,9 @@ import com.intellij.openapi.util.Computable; import com.intellij.util.xml.DomFileDescription; import com.intellij.psi.xml.XmlFile; import com.intellij.openapi.module.Module; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.android.resourceManagers.ResourceManager; /** * @author yole @@ -36,7 +36,7 @@ public class ResourcesDomFileDescription extends DomFileDescription { public boolean isMyFile(@NotNull final XmlFile file, @Nullable Module module) { return ApplicationManager.getApplication().runReadAction(new Computable() { public Boolean compute() { - return ResourceManager.isInResourceSubdirectory(file, "values"); + return AndroidResourceUtil.isInResourceSubdirectory(file, "values"); } }); } diff --git a/plugins/android/src/org/jetbrains/android/inspections/AndroidNonConstantResIdsInSwitchInspection.java b/plugins/android/src/org/jetbrains/android/inspections/AndroidNonConstantResIdsInSwitchInspection.java index 2e2562eaa835..75a7e8d4f450 100644 --- a/plugins/android/src/org/jetbrains/android/inspections/AndroidNonConstantResIdsInSwitchInspection.java +++ b/plugins/android/src/org/jetbrains/android/inspections/AndroidNonConstantResIdsInSwitchInspection.java @@ -67,9 +67,7 @@ public class AndroidNonConstantResIdsInSwitchInspection extends LocalInspectionT } final PsiField resolvedField = (PsiField)resolvedElement; - final PsiFile containingFile = resolvedField.getContainingFile(); - - if (containingFile == null || !AndroidResourceUtil.isRJavaField(containingFile, resolvedField)) { + if (!AndroidResourceUtil.isResourceField(resolvedField)) { return; } diff --git a/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java b/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java index 750a3f0c882c..fa2432272dca 100644 --- a/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java +++ b/plugins/android/src/org/jetbrains/android/resourceManagers/LocalResourceManager.java @@ -27,6 +27,7 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; import com.intellij.psi.PsiFile; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.xml.XmlFile; @@ -57,11 +58,7 @@ import java.util.*; import static org.jetbrains.android.util.AndroidUtils.loadDomElement; /** - * Created by IntelliJ IDEA. - * User: Eugene.Kudelevsky - * Date: Mar 30, 2009 - * Time: 7:44:03 PM - * To change this template use File | Settings | File Templates. + * @author Eugene.Kudelevsky */ public class LocalResourceManager extends ResourceManager { private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.resourceManagers.ResourceManager"); @@ -283,7 +280,7 @@ public class LocalResourceManager extends ResourceManager { // must be invoked in a write action @Nullable public ResourceElement addValueResource(@NotNull final String type, @NotNull final String name, @Nullable final String value) { - String resourceFileName = getDefaultResourceFileName(type); + String resourceFileName = AndroidResourceUtil.getDefaultResourceFileName(type); if (resourceFileName == null) { throw new IllegalArgumentException("Incorrect resource type"); } @@ -316,4 +313,43 @@ public class LocalResourceManager extends ResourceManager { return null; } } + + @NotNull + public List findResourcesByField(@NotNull PsiField field) { + final String type = AndroidResourceUtil.getResourceClassName(field); + if (type == null) { + return Collections.emptyList(); + } + + final String fieldName = field.getName(); + if (fieldName == null) { + return Collections.emptyList(); + } + return findResourcesByFieldName(type, fieldName); + } + + @NotNull + public List findResourcesByFieldName(@NotNull String resClassName, @NotNull String fieldName) { + List targets = new ArrayList(); + if (resClassName.equals("id")) { + targets.addAll(findIdDeclarations(fieldName)); + } + for (PsiFile file : findResourceFiles(resClassName, fieldName, false)) { + targets.add(file); + } + for (ResourceElement element : findValueResources(resClassName, fieldName, false)) { + targets.add(element.getName().getXmlAttributeValue()); + } + if (resClassName.equals("attr")) { + for (Attr attr : findAttrs(fieldName)) { + targets.add(attr.getName().getXmlAttributeValue()); + } + } + else if (resClassName.equals("styleable")) { + for (DeclareStyleable styleable : findStyleables(fieldName)) { + targets.add(styleable.getName().getXmlAttributeValue()); + } + } + return targets; + } } diff --git a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java index 0c69c063e21c..f6fcfec4ffa6 100644 --- a/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java +++ b/plugins/android/src/org/jetbrains/android/resourceManagers/ResourceManager.java @@ -16,22 +16,18 @@ package org.jetbrains.android.resourceManagers; import com.android.resources.ResourceType; -import com.android.sdklib.SdkConstants; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; -import com.intellij.util.ArrayUtil; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashSet; import com.intellij.util.indexing.FileBasedIndex; @@ -39,10 +35,8 @@ import com.intellij.util.xml.DomElement; import org.jetbrains.android.AndroidIdIndex; import org.jetbrains.android.AndroidValueResourcesIndex; import org.jetbrains.android.dom.attrs.AttributeDefinitions; -import org.jetbrains.android.dom.resources.Item; import org.jetbrains.android.dom.resources.ResourceElement; import org.jetbrains.android.dom.resources.Resources; -import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidUtils; import org.jetbrains.android.util.ResourceEntry; @@ -59,20 +53,8 @@ import static java.util.Collections.addAll; public abstract class ResourceManager { private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.resourceManagers.LocalResourceManager"); - public static final Set REFERABLE_RESOURCE_TYPES = new HashSet(); - public static final String[] FILE_RESOURCE_TYPES = new String[]{"drawable", "anim", "layout", "values", "menu", "xml", "raw", "color"}; - public static final String[] VALUE_RESOURCE_TYPES = - new String[]{"drawable", "dimen", "color", "string", "style", "array", "id", "bool", "integer", "integer-array"}; - private static final String[] DRAWABLE_EXTENSIONS = new String[]{AndroidUtils.PNG_EXTENSION, "jpg", "gif"}; - protected final Module myModule; - static { - addAll(REFERABLE_RESOURCE_TYPES, FILE_RESOURCE_TYPES); - addAll(REFERABLE_RESOURCE_TYPES, VALUE_RESOURCE_TYPES); - REFERABLE_RESOURCE_TYPES.remove("values"); - } - protected ResourceManager(@NotNull Module module) { myModule = module; } @@ -81,14 +63,6 @@ public abstract class ResourceManager { return myModule; } - @Nullable - public static String getDefaultResourceFileName(@NotNull String resourceType) { - if (ArrayUtil.find(VALUE_RESOURCE_TYPES, resourceType) < 0) { - return null; - } - return resourceType + "s.xml"; - } - @NotNull public abstract VirtualFile[] getAllResourceDirs(); @@ -109,38 +83,6 @@ public abstract class ResourceManager { return AndroidResourceUtil.getResourceSubdirs(resourceType, getAllResourceDirs()); } - @NotNull - public static String getResourceName(@NotNull String resourceType, @NotNull String fileName) { - String extension = FileUtil.getExtension(fileName); - String s = FileUtil.getNameWithoutExtension(fileName); - if (resourceType.equals("drawable") && ArrayUtil.find(DRAWABLE_EXTENSIONS, extension) >= 0) { - if (s.endsWith(".9") && extension.equals(AndroidUtils.PNG_EXTENSION)) { - return s.substring(0, s.length() - 2); - } - return s; - } - return s; - } - - private static boolean isCorrectFileName(@NotNull String resourceType, @NotNull String fileName) { - return getResourceName(resourceType, fileName) != null; - } - - public static boolean equal(@Nullable String s1, @Nullable String s2, boolean distinguishDelimeters) { - if (s1 == null || s2 == null) { - return false; - } - if (s1.length() != s2.length()) return false; - for (int i = 0, n = s1.length(); i < n; i++) { - char c1 = s1.charAt(i); - char c2 = s2.charAt(i); - if (distinguishDelimeters || (Character.isLetterOrDigit(c1) && Character.isLetterOrDigit(c2))) { - if (c1 != c2) return false; - } - } - return true; - } - @NotNull public List findResourceFiles(@NotNull String resType, @Nullable String resName, @@ -153,8 +95,8 @@ public abstract class ResourceManager { for (final VirtualFile resFile : dir.getChildren()) { String extension = resFile.getExtension(); if (extensions.length == 0 || extensionSet.contains(extension)) { - String s = getResourceName(resType, resFile.getName()); - if (resName == null || equal(resName, s, distinguishDelimetersInName)) { + String s = AndroidResourceUtil.getResourceName(resType, resFile.getName()); + if (resName == null || AndroidUtils.equal(resName, s, distinguishDelimetersInName)) { PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() { @Nullable public PsiFile compute() { @@ -220,7 +162,7 @@ public abstract class ResourceManager { if (!resources.isValid() || myModule.isDisposed() || myModule.getProject().isDisposed()) { return; } - result.addAll(getValueResourcesFromElement(resourceType, resources)); + result.addAll(AndroidResourceUtil.getValueResourcesFromElement(resourceType, resources)); } }); } @@ -250,7 +192,7 @@ public abstract class ResourceManager { } String type = AndroidResourceUtil.getResourceTypeByDirName(dir.getName()); if (type == null) return null; - return isCorrectFileName(type, file.getName()) ? type : null; + return type; } }); } @@ -262,8 +204,7 @@ public abstract class ResourceManager { for (VirtualFile dir : dirs) { for (VirtualFile resourceFile : dir.getChildren()) { if (resourceFile.isDirectory()) continue; - String resName = getResourceName(resourceType, resourceFile.getName()); - if (resName != null) result.add(resName); + result.add(AndroidResourceUtil.getResourceName(resourceType, resourceFile.getName())); } } return result; @@ -313,52 +254,40 @@ public abstract class ResourceManager { return result; } - @NotNull - public static List getValueResourcesFromElement(@NotNull String resourceType, Resources resources) { - List result = new ArrayList(); - if (resourceType.equals("string")) { - result.addAll(resources.getStrings()); - } - else if (resourceType.equals("drawable")) { - result.addAll(resources.getDrawables()); - } - else if (resourceType.equals("color")) { - result.addAll(resources.getColors()); - } - else if (resourceType.equals("dimen")) { - result.addAll(resources.getDimens()); - } - else if (resourceType.equals("style")) { - result.addAll(resources.getStyles()); - } - else if (resourceType.equals("array")) { - result.addAll(resources.getStringArrays()); - result.addAll(resources.getIntegerArrays()); - result.addAll(resources.getArrays()); - } - else if (resourceType.equals("integer")) { - result.addAll(resources.getIntegers()); - } - else if (resourceType.equals("bool")) { - result.addAll(resources.getBools()); - } - for (Item item : resources.getItems()) { - String type = item.getType().getValue(); - if (resourceType.equals(type)) { - result.add(item); - } - } - return result; - } - @Nullable public abstract AttributeDefinitions getAttributeDefinitions(); // searches only declarations such as "@+id/..." @Nullable - public List findIdDeclarations(@NotNull String id) { - List declarations = new ArrayList(); - collectIdDeclarations(id, declarations); + public List findIdDeclarations(@NotNull final String id) { + final List declarations = new ArrayList(); + final Collection files = + FileBasedIndex.getInstance().getContainingFiles(AndroidIdIndex.INDEX_ID, id, GlobalSearchScope.allScope(myModule.getProject())); + final Set fileSet = new HashSet(files); + final PsiManager psiManager = PsiManager.getInstance(myModule.getProject()); + + for (VirtualFile subdir : getResourceSubdirsToSearchIds()) { + for (VirtualFile file : subdir.getChildren()) { + if (fileSet.contains(file)) { + final PsiFile psiFile = psiManager.findFile(file); + + if (psiFile instanceof XmlFile) { + psiFile.accept(new XmlRecursiveElementVisitor() { + @Override + public void visitXmlAttributeValue(XmlAttributeValue attributeValue) { + if (AndroidResourceUtil.isIdDeclaration(attributeValue)) { + final String idInAttr = AndroidResourceUtil.getResourceNameByReferenceText(attributeValue.getValue()); + + if (id.equals(idInAttr)) { + declarations.add(attributeValue); + } + } + } + }); + } + } + } + } return declarations; } @@ -401,7 +330,7 @@ public abstract class ResourceManager { } @NotNull - protected List getResourceSubdirsToSearchIds() { + private List getResourceSubdirsToSearchIds() { final List resSubdirs = new ArrayList(); resSubdirs.addAll(getResourceSubdirs(ResourceType.LAYOUT.getName())); resSubdirs.addAll(getResourceSubdirs(ResourceType.MENU.getName())); @@ -435,97 +364,10 @@ public abstract class ResourceManager { for (ResourceElement element : getValueResources(resourceType, fileSet)) { final String name = element.getName().getValue(); - if (equal(resourceName, name, distinguishDelimetersInName)) { + if (AndroidUtils.equal(resourceName, name, distinguishDelimetersInName)) { result.add(element); } } return result; } - - public static boolean isInResourceSubdirectory(@NotNull PsiFile file, @Nullable String resourceType) { - file = file.getOriginalFile(); - PsiDirectory dir = file.getContainingDirectory(); - if (dir == null) return false; - return isResourceSubdirectory(dir, resourceType); - } - - public static boolean isResourceSubdirectory(PsiDirectory dir, String resourceType) { - if (resourceType != null && !dir.getName().startsWith(resourceType)) return false; - dir = dir.getParent(); - if (dir == null) return false; - if ("default".equals(dir.getName())) { - dir = dir.getParentDirectory(); - } - return dir != null && isResourceDirectory(dir); - } - - public static boolean isResourceDirectory(VirtualFile dir, Project project) { - Module module = ModuleUtil.findModuleForFile(dir, project); - if (module != null) { - AndroidFacet facet = AndroidFacet.getInstance(module); - return facet != null && facet.getLocalResourceManager().isResourceDir(dir); - } - return false; - } - - public static boolean isResourceDirectory(PsiDirectory dir) { - // check facet settings - VirtualFile vf = dir.getVirtualFile(); - - if (isResourceDirectory(vf, dir.getProject())) { - return true; - } - - // method can be invoked for system resource dir, so we should check it - if (!SdkConstants.FD_RES.equals(dir.getName())) return false; - dir = dir.getParent(); - if (dir != null) { - if (dir.findFile(SdkConstants.FN_ANDROID_MANIFEST_XML) != null) { - return true; - } - dir = dir.getParent(); - if (dir != null) { - if (containsAndroidJar(dir)) return true; - dir = dir.getParent(); - if (dir != null) { - return containsAndroidJar(dir); - } - } - } - return false; - } - - private static boolean containsAndroidJar(@NotNull PsiDirectory psiDirectory) { - return psiDirectory.findFile(SdkConstants.FN_FRAMEWORK_LIBRARY) != null; - } - - public void collectIdDeclarations(@NotNull final String id, final List targets) { - final Collection files = - FileBasedIndex.getInstance().getContainingFiles(AndroidIdIndex.INDEX_ID, id, GlobalSearchScope.allScope(myModule.getProject())); - final Set fileSet = new HashSet(files); - final PsiManager psiManager = PsiManager.getInstance(myModule.getProject()); - - for (VirtualFile subdir : getResourceSubdirsToSearchIds()) { - for (VirtualFile file : subdir.getChildren()) { - if (fileSet.contains(file)) { - final PsiFile psiFile = psiManager.findFile(file); - - if (psiFile instanceof XmlFile) { - psiFile.accept(new XmlRecursiveElementVisitor() { - @Override - public void visitXmlAttributeValue(XmlAttributeValue attributeValue) { - if (AndroidResourceUtil.isIdDeclaration(attributeValue)) { - final String idInAttr = AndroidResourceUtil.getResourceNameByReferenceText(attributeValue.getValue()); - - if (id.equals(idInAttr)) { - targets.add(attributeValue); - } - } - } - }); - } - } - } - } - } } diff --git a/plugins/android/src/org/jetbrains/android/uipreview/AndroidLayoutPreviewToolWindowManager.java b/plugins/android/src/org/jetbrains/android/uipreview/AndroidLayoutPreviewToolWindowManager.java index 5e835b8ab3cb..d2d5c9791214 100644 --- a/plugins/android/src/org/jetbrains/android/uipreview/AndroidLayoutPreviewToolWindowManager.java +++ b/plugins/android/src/org/jetbrains/android/uipreview/AndroidLayoutPreviewToolWindowManager.java @@ -47,12 +47,12 @@ import com.intellij.util.ui.update.Update; import org.jetbrains.android.dom.layout.LayoutDomFileDescription; import org.jetbrains.android.facet.AndroidFacet; import org.jetbrains.android.maven.AndroidMavenUtil; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.android.sdk.AndroidPlatform; import org.jetbrains.android.sdk.AndroidSdkAdditionalData; import org.jetbrains.android.sdk.AndroidSdkType; import org.jetbrains.android.sdk.AndroidSdkUtils; import org.jetbrains.android.util.AndroidBundle; +import org.jetbrains.android.util.AndroidResourceUtil; import org.jetbrains.android.util.AndroidSdkNotConfiguredException; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -534,13 +534,13 @@ public class AndroidLayoutPreviewToolWindowManager implements ProjectComponent { return; } - if (ResourceManager.isResourceDirectory(parent, myProject)) { + if (AndroidResourceUtil.isLocalResourceDirectory(parent, myProject)) { myToolWindowForm.updateLocales(); render(); } final VirtualFile gp = parent.getParent(); - if (gp != null && ResourceManager.isResourceDirectory(gp, myProject)) { + if (gp != null && AndroidResourceUtil.isLocalResourceDirectory(gp, myProject)) { myToolWindowForm.updateLocales(); render(); } diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java index f2a71e6b7738..54fe08ed0ffb 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidResourceUtil.java @@ -16,15 +16,17 @@ package org.jetbrains.android.util; +import com.android.sdklib.SdkConstants; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ModulePackageIndex; import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.psi.util.PsiUtilCore; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlTag; @@ -33,10 +35,10 @@ import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashSet; import org.jetbrains.android.dom.manifest.Manifest; -import org.jetbrains.android.dom.resources.*; +import org.jetbrains.android.dom.resources.Item; +import org.jetbrains.android.dom.resources.ResourceElement; +import org.jetbrains.android.dom.resources.Resources; import org.jetbrains.android.facet.AndroidFacet; -import org.jetbrains.android.resourceManagers.LocalResourceManager; -import org.jetbrains.android.resourceManagers.ResourceManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -45,11 +47,24 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import static java.util.Collections.addAll; + /** * @author Eugene.Kudelevsky */ public class AndroidResourceUtil { public static final String NEW_ID_PREFIX = "@+id/"; + public static final String[] VALUE_RESOURCE_TYPES = + new String[]{"drawable", "dimen", "color", "string", "style", "array", "id", "bool", "integer", "integer-array"}; + private static final String[] DRAWABLE_EXTENSIONS = new String[]{AndroidUtils.PNG_EXTENSION, "jpg", "gif"}; + public static final Set REFERABLE_RESOURCE_TYPES = new HashSet(); + public static final String[] FILE_RESOURCE_TYPES = new String[]{"drawable", "anim", "layout", "values", "menu", "xml", "raw", "color"}; + + static { + addAll(REFERABLE_RESOURCE_TYPES, FILE_RESOURCE_TYPES); + addAll(REFERABLE_RESOURCE_TYPES, VALUE_RESOURCE_TYPES); + REFERABLE_RESOURCE_TYPES.remove("values"); + } private AndroidResourceUtil() { } @@ -60,47 +75,51 @@ public class AndroidResourceUtil { @NotNull String resourceName, boolean onlyInOwnPackages) { resourceName = getRJavaFieldName(resourceName); - List result = findResourceFieldsByName(facet, resClassName, resourceName, onlyInOwnPackages); - return result.toArray(new PsiField[result.size()]); - } - public static List findResourceFieldsByName(AndroidFacet facet, - String innerClassName, - String fieldName, - boolean onlyInOwnPackages) { - List rClassFiles = findRClassFiles(facet, onlyInOwnPackages); - List result = new ArrayList(); + final List rClassFiles = findRJavaFiles(facet, onlyInOwnPackages); + final List result = new ArrayList(); + for (PsiJavaFile rClassFile : rClassFiles) { - if (rClassFile == null) continue; - PsiClass rClass = findClass(rClassFile.getClasses(), AndroidUtils.R_CLASS_NAME); + if (rClassFile == null) { + continue; + } + final PsiClass rClass = findClass(rClassFile.getClasses(), AndroidUtils.R_CLASS_NAME); + if (rClass != null) { - PsiClass resourceTypeClass = findClass(rClass.getInnerClasses(), innerClassName); + final PsiClass resourceTypeClass = findClass(rClass.getInnerClasses(), resClassName); + if (resourceTypeClass != null) { - PsiField field = resourceTypeClass.findFieldByName(fieldName, false); + final PsiField field = resourceTypeClass.findFieldByName(resourceName, false); + if (field != null) { result.add(field); } } } } - return result; + return result.toArray(new PsiField[result.size()]); } @NotNull - public static List findRClassFiles(@NotNull AndroidFacet facet, boolean onlyInOwnPackages) { - Module module = facet.getModule(); + private static List findRJavaFiles(@NotNull AndroidFacet facet, boolean onlyInOwnPackages) { + final Module module = facet.getModule(); final Project project = module.getProject(); - Manifest manifest = facet.getManifest(); + final Manifest manifest = facet.getManifest(); + if (manifest == null) { return Collections.emptyList(); } final Set dirs = new HashSet(); collectDirsForPackage(module, project, null, dirs, new HashSet(), onlyInOwnPackages); - List rJavaFiles = new ArrayList(); + + final List rJavaFiles = new ArrayList(); + for (PsiDirectory dir : dirs) { - VirtualFile file = dir.getVirtualFile().findChild(AndroidCommonUtils.R_JAVA_FILENAME); + final VirtualFile file = dir.getVirtualFile().findChild(AndroidCommonUtils.R_JAVA_FILENAME); + if (file != null) { - PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + final PsiFile psiFile = PsiManager.getInstance(project).findFile(file); + if (psiFile instanceof PsiJavaFile) { rJavaFiles.add((PsiJavaFile)psiFile); } @@ -115,7 +134,10 @@ public class AndroidResourceUtil { final Set dirs, Set visitedModules, boolean onlyInOwnPackages) { - if (!visitedModules.add(module)) return; + if (!visitedModules.add(module)) { + return; + } + if (packageName != null) { ModulePackageIndex.getInstance(module).getDirsByPackageName(packageName, false).forEach(new Processor() { public boolean process(final VirtualFile directory) { @@ -124,11 +146,13 @@ public class AndroidResourceUtil { } }); } - AndroidFacet ownFacet = AndroidFacet.getInstance(module); + final AndroidFacet ownFacet = AndroidFacet.getInstance(module); String ownPackageName = null; + if (ownFacet != null) { - Manifest ownManifest = ownFacet.getManifest(); + final Manifest ownManifest = ownFacet.getManifest(); ownPackageName = ownManifest != null ? ownManifest.getPackage().getValue() : null; + if (ownPackageName != null && !ownPackageName.equals(packageName)) { ModulePackageIndex.getInstance(module).getDirsByPackageName(ownPackageName, false).forEach(new Processor() { public boolean process(final VirtualFile directory) { @@ -138,6 +162,7 @@ public class AndroidResourceUtil { }); } } + for (Module otherModule : ModuleManager.getInstance(project).getModules()) { if (ModuleRootManager.getInstance(otherModule).isDependsOn(module)) { collectDirsForPackage(otherModule, project, packageName != null || onlyInOwnPackages ? packageName : ownPackageName, dirs, @@ -147,7 +172,7 @@ public class AndroidResourceUtil { } @Nullable - public static PsiClass findClass(PsiClass[] classes, @NotNull String name) { + private static PsiClass findClass(@NotNull PsiClass[] classes, @NotNull String name) { for (PsiClass c : classes) { if (name.equals(c.getName())) { return c; @@ -157,23 +182,48 @@ public class AndroidResourceUtil { } @NotNull - public static PsiField[] findResourceFieldsForFileResource(PsiFile file, boolean onlyInOwnPackages) { - AndroidFacet facet = AndroidFacet.getInstance(file); - if (facet != null) { - LocalResourceManager manager = facet.getLocalResourceManager(); - String resourceType = manager.getFileResourceType(file); - if (resourceType != null) { - String resourceName = ResourceManager.getResourceName(resourceType, file.getName()); - return findResourceFields(facet, resourceType, resourceName, onlyInOwnPackages); - } + public static PsiField[] findResourceFieldsForFileResource(@NotNull PsiFile file, boolean onlyInOwnPackages) { + final AndroidFacet facet = AndroidFacet.getInstance(file); + if (facet == null) { + return PsiField.EMPTY_ARRAY; } - return PsiField.EMPTY_ARRAY; + + final String resourceType = facet.getLocalResourceManager().getFileResourceType(file); + if (resourceType == null) { + return PsiField.EMPTY_ARRAY; + } + + final String resourceName = getResourceName(resourceType, file.getName()); + return findResourceFields(facet, resourceType, resourceName, onlyInOwnPackages); + } + + @NotNull + public static PsiField[] findResourceFieldsForValueResource(XmlTag tag, boolean onlyInOwnPackages) { + final AndroidFacet facet = AndroidFacet.getInstance(tag); + if (facet == null) { + return PsiField.EMPTY_ARRAY; + } + + String fileResType = facet.getLocalResourceManager().getFileResourceType(tag.getContainingFile()); + final String resourceType = "values".equals(fileResType) + ? getResourceTypeByValueResourceTag(tag) + : null; + if (resourceType == null) { + return PsiField.EMPTY_ARRAY; + } + + final String name = tag.getAttributeValue("name"); + if (name == null) { + return PsiField.EMPTY_ARRAY; + } + return findResourceFields(facet, resourceType, name, onlyInOwnPackages); } @NotNull public static String getRJavaFieldName(@NotNull String resourceName) { - String[] identifiers = resourceName.split("\\."); - StringBuilder result = new StringBuilder(); + final String[] identifiers = resourceName.split("\\."); + final StringBuilder result = new StringBuilder(); + for (int i = 0, n = identifiers.length; i < n; i++) { result.append(identifiers[i]); if (i < n - 1) { @@ -184,8 +234,11 @@ public class AndroidResourceUtil { } public static boolean isCorrectAndroidResourceName(@NotNull String resourceName) { - if (resourceName.length() == 0) return false; - String[] identifiers = resourceName.split("\\."); + if (resourceName.length() == 0) { + return false; + } + final String[] identifiers = resourceName.split("\\."); + for (String identifier : identifiers) { if (!StringUtil.isJavaIdentifier(identifier)) { return false; @@ -194,33 +247,8 @@ public class AndroidResourceUtil { return true; } - @NotNull - public static PsiField[] findResourceFieldsForValueResource(XmlTag tag, boolean onlyInOwnPackages) { - AndroidFacet facet = AndroidFacet.getInstance(tag); - if (facet != null) { - String resourceType = getResClassNameByValueResourceTag(facet, tag); - if (resourceType != null) { - String name = tag.getAttributeValue("name"); - if (name != null) { - return findResourceFields(facet, resourceType, name, onlyInOwnPackages); - } - } - } - return PsiField.EMPTY_ARRAY; - } - @Nullable - public static String getResClassNameByValueResourceTag(AndroidFacet facet, XmlTag tag) { - LocalResourceManager manager = facet.getLocalResourceManager(); - String fileResType = manager.getFileResourceType(tag.getContainingFile()); - if ("values".equals(fileResType)) { - return getResourceTypeByValueResourceTag(tag); - } - return null; - } - - @Nullable - public static String getResourceTypeByValueResourceTag(XmlTag tag) { + public static String getResourceTypeByValueResourceTag(@NotNull XmlTag tag) { String resClassName = tag.getName(); resClassName = resClassName.equals("item") ? tag.getAttributeValue("type", null) @@ -232,6 +260,7 @@ public class AndroidResourceUtil { return null; } + @NotNull public static String getResourceTypeByTagName(@NotNull String tagName) { if (tagName.equals("declare-styleable")) { tagName = "styleable"; @@ -244,69 +273,27 @@ public class AndroidResourceUtil { @Nullable public static String getResourceClassName(@NotNull PsiField field) { - PsiClass resourceClass = field.getContainingClass(); + final PsiClass resourceClass = field.getContainingClass(); + if (resourceClass != null) { - PsiClass parentClass = resourceClass.getContainingClass(); - if (parentClass != null) { - if (AndroidUtils.R_CLASS_NAME.equals(parentClass.getName()) && parentClass.getContainingClass() == null) { - return resourceClass.getName(); - } + final PsiClass parentClass = resourceClass.getContainingClass(); + + if (parentClass != null && + AndroidUtils.R_CLASS_NAME.equals(parentClass.getName()) && + parentClass.getContainingClass() == null) { + return resourceClass.getName(); } } return null; } // result contains XmlAttributeValue or PsiFile - @NotNull public static List findResourcesByField(@NotNull PsiField field) { - LocalResourceManager manager = LocalResourceManager.getInstance(field); - if (manager != null) { - return findResourcesByField(manager, field); - } - return Collections.emptyList(); - } - - @NotNull - public static List findResourcesByField(@NotNull LocalResourceManager manager, - @NotNull PsiField field) { - final String type = getResourceClassName(field); - if (type == null) { - return Collections.emptyList(); - } - - final String fieldName = field.getName(); - if (fieldName == null) { - return Collections.emptyList(); - } - return findResourcesByFieldName(manager, type, fieldName); - } - - @NotNull - public static List findResourcesByFieldName(@NotNull LocalResourceManager manager, - @NotNull String resClassName, - @NotNull String fieldName) { - List targets = new ArrayList(); - if (resClassName.equals("id")) { - manager.collectIdDeclarations(fieldName, targets); - } - for (PsiFile file : manager.findResourceFiles(resClassName, fieldName, false)) { - targets.add(file); - } - for (ResourceElement element : manager.findValueResources(resClassName, fieldName, false)) { - targets.add(element.getName().getXmlAttributeValue()); - } - if (resClassName.equals("attr")) { - for (Attr attr : manager.findAttrs(fieldName)) { - targets.add(attr.getName().getXmlAttributeValue()); - } - } - else if (resClassName.equals("styleable")) { - for (DeclareStyleable styleable : manager.findStyleables(fieldName)) { - targets.add(styleable.getName().getXmlAttributeValue()); - } - } - return targets; + final AndroidFacet facet = AndroidFacet.getInstance(field); + return facet != null + ? facet.getLocalResourceManager().findResourcesByField(field) + : Collections.emptyList(); } public static boolean isResourceField(@NotNull PsiField field) { @@ -325,39 +312,36 @@ public class AndroidResourceUtil { return false; } - @NotNull - public static PsiField[] findIdFields(XmlAttributeValue value) { + public static PsiField[] findIdFields(@NotNull XmlAttributeValue value) { if (value.getParent() instanceof XmlAttribute) { return findIdFields((XmlAttribute)value.getParent()); } return PsiField.EMPTY_ARRAY; } - public static boolean isIdDeclaration(String attrValue) { + public static boolean isIdDeclaration(@Nullable String attrValue) { return attrValue != null && attrValue.startsWith(NEW_ID_PREFIX); } - public static boolean isIdReference(String attrValue) { + public static boolean isIdReference(@Nullable String attrValue) { return attrValue != null && attrValue.startsWith("@id/"); } - public static boolean isIdDeclaration(XmlAttributeValue value) { - String s = value.getValue(); - return isIdDeclaration(s); - } - - public static boolean isIdDeclaration(XmlAttribute attribute) { - XmlAttributeValue value = attribute.getValueElement(); - return value != null && isIdDeclaration(value); + public static boolean isIdDeclaration(@NotNull XmlAttributeValue value) { + return isIdDeclaration(value.getValue()); } @NotNull - public static PsiField[] findIdFields(XmlAttribute attribute) { - if (isIdDeclaration(attribute)) { - String id = getResourceNameByReferenceText(attribute.getValue()); + public static PsiField[] findIdFields(@NotNull XmlAttribute attribute) { + final XmlAttributeValue value = attribute.getValueElement(); + + if (value != null && isIdDeclaration(value)) { + final String id = getResourceNameByReferenceText(attribute.getValue()); + if (id != null) { - AndroidFacet facet = AndroidFacet.getInstance(attribute); + final AndroidFacet facet = AndroidFacet.getInstance(attribute); + if (facet != null) { return findResourceFields(facet, "id", id, false); } @@ -375,29 +359,6 @@ public class AndroidResourceUtil { return null; } - public static boolean isRJavaField(@NotNull PsiFile file, @NotNull PsiField field) { - PsiClass aClass = field.getContainingClass(); - if (aClass != null) { - aClass = aClass.getContainingClass(); - if (aClass != null && AndroidUtils.R_CLASS_NAME.equals(aClass.getName())) { - AndroidFacet facet = AndroidFacet.getInstance(file); - if (facet != null) { - return AndroidUtils.isRClassFile(facet, file); - } - } - } - return false; - } - - @NotNull - public static PsiElement[] findResources(@NotNull PsiField resField) { - AndroidFacet facet = AndroidFacet.getInstance(resField); - assert facet != null; - LocalResourceManager manager = facet.getLocalResourceManager(); - List targets = findResourcesByField(manager, resField); - return PsiUtilCore.toPsiElementArray(targets); - } - @NotNull public static ResourceElement addValueResource(@NotNull final String type, @NotNull final Resources resources) { if (type.equals("string")) { @@ -435,19 +396,22 @@ public class AndroidResourceUtil { @Nullable public static String getResourceTypeByDirName(@NotNull String name) { - int index = name.indexOf('-'); - String type = index >= 0 ? name.substring(0, index) : name; - return ArrayUtil.find(ResourceManager.FILE_RESOURCE_TYPES, type) >= 0 ? type : null; + final int index = name.indexOf('-'); + final String type = index >= 0 ? name.substring(0, index) : name; + return ArrayUtil.find(FILE_RESOURCE_TYPES, type) >= 0 ? type : null; } @NotNull public static List getResourceSubdirs(@Nullable String resourceType, @NotNull VirtualFile[] resourceDirs) { - List dirs = new ArrayList(); - if (ArrayUtil.find(ResourceManager.FILE_RESOURCE_TYPES, resourceType) < 0 && resourceType != null) { - return dirs; + if (ArrayUtil.find(FILE_RESOURCE_TYPES, resourceType) < 0 && resourceType != null) { + return Collections.emptyList(); } + final List dirs = new ArrayList(); + for (VirtualFile resourcesDir : resourceDirs) { - if (resourcesDir == null) return dirs; + if (resourcesDir == null) { + return dirs; + } if (resourceType == null) { ContainerUtil.addAll(dirs, resourcesDir.getChildren()); } @@ -460,4 +424,130 @@ public class AndroidResourceUtil { } return dirs; } + + @Nullable + public static String getDefaultResourceFileName(@NotNull String resourceType) { + if (ArrayUtil.find(VALUE_RESOURCE_TYPES, resourceType) < 0) { + return null; + } + return resourceType + "s.xml"; + } + + @NotNull + public static String getResourceName(@NotNull String resourceType, @NotNull String fileName) { + final String extension = FileUtil.getExtension(fileName); + final String s = FileUtil.getNameWithoutExtension(fileName); + + return resourceType.equals("drawable") && + ArrayUtil.find(DRAWABLE_EXTENSIONS, extension) >= 0 && + s.endsWith(".9") && + extension.equals(AndroidUtils.PNG_EXTENSION) + ? s.substring(0, s.length() - 2) + : s; + } + + @NotNull + public static List getValueResourcesFromElement(@NotNull String resourceType, @NotNull Resources resources) { + final List result = new ArrayList(); + + if (resourceType.equals("string")) { + result.addAll(resources.getStrings()); + } + else if (resourceType.equals("drawable")) { + result.addAll(resources.getDrawables()); + } + else if (resourceType.equals("color")) { + result.addAll(resources.getColors()); + } + else if (resourceType.equals("dimen")) { + result.addAll(resources.getDimens()); + } + else if (resourceType.equals("style")) { + result.addAll(resources.getStyles()); + } + else if (resourceType.equals("array")) { + result.addAll(resources.getStringArrays()); + result.addAll(resources.getIntegerArrays()); + result.addAll(resources.getArrays()); + } + else if (resourceType.equals("integer")) { + result.addAll(resources.getIntegers()); + } + else if (resourceType.equals("bool")) { + result.addAll(resources.getBools()); + } + for (Item item : resources.getItems()) { + String type = item.getType().getValue(); + if (resourceType.equals(type)) { + result.add(item); + } + } + return result; + } + + public static boolean isInResourceSubdirectory(@NotNull PsiFile file, @Nullable String resourceType) { + file = file.getOriginalFile(); + PsiDirectory dir = file.getContainingDirectory(); + if (dir == null) return false; + return isResourceSubdirectory(dir, resourceType); + } + + public static boolean isResourceSubdirectory(@NotNull PsiDirectory directory, @Nullable String resourceType) { + PsiDirectory dir = directory; + + if (resourceType != null && !dir.getName().startsWith(resourceType)) { + return false; + } + dir = dir.getParent(); + + if (dir == null) { + return false; + } + if ("default".equals(dir.getName())) { + dir = dir.getParentDirectory(); + } + return dir != null && isResourceDirectory(dir); + } + + public static boolean isLocalResourceDirectory(@NotNull VirtualFile dir, @NotNull Project project) { + final Module module = ModuleUtil.findModuleForFile(dir, project); + + if (module != null) { + final AndroidFacet facet = AndroidFacet.getInstance(module); + return facet != null && facet.getLocalResourceManager().isResourceDir(dir); + } + return false; + } + + public static boolean isResourceDirectory(@NotNull PsiDirectory directory) { + PsiDirectory dir = directory; + // check facet settings + VirtualFile vf = dir.getVirtualFile(); + + if (isLocalResourceDirectory(vf, dir.getProject())) { + return true; + } + + // method can be invoked for system resource dir, so we should check it + if (!SdkConstants.FD_RES.equals(dir.getName())) return false; + dir = dir.getParent(); + if (dir != null) { + if (dir.findFile(SdkConstants.FN_ANDROID_MANIFEST_XML) != null) { + return true; + } + dir = dir.getParent(); + if (dir != null) { + if (containsAndroidJar(dir)) return true; + dir = dir.getParent(); + if (dir != null) { + return containsAndroidJar(dir); + } + } + } + return false; + } + + private static boolean containsAndroidJar(@NotNull PsiDirectory psiDirectory) { + return psiDirectory.findFile(SdkConstants.FN_FRAMEWORK_LIBRARY) != null; + } } diff --git a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java index 34333f8885fc..cfc6f1935f72 100644 --- a/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java +++ b/plugins/android/src/org/jetbrains/android/util/AndroidUtils.java @@ -1021,4 +1021,19 @@ public class AndroidUtils { } return null; } + + public static boolean equal(@Nullable String s1, @Nullable String s2, boolean distinguishDelimeters) { + if (s1 == null || s2 == null) { + return false; + } + if (s1.length() != s2.length()) return false; + for (int i = 0, n = s1.length(); i < n; i++) { + char c1 = s1.charAt(i); + char c2 = s2.charAt(i); + if (distinguishDelimeters || (Character.isLetterOrDigit(c1) && Character.isLetterOrDigit(c2))) { + if (c1 != c2) return false; + } + } + return true; + } } diff --git a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidDomTest.java b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidDomTest.java index 22ded0c7de75..3a73317ca1ae 100644 --- a/plugins/android/testSrc/org/jetbrains/android/dom/AndroidDomTest.java +++ b/plugins/android/testSrc/org/jetbrains/android/dom/AndroidDomTest.java @@ -6,7 +6,7 @@ import com.intellij.testFramework.UsefulTestCase; import com.intellij.util.ArrayUtil; import org.jetbrains.android.AndroidTestCase; import org.jetbrains.android.inspections.AndroidDomInspection; -import org.jetbrains.android.resourceManagers.ResourceManager; +import org.jetbrains.android.util.AndroidResourceUtil; import java.io.IOException; import java.util.ArrayList; @@ -55,7 +55,7 @@ abstract class AndroidDomTest extends AndroidTestCase { protected static List getAllResources() { List list = new ArrayList(); - for (String type : ResourceManager.REFERABLE_RESOURCE_TYPES) { + for (String type : AndroidResourceUtil.REFERABLE_RESOURCE_TYPES) { list.add('@' + type + '/'); } return list;