blob: a7a5ee0b44ebccfe711c4ff001348b404d792eae [file] [log] [blame]
package org.jetbrains.android.dom.converters;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceBase;
import com.intellij.psi.impl.source.resolve.ResolveCache;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.HashSet;
import com.intellij.util.xml.*;
import org.jetbrains.android.dom.manifest.Manifest;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
/**
* @author Eugene.Kudelevsky
*/
public class InstrumentationTargetPackageConverter extends Converter<String> implements CustomReferenceConverter<String> {
@Nullable
@Override
public String fromString(@Nullable @NonNls String s, ConvertContext context) {
return s;
}
@Nullable
@Override
public String toString(@Nullable String s, ConvertContext context) {
return s;
}
@NotNull
@Override
public PsiReference[] createReferences(GenericDomValue<String> value, PsiElement element, ConvertContext context) {
final Module module = context.getModule();
return element != null && module != null
? new PsiReference[]{new MyReference(element, module)}
: PsiReference.EMPTY_ARRAY;
}
private static class MyReference extends PsiReferenceBase<PsiElement> {
private final Module myModule;
public MyReference(@NotNull PsiElement element, @NotNull Module module) {
super(element, true);
myModule = module;
}
@Nullable
@Override
public PsiElement resolve() {
return ResolveCache.getInstance(myElement.getProject())
.resolveWithCaching(this, new ResolveCache.Resolver() {
@Override
public PsiElement resolve(@NotNull PsiReference reference, boolean incompleteCode) {
return resolveInner();
}
}, false, false);
}
@Nullable
private PsiElement resolveInner() {
final String value = getValue();
if (value.length() == 0) {
return null;
}
final Ref<PsiElement> result = Ref.create();
processApkPackageAttrs(new Processor<GenericAttributeValue<String>>() {
@Override
public boolean process(GenericAttributeValue<String> domValue) {
if (value.equals(domValue.getValue())) {
final XmlAttributeValue xmlValue = domValue.getXmlAttributeValue();
if (xmlValue != null) {
result.set(xmlValue);
return false;
}
}
return true;
}
});
return result.get();
}
@NotNull
@Override
public Object[] getVariants() {
final Set<String> result = new HashSet<String>();
processApkPackageAttrs(new Processor<GenericAttributeValue<String>>() {
@Override
public boolean process(GenericAttributeValue<String> domValue) {
final String value = domValue.getValue();
if (value != null && value.length() > 0) {
result.add(value);
}
return true;
}
});
return ArrayUtil.toStringArray(result);
}
private void processApkPackageAttrs(@NotNull Processor<GenericAttributeValue<String>> processor) {
for (Module depModule : ModuleRootManager.getInstance(myModule).getDependencies()) {
final AndroidFacet depFacet = AndroidFacet.getInstance(depModule);
if (depFacet != null && !depFacet.isLibraryProject()) {
final Manifest manifest = depFacet.getManifest();
if (manifest != null) {
final GenericAttributeValue<String> packageAttr = manifest.getPackage();
if (packageAttr != null && !processor.process(packageAttr)) {
return;
}
}
}
}
}
}
}