blob: 796f1e2af7f6fd374ac61680b39736e5fb40de3f [file] [log] [blame]
/*
* Copyright 2007 Sascha Weinreuter
*
* 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.intellij.plugins.relaxNG.references;
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.LocalQuickFixProvider;
import com.intellij.codeInspection.XmlQuickFixFactory;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceProvider;
import com.intellij.psi.XmlElementFactory;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.BasicAttributeValueReference;
import com.intellij.psi.impl.source.xml.SchemaPrefix;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/*
* Created by IntelliJ IDEA.
* User: sweinreuter
* Date: 24.07.2007
*/
public class PrefixReferenceProvider extends PsiReferenceProvider {
private static final Logger LOG = Logger.getInstance("#org.intellij.plugins.relaxNG.references.PrefixReferenceProvider");
@Override
@NotNull
public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
final XmlAttributeValue value = (XmlAttributeValue)element;
final String s = value.getValue();
final int i = s.indexOf(':');
if (i <= 0 || s.startsWith("xml:")) {
return PsiReference.EMPTY_ARRAY;
}
return new PsiReference[]{
new PrefixReference(value, i)
};
}
private static class PrefixReference extends BasicAttributeValueReference implements EmptyResolveMessageProvider, LocalQuickFixProvider {
public PrefixReference(XmlAttributeValue value, int length) {
super(value, TextRange.from(1, length));
}
@Override
@Nullable
public PsiElement resolve() {
final String prefix = getCanonicalText();
XmlTag tag = PsiTreeUtil.getParentOfType(getElement(), XmlTag.class);
while (tag != null) {
if (tag.getLocalNamespaceDeclarations().containsKey(prefix)) {
final XmlAttribute attribute = tag.getAttribute("xmlns:" + prefix, "");
final TextRange textRange = TextRange.from("xmlns:".length(), prefix.length());
return new SchemaPrefix(attribute, textRange, prefix);
}
tag = tag.getParentTag();
}
return null;
}
@Override
public boolean isReferenceTo(PsiElement element) {
if (element instanceof SchemaPrefix && element.getContainingFile() == myElement.getContainingFile()) {
final PsiElement e = resolve();
if (e instanceof SchemaPrefix) {
final String s = ((SchemaPrefix)e).getName();
return s != null && s.equals(((SchemaPrefix)element).getName());
}
}
return super.isReferenceTo(element);
}
@Nullable
@Override
public LocalQuickFix[] getQuickFixes() {
final PsiElement element = getElement();
final XmlElementFactory factory = XmlElementFactory.getInstance(element.getProject());
final String value = ((XmlAttributeValue)element).getValue();
final String[] name = value.split(":");
final XmlTag tag = factory.createTagFromText("<" + (name.length > 1 ? name[1] : value) + " />", XMLLanguage.INSTANCE);
return new LocalQuickFix[] { XmlQuickFixFactory.getInstance().createNSDeclarationIntentionFix(tag, getCanonicalText(), null) };
}
@Override
@NotNull
public Object[] getVariants() {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
@Override
public boolean isSoft() {
return false;
}
@Override
@NotNull
public String getUnresolvedMessagePattern() {
return "Undefined namespace prefix ''{0}''";
}
}
}