Inspections - pass onTheFly into ProblemDescriptors & use it to create LAZY refs...
[fedora-idea.git] / plugins / xpath / xpath-lang / src / org / intellij / lang / xpath / validation / inspections / CheckNodeTest.java
blob4b2d51168a0c1e222c8a1d20513a2f52cde0162f
1 /*
2 * Copyright 2005 Sascha Weinreuter
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.intellij.lang.xpath.validation.inspections;
18 import com.intellij.codeInspection.InspectionManager;
19 import com.intellij.codeInspection.LocalQuickFix;
20 import com.intellij.codeInspection.ProblemHighlightType;
21 import com.intellij.psi.xml.XmlElement;
22 import org.intellij.lang.xpath.context.ContextProvider;
23 import org.intellij.lang.xpath.context.NamespaceContext;
24 import org.intellij.lang.xpath.psi.PrefixedName;
25 import org.intellij.lang.xpath.psi.XPathNodeTest;
26 import org.jetbrains.annotations.NonNls;
27 import org.jetbrains.annotations.NotNull;
28 import org.jetbrains.annotations.Nullable;
30 import javax.xml.namespace.QName;
31 import java.text.MessageFormat;
32 import java.util.Set;
34 public class CheckNodeTest extends XPathInspection {
35 @NonNls
36 private static final String SHORT_NAME = "CheckNodeTest";
38 protected Visitor createVisitor(InspectionManager manager, boolean isOnTheFly) {
39 return new MyVisitor(manager, isOnTheFly);
42 @NotNull
43 public String getDisplayName() {
44 return "Check Node Test";
47 @NotNull
48 @NonNls
49 public String getShortName() {
50 return SHORT_NAME;
53 public boolean isEnabledByDefault() {
54 return true;
57 final static class MyVisitor extends Visitor {
58 MyVisitor(InspectionManager manager, boolean isOnTheFly) {
59 super(manager, isOnTheFly);
62 protected void checkNodeTest(XPathNodeTest nodeTest) {
63 final ContextProvider contextProvider = ContextProvider.getContextProvider(nodeTest.getContainingFile());
64 final XmlElement contextNode = contextProvider.getContextElement();
65 final NamespaceContext namespaceContext = contextProvider.getNamespaceContext();
66 if (namespaceContext == null) return;
68 if (nodeTest.isNameTest() && contextNode != null) {
69 final PrefixedName prefixedName = nodeTest.getQName();
70 assert prefixedName != null;
71 if (!"*".equals(prefixedName.getLocalName())) {
72 boolean found;
74 if (nodeTest.getPrincipalType() == XPathNodeTest.PrincipalType.ELEMENT) {
75 final Set<QName> elementNames = contextProvider.getElements(true);
76 if (elementNames != null) {
77 found = false;
78 for (javax.xml.namespace.QName pair : elementNames) {
79 if (matches(nodeTest.getQName(), pair, namespaceContext, contextNode)) {
80 found = true;
81 break;
84 if (!found) {
85 registerProblem(contextProvider, prefixedName, nodeTest, "element");
88 } else if (nodeTest.getPrincipalType() == XPathNodeTest.PrincipalType.ATTRIBUTE) {
89 final Set<javax.xml.namespace.QName> attributeNames = contextProvider.getAttributes(true);
90 if (attributeNames != null) {
91 found = false;
92 for (javax.xml.namespace.QName pair : attributeNames) {
93 if (matches(nodeTest.getQName(), pair, namespaceContext, contextNode)) {
94 found = true;
95 break;
98 if (!found) {
99 registerProblem(contextProvider, prefixedName, nodeTest, "attribute");
107 private void registerProblem(ContextProvider contextProvider, PrefixedName prefixedName, XPathNodeTest nodeTest, String type) {
108 final QName qName = contextProvider.getQName(prefixedName, nodeTest);
109 final String name;
110 if (qName != null) {
111 final String pattern;
112 if (!"".equals(qName.getNamespaceURI())) {
113 pattern = "''<b>{0}</b>'' (<i>{1}</i>)";
114 } else {
115 pattern = "''<b>{0}</b>''";
117 name = MessageFormat.format(pattern, qName.getLocalPart(), qName.getNamespaceURI());
118 } else {
119 name = MessageFormat.format("''<b>{0}</b>''", prefixedName.getLocalName());
122 final LocalQuickFix[] fixes = contextProvider.getQuickFixFactory().createUnknownNodeTestFixes(nodeTest);
123 addProblem(myManager.createProblemDescriptor(nodeTest, "<html>Unknown " + type + " name " + name + "</html>",
124 fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, myOnTheFly));
127 private static boolean matches(@Nullable PrefixedName prefixedName, QName element, NamespaceContext namespaceContext, XmlElement context) {
128 if (prefixedName == null) return false;
129 boolean b = prefixedName.getLocalName().equals(element.getLocalPart()) || "*".equals(element.getLocalPart());
130 if (prefixedName.getPrefix() != null) {
131 b = b && element.getNamespaceURI().equals(namespaceContext.getNamespaceURI(prefixedName.getPrefix(), context));
132 } else {
133 b = b && element.getNamespaceURI().equals("");
135 return b;