refactoring

This commit is contained in:
Eugene Kudelevsky
2012-02-13 14:04:09 +04:00
parent 191a7ee0cb
commit c4e272f8d5
26 changed files with 423 additions and 430 deletions
@@ -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<PsiElement> resourceList =
AndroidResourceUtil.findResourcesByFieldName(facet.getLocalResourceManager(), resClassName, resFieldName);
final List<PsiElement> resourceList = facet.getLocalResourceManager().findResourcesByFieldName(resClassName, resFieldName);
final PsiElement[] resources = resourceList.toArray(new PsiElement[resourceList.size()]);
final PsiElement[] wrappedResources = new PsiElement[resources.length];
@@ -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<VirtualFi
if (parent == null) return false;
parent = parent.getParent();
if (parent == null) return false;
return ResourceManager.isResourceDirectory(parent, myProject);
return AndroidResourceUtil.isLocalResourceDirectory(parent, myProject);
}
}
@@ -24,7 +24,7 @@ import com.intellij.psi.PsiReference;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor;
import org.jetbrains.android.resourceManagers.LocalResourceManager;
import org.jetbrains.android.resourceManagers.ResourceManager;
import org.jetbrains.android.util.AndroidResourceUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -49,7 +49,7 @@ public class AndroidReferenceSearchExecutor extends QueryExecutorBase<PsiReferen
String resType = manager.getFileResourceType((PsiFile)refElement);
if (resType != null) {
String resName = ResourceManager.getResourceName(resType, vFile.getName());
String resName = AndroidResourceUtil.getResourceName(resType, vFile.getName());
// unless references can be found by a simple CachedBasedRefSearcher
if (!resName.equals(vFile.getNameWithoutExtension()) && StringUtil.isNotEmpty(resName)) {
params.getOptimizer().searchWord(resName, params.getEffectiveSearchScope(), true, refElement);
@@ -67,7 +67,7 @@ public class AndroidRenameResourceProcessor extends RenamePsiElementProcessor {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
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<PsiFile> resourceFiles = manager.findResourceFiles(type, ResourceManager.getResourceName(type, name));
List<PsiFile> resourceFiles = manager.findResourceFiles(type, AndroidResourceUtil.getResourceName(type, name));
List<PsiFile> alternativeResources = new ArrayList<PsiFile>();
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);
}
}
@@ -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<PsiElement[]>() {
@Override
@@ -170,8 +170,8 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider {
final Map<MyResourceEntry, List<PsiElement>> result = new HashMap<MyResourceEntry, List<PsiElement>>();
Collection<Resources> 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<PsiElement> list = result.get(key);
if (list == null) {
@@ -264,7 +264,7 @@ public class AndroidResourcesLineMarkerProvider implements LineMarkerProvider {
if (resourceMap != null) {
targets = new ArrayList<PsiElement>();
if (resType.equals("id")) {
manager.collectIdDeclarations(fieldName, targets);
targets.addAll(manager.findIdDeclarations(fieldName));
}
List<PsiElement> 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;
@@ -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;
}
@@ -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;
}
@@ -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<Boolean>() {
public Boolean compute() {
return ResourceManager.isResourceDirectory((PsiDirectory)element);
return AndroidResourceUtil.isResourceDirectory((PsiDirectory)element);
}
});
}
@@ -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<Boolean>() {
public Boolean compute() {
return ResourceManager.isResourceDirectory((PsiDirectory)element);
return AndroidResourceUtil.isResourceDirectory((PsiDirectory)element);
}
});
}
@@ -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();
@@ -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()));
@@ -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<PsiElement> 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<PsiElement> 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;
}
}
@@ -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) {
@@ -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<T extends DomElement> ex
return false;
}
for (String resourceType : resourceTypes) {
if (ResourceManager.isInResourceSubdirectory(file, resourceType)) {
if (AndroidResourceUtil.isInResourceSubdirectory(file, resourceType)) {
return AndroidFacet.getInstance(file) != null;
}
}
@@ -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<Boolean>() {
public Boolean compute() {
return ResourceManager.isInResourceSubdirectory(file, null);
return AndroidResourceUtil.isInResourceSubdirectory(file, null);
}
});
}
@@ -86,7 +86,7 @@ public class AndroidResourceReference extends PsiReferenceBase.Poly<XmlElement>
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();
}
@@ -144,7 +144,7 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
? null
: getResourceTypesInCurrentModule(facet);
for (String type : ResourceManager.REFERABLE_RESOURCE_TYPES) {
for (String type : AndroidResourceUtil.REFERABLE_RESOURCE_TYPES) {
String typePrefix = getTypePrefix(resourcePackage, type);
if (value.startsWith(typePrefix)) {
addResourceReferenceValues(facet, type, resourcePackage, result, true);
@@ -202,7 +202,7 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
if (s != null) types.add(s);
}
if (types.size() == 0) {
types.addAll(ResourceManager.REFERABLE_RESOURCE_TYPES);
types.addAll(AndroidResourceUtil.REFERABLE_RESOURCE_TYPES);
}
return types;
}
@@ -342,8 +342,8 @@ public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue
@NotNull
public String getName() {
String containerName;
if (ArrayUtil.find(ResourceManager.VALUE_RESOURCE_TYPES, myResourceType) >= 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<ResourceValue
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
LocalResourceManager manager = myFacet.getLocalResourceManager();
if (ArrayUtil.find(ResourceManager.VALUE_RESOURCE_TYPES, myResourceType) >= 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) {
@@ -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));
}
}
@@ -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<Resources> {
public boolean isMyFile(@NotNull final XmlFile file, @Nullable Module module) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
return ResourceManager.isInResourceSubdirectory(file, "values");
return AndroidResourceUtil.isInResourceSubdirectory(file, "values");
}
});
}
@@ -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;
}
@@ -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<PsiElement> 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<PsiElement> findResourcesByFieldName(@NotNull String resClassName, @NotNull String fieldName) {
List<PsiElement> targets = new ArrayList<PsiElement>();
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;
}
}
@@ -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<String> REFERABLE_RESOURCE_TYPES = new HashSet<String>();
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<PsiFile> 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<PsiFile>() {
@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<ResourceElement> getValueResourcesFromElement(@NotNull String resourceType, Resources resources) {
List<ResourceElement> result = new ArrayList<ResourceElement>();
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<PsiElement> findIdDeclarations(@NotNull String id) {
List<PsiElement> declarations = new ArrayList<PsiElement>();
collectIdDeclarations(id, declarations);
public List<PsiElement> findIdDeclarations(@NotNull final String id) {
final List<PsiElement> declarations = new ArrayList<PsiElement>();
final Collection<VirtualFile> files =
FileBasedIndex.getInstance().getContainingFiles(AndroidIdIndex.INDEX_ID, id, GlobalSearchScope.allScope(myModule.getProject()));
final Set<VirtualFile> fileSet = new HashSet<VirtualFile>(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<VirtualFile> getResourceSubdirsToSearchIds() {
private List<VirtualFile> getResourceSubdirsToSearchIds() {
final List<VirtualFile> resSubdirs = new ArrayList<VirtualFile>();
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<PsiElement> targets) {
final Collection<VirtualFile> files =
FileBasedIndex.getInstance().getContainingFiles(AndroidIdIndex.INDEX_ID, id, GlobalSearchScope.allScope(myModule.getProject()));
final Set<VirtualFile> fileSet = new HashSet<VirtualFile>(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);
}
}
}
});
}
}
}
}
}
}
@@ -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();
}
@@ -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<String> REFERABLE_RESOURCE_TYPES = new HashSet<String>();
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<PsiField> result = findResourceFieldsByName(facet, resClassName, resourceName, onlyInOwnPackages);
return result.toArray(new PsiField[result.size()]);
}
public static List<PsiField> findResourceFieldsByName(AndroidFacet facet,
String innerClassName,
String fieldName,
boolean onlyInOwnPackages) {
List<PsiJavaFile> rClassFiles = findRClassFiles(facet, onlyInOwnPackages);
List<PsiField> result = new ArrayList<PsiField>();
final List<PsiJavaFile> rClassFiles = findRJavaFiles(facet, onlyInOwnPackages);
final List<PsiField> result = new ArrayList<PsiField>();
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<PsiJavaFile> findRClassFiles(@NotNull AndroidFacet facet, boolean onlyInOwnPackages) {
Module module = facet.getModule();
private static List<PsiJavaFile> 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<PsiDirectory> dirs = new HashSet<PsiDirectory>();
collectDirsForPackage(module, project, null, dirs, new HashSet<Module>(), onlyInOwnPackages);
List<PsiJavaFile> rJavaFiles = new ArrayList<PsiJavaFile>();
final List<PsiJavaFile> rJavaFiles = new ArrayList<PsiJavaFile>();
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<PsiDirectory> dirs,
Set<Module> 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<VirtualFile>() {
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<VirtualFile>() {
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<PsiElement> findResourcesByField(@NotNull PsiField field) {
LocalResourceManager manager = LocalResourceManager.getInstance(field);
if (manager != null) {
return findResourcesByField(manager, field);
}
return Collections.emptyList();
}
@NotNull
public static List<PsiElement> 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<PsiElement> findResourcesByFieldName(@NotNull LocalResourceManager manager,
@NotNull String resClassName,
@NotNull String fieldName) {
List<PsiElement> targets = new ArrayList<PsiElement>();
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.<PsiElement>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<PsiElement> 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<VirtualFile> getResourceSubdirs(@Nullable String resourceType, @NotNull VirtualFile[] resourceDirs) {
List<VirtualFile> dirs = new ArrayList<VirtualFile>();
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<VirtualFile> dirs = new ArrayList<VirtualFile>();
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<ResourceElement> getValueResourcesFromElement(@NotNull String resourceType, @NotNull Resources resources) {
final List<ResourceElement> result = new ArrayList<ResourceElement>();
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;
}
}
@@ -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;
}
}
@@ -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<String> getAllResources() {
List<String> list = new ArrayList<String>();
for (String type : ResourceManager.REFERABLE_RESOURCE_TYPES) {
for (String type : AndroidResourceUtil.REFERABLE_RESOURCE_TYPES) {
list.add('@' + type + '/');
}
return list;