update copyright
[fedora-idea.git] / xml / dom-impl / src / com / intellij / util / xml / highlighting / DomElementProblemDescriptorImpl.java
blob0d4c0385cc8873209a16291e0d343e97a54e703a
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
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.
17 package com.intellij.util.xml.highlighting;
19 import com.intellij.codeInspection.LocalQuickFix;
20 import com.intellij.codeInspection.ProblemHighlightType;
21 import com.intellij.lang.annotation.Annotation;
22 import com.intellij.lang.annotation.HighlightSeverity;
23 import com.intellij.openapi.application.ApplicationManager;
24 import com.intellij.openapi.diagnostic.Logger;
25 import com.intellij.openapi.util.Pair;
26 import com.intellij.openapi.util.TextRange;
27 import com.intellij.openapi.util.text.StringUtil;
28 import com.intellij.psi.PsiElement;
29 import com.intellij.psi.xml.XmlAttributeValue;
30 import com.intellij.psi.xml.XmlElement;
31 import com.intellij.psi.xml.XmlTag;
32 import com.intellij.psi.xml.XmlText;
33 import com.intellij.util.containers.ContainerUtil;
34 import com.intellij.util.xml.DomElement;
35 import com.intellij.util.xml.GenericAttributeValue;
36 import com.intellij.util.xml.GenericValue;
37 import com.intellij.util.xml.DomFileElement;
38 import com.intellij.xml.util.XmlTagUtil;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
42 import java.util.List;
44 public class DomElementProblemDescriptorImpl implements DomElementProblemDescriptor {
45 private static final Logger LOG = Logger.getInstance("#com.intellij.util.xml.highlighting.DomElementProblemDescriptorImpl");
46 private final DomElement myDomElement;
47 private final HighlightSeverity mySeverity;
48 private final String myMessage;
49 private final LocalQuickFix[] myFixes;
50 private List<Annotation> myAnnotations;
51 private Pair<TextRange, PsiElement> myPair;
52 public static final Pair<TextRange,PsiElement> NO_PROBLEM = new Pair<TextRange, PsiElement>(null, null);
53 private final ProblemHighlightType myHighlightType;
55 public DomElementProblemDescriptorImpl(@NotNull final DomElement domElement, final String message, final HighlightSeverity type) {
56 this(domElement, message, type, LocalQuickFix.EMPTY_ARRAY);
59 public DomElementProblemDescriptorImpl(@NotNull final DomElement domElement,
60 final String message,
61 final HighlightSeverity type,
62 @Nullable final TextRange textRange) {
63 this(domElement, message, type, textRange, null, LocalQuickFix.EMPTY_ARRAY);
66 public DomElementProblemDescriptorImpl(@NotNull final DomElement domElement,
67 final String message,
68 final HighlightSeverity type,
69 final LocalQuickFix... fixes) {
70 this(domElement, message, type, null, null, fixes);
73 public DomElementProblemDescriptorImpl(@NotNull final DomElement domElement,
74 final String message,
75 final HighlightSeverity type,
76 @Nullable final TextRange textRange,
77 ProblemHighlightType highlightType,
78 final LocalQuickFix... fixes) {
79 myDomElement = domElement;
80 final XmlElement element = domElement.getXmlElement();
81 if (element != null && !ApplicationManager.getApplication().isUnitTestMode()) {
82 //LOG.assertTrue(element.isPhysical(), "Problems may not be created for non-physical DOM elements");
84 mySeverity = type;
85 myMessage = message;
86 myFixes = fixes;
88 if (textRange != null) {
89 final PsiElement psiElement = getPsiElement();
90 LOG.assertTrue(psiElement != null, "Problems with explicit text range can't be created for DOM elements without underlying XML element");
91 myPair = new Pair<TextRange, PsiElement>(textRange, psiElement);
93 myHighlightType = highlightType;
96 @NotNull
97 public DomElement getDomElement() {
98 return myDomElement;
101 @NotNull
102 public HighlightSeverity getHighlightSeverity() {
103 return mySeverity;
106 @NotNull
107 public String getDescriptionTemplate() {
108 return myMessage == null ? "" : myMessage;
111 @NotNull
112 public LocalQuickFix[] getFixes() {
113 return myFixes;
116 @NotNull
117 public final List<Annotation> getAnnotations() {
118 if (myAnnotations == null) {
119 myAnnotations = ContainerUtil.createMaybeSingletonList(DomElementsHighlightingUtil.createAnnotation(this));
121 return myAnnotations;
124 public void highlightWholeElement() {
125 final PsiElement psiElement = getPsiElement();
126 if (psiElement instanceof XmlAttributeValue) {
127 final PsiElement attr = psiElement.getParent();
128 myPair = Pair.create(new TextRange(0, attr.getTextLength()), attr);
130 else if (psiElement != null) {
131 final XmlTag tag = (XmlTag)(psiElement instanceof XmlTag ? psiElement : psiElement.getParent());
132 myPair = new Pair<TextRange, PsiElement>(new TextRange(0, tag.getTextLength()), tag);
136 public Pair<TextRange,PsiElement> getProblemRange() {
137 if (myPair == null) {
138 myPair = computeProblemRange();
140 return myPair;
143 @NotNull
144 protected Pair<TextRange,PsiElement> computeProblemRange() {
145 final PsiElement element = getPsiElement();
147 if (element != null) {
148 if (element instanceof XmlTag) {
149 return createTagNameRange((XmlTag)element);
152 int length = element.getTextRange().getLength();
153 TextRange range = TextRange.from(0, length);
154 if (element instanceof XmlAttributeValue) {
155 final String value = ((XmlAttributeValue)element).getValue();
156 if (StringUtil.isNotEmpty(value)) {
157 range = TextRange.from(element.getText().indexOf(value), value.length());
160 return Pair.create(range, element);
163 final XmlTag tag = getParentXmlTag();
164 if (tag != null) {
165 return createTagNameRange(tag);
167 return NO_PROBLEM;
170 private static Pair<TextRange, PsiElement> createTagNameRange(final XmlTag tag) {
171 final PsiElement startToken = XmlTagUtil.getStartTagNameElement(tag);
172 assert startToken != null;
173 return Pair.create(startToken.getTextRange().shiftRight(-tag.getTextRange().getStartOffset()), (PsiElement)tag);
176 public String toString() {
177 return myDomElement + "; " + myMessage;
180 public boolean equals(final Object o) {
181 if (this == o) return true;
182 if (o == null || getClass() != o.getClass()) return false;
184 final DomElementProblemDescriptorImpl that = (DomElementProblemDescriptorImpl)o;
186 if (myDomElement != null ? !myDomElement.equals(that.myDomElement) : that.myDomElement != null) return false;
187 if (!myMessage.equals(that.myMessage)) return false;
188 if (!mySeverity.equals(that.mySeverity)) return false;
190 return true;
193 public int hashCode() {
194 int result;
195 result = (myDomElement != null ? myDomElement.hashCode() : 0);
196 result = 31 * result + mySeverity.hashCode();
197 result = 31 * result + myMessage.hashCode();
198 return result;
201 @Nullable
202 private PsiElement getPsiElement() {
203 if (myDomElement instanceof DomFileElement) {
204 return ((DomFileElement)myDomElement).getFile();
207 if (myDomElement instanceof GenericAttributeValue) {
208 final GenericAttributeValue attributeValue = (GenericAttributeValue)myDomElement;
209 final XmlAttributeValue value = attributeValue.getXmlAttributeValue();
210 return value != null && StringUtil.isNotEmpty(value.getText()) ? value : attributeValue.getXmlElement();
212 final XmlTag tag = myDomElement.getXmlTag();
213 if (myDomElement instanceof GenericValue && tag != null) {
214 final XmlText[] textElements = tag.getValue().getTextElements();
215 if (textElements.length > 0) {
216 return textElements[0];
220 return tag;
223 @Nullable
224 private XmlTag getParentXmlTag() {
225 DomElement parent = myDomElement.getParent();
226 while (parent != null) {
227 if (parent.getXmlTag() != null) return parent.getXmlTag();
228 parent = parent.getParent();
230 return null;
233 @Nullable
234 public ProblemHighlightType getHighlightType() {
235 return myHighlightType;