update copyright
[fedora-idea.git] / xml / dom-openapi / src / com / intellij / util / xml / highlighting / DomElementsInspection.java
blobd12b957460b1c6373d3e7022ffc2e5fa80839b57
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.codeHighlighting.HighlightDisplayLevel;
20 import com.intellij.codeInspection.InspectionManager;
21 import com.intellij.codeInspection.ProblemDescriptor;
22 import com.intellij.codeInspection.XmlSuppressableInspectionTool;
23 import com.intellij.openapi.application.ApplicationManager;
24 import com.intellij.openapi.diagnostic.Logger;
25 import com.intellij.psi.PsiFile;
26 import com.intellij.psi.xml.XmlElement;
27 import com.intellij.psi.xml.XmlFile;
28 import com.intellij.psi.xml.XmlTag;
29 import com.intellij.util.Consumer;
30 import com.intellij.util.Function;
31 import com.intellij.util.containers.ContainerUtil;
32 import com.intellij.util.xml.*;
33 import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
34 import gnu.trove.THashSet;
35 import org.jetbrains.annotations.NotNull;
36 import org.jetbrains.annotations.Nullable;
38 import java.util.Arrays;
39 import java.util.Collection;
40 import java.util.List;
41 import java.util.Set;
43 /**
44 * @author Dmitry Avdeev
45 * @see com.intellij.util.xml.highlighting.BasicDomElementsInspection
47 public abstract class DomElementsInspection<T extends DomElement> extends XmlSuppressableInspectionTool {
48 private static final Logger LOG = Logger.getInstance("#com.intellij.util.xml.highlighting.DomElementsInspection");
50 private final Set<Class<? extends T>> myDomClasses;
52 public DomElementsInspection(Class<? extends T> domClass, @NotNull Class<? extends T>... additonalClasses) {
53 myDomClasses = new THashSet<Class<? extends T>>(Arrays.asList(additonalClasses));
54 myDomClasses.add(domClass);
57 /**
58 * This method is called internally in {@link com.intellij.util.xml.highlighting.DomElementAnnotationsManager#checkFileElement(com.intellij.util.xml.DomFileElement, DomElementsInspection)},
59 * it should add some problems to the annotation holder. The default implementation performs recursive tree traversal, and calls
60 * {@link #checkDomElement(com.intellij.util.xml.DomElement, DomElementAnnotationHolder, DomHighlightingHelper)} for each element.
61 * @param domFileElement file element to check
62 * @param holder the place to store problems
64 public void checkFileElement(DomFileElement<T> domFileElement, final DomElementAnnotationHolder holder) {
65 final DomHighlightingHelper helper =
66 DomElementAnnotationsManager.getInstance(domFileElement.getManager().getProject()).getHighlightingHelper();
67 final Consumer<DomElement> consumer = new Consumer<DomElement>() {
68 public void consume(final DomElement element) {
69 checkChildren(element, this);
70 checkDomElement(element, holder, helper);
73 consumer.consume(domFileElement.getRootElement());
76 @SuppressWarnings({"MethodMayBeStatic"})
77 protected void checkChildren(final DomElement element, Consumer<DomElement> visitor) {
78 final XmlElement xmlElement = element.getXmlElement();
79 if (xmlElement instanceof XmlTag) {
80 for (final DomElement child : DomUtil.getDefinedChildren(element, true, true)) {
81 final XmlElement element1 = child.getXmlElement();
82 if (element1 == null) {
83 LOG.assertTrue(false, "child=" + child + "; parent=" + element);
85 if (element1.isPhysical()) {
86 visitor.consume(child);
90 for (final AbstractDomChildrenDescription description : element.getGenericInfo().getChildrenDescriptions()) {
91 if (description.getAnnotation(Required.class) != null) {
92 for (final DomElement child : description.getValues(element)) {
93 if (!DomUtil.hasXml(child)) {
94 visitor.consume(child);
103 * @return the classes passed earlier to the constructor
105 public final Set<Class<? extends T>> getDomClasses() {
106 return myDomClasses;
110 * Not intended to be overriden or called by implementors.
111 * Override {@link #checkFileElement(com.intellij.util.xml.DomFileElement, DomElementAnnotationHolder)} (which is preferred) or
112 * {@link #checkDomElement(com.intellij.util.xml.DomElement, DomElementAnnotationHolder, DomHighlightingHelper)} instead.
114 @Nullable
115 public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
116 if (file instanceof XmlFile && (file.isPhysical() || ApplicationManager.getApplication().isUnitTestMode())) {
117 for (Class<? extends T> domClass: myDomClasses) {
118 final DomFileElement<? extends T> fileElement = DomManager.getDomManager(file.getProject()).getFileElement((XmlFile)file, domClass);
119 if (fileElement != null) {
120 return checkDomFile((DomFileElement<T>)fileElement, manager, isOnTheFly);
124 return null;
127 @NotNull
128 public HighlightDisplayLevel getDefaultLevel() {
129 return HighlightDisplayLevel.ERROR;
132 public boolean isEnabledByDefault() {
133 return true;
137 * not intended to be overriden or called by implementors
139 @Nullable
140 protected ProblemDescriptor[] checkDomFile(@NotNull final DomFileElement<T> domFileElement,
141 @NotNull final InspectionManager manager,
142 final boolean isOnTheFly) {
143 final DomElementAnnotationsManager annotationsManager = DomElementAnnotationsManager.getInstance(manager.getProject());
145 final List<DomElementProblemDescriptor> list = annotationsManager.checkFileElement(domFileElement, this);
146 List<ProblemDescriptor> problems =
147 ContainerUtil.concat(list, new Function<DomElementProblemDescriptor, Collection<? extends ProblemDescriptor>>() {
148 public Collection<ProblemDescriptor> fun(final DomElementProblemDescriptor s) {
149 return annotationsManager.createProblemDescriptors(manager, s);
152 return problems.toArray(new ProblemDescriptor[problems.size()]);
156 * Check particular DOM element for problems. The inspection implementor should focus on this method.
157 * The default implementation throws {@link UnsupportedOperationException}.
158 * See {@link com.intellij.util.xml.highlighting.BasicDomElementsInspection}
159 * @param element element to check
160 * @param holder a place to add problems to
161 * @param helper helper object
163 protected void checkDomElement(DomElement element, DomElementAnnotationHolder holder, DomHighlightingHelper helper) {
164 throw new UnsupportedOperationException("checkDomElement() is not implemented in " + getClass().getName());