blob: b9cb283a1ac5cc65d424a192858d94ca7ced8b12 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.devkit.dom;
import com.intellij.ide.highlighter.XmlFileType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.paths.PathReference;
import com.intellij.openapi.paths.PathReferenceManager;
import com.intellij.openapi.paths.PathReferenceProvider;
import com.intellij.openapi.paths.StaticPathReferenceProvider;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.psi.xml.XmlElement;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomUtil;
import com.intellij.util.xml.GenericAttributeValue;
import com.intellij.util.xml.converters.PathReferenceConverter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.util.DescriptorUtil;
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
import java.util.*;
public class DependencyConfigFileConverter extends PathReferenceConverter {
private static final PathReferenceProvider ourProvider = new StaticPathReferenceProvider(null) {
@Override
public boolean createReferences(@NotNull final PsiElement psiElement,
int offset,
String text,
@NotNull List<PsiReference> references,
boolean soft) {
FileReferenceSet set = new FileReferenceSet(text, psiElement, offset, null,
true, true,
new FileType[]{XmlFileType.INSTANCE}) {
private final Condition<PsiFileSystemItem> PLUGIN_XML_CONDITION = new Condition<PsiFileSystemItem>() {
@Override
public boolean value(PsiFileSystemItem item) {
return !item.isDirectory() &&
!item.equals(getContainingFile()) &&
(item instanceof XmlFile && DescriptorUtil.isPluginXml((PsiFile)item)) &&
!isAlreadyUsed((XmlFile)item);
}
};
private boolean isAlreadyUsed(final XmlFile xmlFile) {
final PsiFile file = getContainingFile();
if (!(file instanceof XmlFile)) return false;
final DomFileElement<IdeaPlugin> ideaPlugin = DescriptorUtil.getIdeaPlugin((XmlFile)file);
if (ideaPlugin == null) return false;
return !ContainerUtil.process(ideaPlugin.getRootElement().getDependencies(), new Processor<Dependency>() {
@Override
public boolean process(Dependency dependency) {
final GenericAttributeValue<PathReference> configFileAttribute = dependency.getConfigFile();
if (!DomUtil.hasXml(configFileAttribute)) return true;
final PathReference pathReference = configFileAttribute.getValue();
if (pathReference == null) return true;
return !xmlFile.equals(pathReference.resolve());
}
});
}
@NotNull
@Override
public Collection<PsiFileSystemItem> computeDefaultContexts() {
final PsiFile containingFile = getContainingFile();
if (containingFile == null) {
return Collections.emptyList();
}
final Module module = ModuleUtilCore.findModuleForPsiElement(getElement());
if (module == null) {
return Collections.emptyList();
}
final Set<VirtualFile> roots = new HashSet<VirtualFile>();
final VirtualFile parent = containingFile.getVirtualFile().getParent();
roots.add(parent);
for (VirtualFile sourceRoot : ModuleRootManager.getInstance(module).getSourceRoots(JavaModuleSourceRootTypes.PRODUCTION)) {
roots.add(sourceRoot.findChild("META-INF"));
}
return toFileSystemItems(roots);
}
@Override
protected boolean isSoft() {
return true;
}
@Override
protected Condition<PsiFileSystemItem> getReferenceCompletionFilter() {
return PLUGIN_XML_CONDITION;
}
};
Collections.addAll(references, set.getAllReferences());
return true;
}
};
@Override
public PathReference fromString(@Nullable String s, ConvertContext context) {
final XmlElement element = context.getXmlElement();
final Module module = context.getModule();
if (s == null || element == null || module == null) {
return null;
}
return PathReferenceManager.getInstance().getCustomPathReference(s, module, element, ourProvider);
}
@NotNull
@Override
public PsiReference[] createReferences(@NotNull PsiElement psiElement, boolean soft) {
return PathReferenceManager.getInstance().createCustomReferences(psiElement,
soft,
ourProvider);
}
}