blob: cc5619d8a50d9b917f1dbf3ae3f3f0acc1a16812 [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.maven.dom.references;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.util.Function;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomUtil;
import com.intellij.util.xml.GenericDomValue;
import com.intellij.util.xml.converters.PathReferenceConverter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.MavenPropertyResolver;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import java.util.Collection;
import java.util.Collections;
/**
* @author Sergey Evdokimov
*/
public class MavenPathReferenceConverter extends PathReferenceConverter {
private final Condition<PsiFileSystemItem> myCondition;
public MavenPathReferenceConverter() {
this(Conditions.<PsiFileSystemItem>alwaysTrue());
}
public MavenPathReferenceConverter(@NotNull Condition<PsiFileSystemItem> condition) {
myCondition = condition;
}
public static PsiReference[] createReferences(final DomElement genericDomValue,
PsiElement element,
@NotNull final Condition<PsiFileSystemItem> fileFilter) {
return createReferences(genericDomValue, element, fileFilter, false);
}
public static PsiReference[] createReferences(final DomElement genericDomValue,
PsiElement element,
@NotNull final Condition<PsiFileSystemItem> fileFilter, boolean isAbsolutePath) {
ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(element);
TextRange range = manipulator.getRangeInElement(element);
String text = range.substring(element.getText());
FileReferenceSet set = new FileReferenceSet(text, element, range.getStartOffset(), null, SystemInfo.isFileSystemCaseSensitive, false) {
private MavenDomProjectModel model;
@Override
protected Condition<PsiFileSystemItem> getReferenceCompletionFilter() {
return fileFilter;
}
@Override
protected boolean isSoft() {
return true;
}
@Override
public FileReference createFileReference(TextRange range, int index, String text) {
return new FileReference(this, range, index, text) {
@Override
protected void innerResolveInContext(@NotNull String text,
@NotNull PsiFileSystemItem context,
Collection<ResolveResult> result,
boolean caseSensitive) {
if (model == null) {
DomElement rootElement = DomUtil.getFileElement(genericDomValue).getRootElement();
if (rootElement instanceof MavenDomProjectModel) {
model = (MavenDomProjectModel)rootElement;
}
}
String resolvedText = model == null ? text : MavenPropertyResolver.resolve(text, model);
if (resolvedText.equals(text)) {
if (getIndex() == 0 && resolvedText.length() == 2 && resolvedText.charAt(1) == ':') {
// it's root on windows, e.g. "C:"
VirtualFile file = LocalFileSystem.getInstance().findFileByPath(resolvedText + '/');
if (file != null) {
PsiDirectory psiDirectory = context.getManager().findDirectory(file);
if (psiDirectory != null) {
result.add(new PsiElementResolveResult(psiDirectory));
}
}
}
else {
super.innerResolveInContext(resolvedText, context, result, caseSensitive);
}
}
else {
VirtualFile contextFile = context.getVirtualFile();
if (contextFile == null) return;
VirtualFile file = null;
if (getIndex() == 0) {
file = LocalFileSystem.getInstance().findFileByPath(resolvedText);
}
if (file == null) {
file = LocalFileSystem.getInstance().findFileByPath(contextFile.getPath() + '/' + resolvedText);
}
if (file != null) {
PsiFileSystemItem res = file.isDirectory() ? context.getManager().findDirectory(file) : context.getManager().findFile(file);
if (res != null) {
result.add(new PsiElementResolveResult(res));
}
}
}
}
};
}
};
if (isAbsolutePath) {
set.addCustomization(FileReferenceSet.DEFAULT_PATH_EVALUATOR_OPTION, new Function<PsiFile, Collection<PsiFileSystemItem>>() {
@Override
public Collection<PsiFileSystemItem> fun(PsiFile file) {
VirtualFile virtualFile = file.getVirtualFile();
if (virtualFile == null) {
return FileReferenceSet.ABSOLUTE_TOP_LEVEL.fun(file);
}
while (true) {
VirtualFile parent = virtualFile.getParent();
if (parent == null) break;
virtualFile = parent;
}
PsiDirectory root = file.getManager().findDirectory(virtualFile);
if (root == null) {
return FileReferenceSet.ABSOLUTE_TOP_LEVEL.fun(file);
}
return Collections.<PsiFileSystemItem>singletonList(root);
}
});
}
return set.getAllReferences();
}
@NotNull
@Override
public PsiReference[] createReferences(final GenericDomValue genericDomValue, PsiElement element, ConvertContext context) {
return createReferences(genericDomValue, element, myCondition);
}
@NotNull
@Override
public PsiReference[] createReferences(@NotNull PsiElement psiElement, boolean soft) {
throw new UnsupportedOperationException();
}
}