| /* |
| * Copyright 2000-2009 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 com.intellij.lang.properties.references; |
| |
| import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider; |
| import com.intellij.lang.properties.IProperty; |
| import com.intellij.lang.properties.PropertiesBundle; |
| import com.intellij.lang.properties.PropertiesImplUtil; |
| import com.intellij.lang.properties.psi.PropertiesFile; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.TextRange; |
| import com.intellij.pom.references.PomService; |
| import com.intellij.psi.*; |
| import com.intellij.util.ArrayUtil; |
| import com.intellij.util.IncorrectOperationException; |
| import com.intellij.util.containers.ContainerUtil; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.util.ArrayList; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * @author nik |
| */ |
| public abstract class PropertyReferenceBase implements PsiPolyVariantReference, EmptyResolveMessageProvider { |
| private static final Logger LOG = Logger.getInstance("#com.intellij.lang.properties.references.PropertyReferenceBase"); |
| protected final String myKey; |
| protected final PsiElement myElement; |
| protected boolean mySoft; |
| private final TextRange myTextRange; |
| |
| public PropertyReferenceBase(@NotNull String key, final boolean soft, @NotNull PsiElement element) { |
| this(key, soft, element, ElementManipulators.getValueTextRange(element)); |
| } |
| |
| public PropertyReferenceBase(@NotNull String key, final boolean soft, @NotNull PsiElement element, TextRange range) { |
| myKey = key; |
| mySoft = soft; |
| myElement = element; |
| myTextRange = range; |
| } |
| |
| public PsiElement resolve() { |
| ResolveResult[] resolveResults = multiResolve(false); |
| return resolveResults.length == 1 ? resolveResults[0].getElement() : null; |
| } |
| |
| @NotNull |
| protected String getKeyText() { |
| return myKey; |
| } |
| |
| public boolean equals(final Object o) { |
| if (this == o) return true; |
| if (o == null || getClass() != o.getClass()) return false; |
| PropertyReferenceBase other = (PropertyReferenceBase)o; |
| |
| return getElement() == other.getElement() && getKeyText().equals(other.getKeyText()); |
| } |
| |
| public int hashCode() { |
| return getKeyText().hashCode(); |
| } |
| |
| @NotNull |
| public PsiElement getElement() { |
| return myElement; |
| } |
| |
| public TextRange getRangeInElement() { |
| return myTextRange; |
| } |
| |
| @NotNull |
| public String getCanonicalText() { |
| return myKey; |
| } |
| |
| public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { |
| /*PsiElementFactory factory = JavaPsiFacade.getInstance(myElement.getProject()).getElementFactory(); |
| |
| if (myElement instanceof PsiLiteralExpression) { |
| PsiExpression newExpression = factory.createExpressionFromText("\"" + newElementName + "\"", myElement); |
| return myElement.replace(newExpression); |
| } |
| else {*/ |
| ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(myElement); |
| if (manipulator == null) { |
| LOG.error("Cannot find manipulator for " + myElement + " of class " + myElement.getClass()); |
| } |
| return manipulator.handleContentChange(myElement, getRangeInElement(), newElementName); |
| /*}*/ |
| } |
| |
| public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { |
| throw new IncorrectOperationException("not implemented"); |
| } |
| |
| public boolean isReferenceTo(PsiElement element) { |
| for (ResolveResult result : multiResolve(false)) { |
| final PsiElement el = result.getElement(); |
| if (el != null && el.isEquivalentTo(element)) return true; |
| } |
| return false; |
| } |
| |
| protected void addKey(Object property, Set<Object> variants) { |
| variants.add(property); |
| } |
| |
| protected void setSoft(final boolean soft) { |
| mySoft = soft; |
| } |
| |
| public boolean isSoft() { |
| return mySoft; |
| } |
| |
| @NotNull |
| public String getUnresolvedMessagePattern() { |
| return PropertiesBundle.message("unresolved.property.key"); |
| } |
| |
| @NotNull |
| public ResolveResult[] multiResolve(final boolean incompleteCode) { |
| final String key = getKeyText(); |
| |
| List<IProperty> properties; |
| final List<PropertiesFile> propertiesFiles = getPropertiesFiles(); |
| if (propertiesFiles == null) { |
| properties = PropertiesImplUtil.findPropertiesByKey(getElement().getProject(), key); |
| } |
| else { |
| properties = new ArrayList<IProperty>(); |
| for (PropertiesFile propertiesFile : propertiesFiles) { |
| properties.addAll(propertiesFile.findPropertiesByKey(key)); |
| } |
| } |
| // put default properties file first |
| ContainerUtil.quickSort(properties, new Comparator<IProperty>() { |
| public int compare(final IProperty o1, final IProperty o2) { |
| String name1 = o1.getPropertiesFile().getName(); |
| String name2 = o2.getPropertiesFile().getName(); |
| return Comparing.compare(name1, name2); |
| } |
| }); |
| return getResolveResults(properties); |
| } |
| |
| protected static ResolveResult[] getResolveResults(List<IProperty> properties) { |
| if (properties.isEmpty()) return ResolveResult.EMPTY_ARRAY; |
| |
| final ResolveResult[] results = new ResolveResult[properties.size()]; |
| for (int i = 0; i < properties.size(); i++) { |
| IProperty property = properties.get(i); |
| results[i] = new PsiElementResolveResult(property instanceof PsiElement ? (PsiElement)property : PomService.convertToPsi( |
| (PsiTarget)property)); |
| } |
| return results; |
| } |
| |
| @Nullable |
| protected abstract List<PropertiesFile> getPropertiesFiles(); |
| |
| @NotNull |
| public Object[] getVariants() { |
| return ArrayUtil.EMPTY_OBJECT_ARRAY; |
| } |
| } |