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.
16 package com
.intellij
.xml
;
18 import com
.intellij
.codeInsight
.daemon
.impl
.HighlightInfo
;
19 import com
.intellij
.codeInsight
.daemon
.impl
.HighlightInfoType
;
20 import com
.intellij
.codeInsight
.daemon
.impl
.quickfix
.QuickFixAction
;
21 import com
.intellij
.codeInsight
.intention
.IntentionAction
;
22 import com
.intellij
.lang
.ASTNode
;
23 import com
.intellij
.openapi
.editor
.Document
;
24 import com
.intellij
.openapi
.editor
.Editor
;
25 import com
.intellij
.openapi
.extensions
.ExtensionPointName
;
26 import com
.intellij
.openapi
.extensions
.Extensions
;
27 import com
.intellij
.openapi
.util
.Pair
;
28 import com
.intellij
.openapi
.util
.text
.StringUtil
;
29 import com
.intellij
.psi
.PsiElement
;
30 import com
.intellij
.psi
.PsiFile
;
31 import com
.intellij
.psi
.impl
.source
.xml
.TagNameReference
;
32 import com
.intellij
.psi
.xml
.XmlAttribute
;
33 import com
.intellij
.psi
.xml
.XmlDocument
;
34 import com
.intellij
.psi
.xml
.XmlFile
;
35 import com
.intellij
.psi
.xml
.XmlTag
;
36 import com
.intellij
.util
.IncorrectOperationException
;
37 import com
.intellij
.xml
.util
.XmlUtil
;
38 import org
.jetbrains
.annotations
.NonNls
;
39 import org
.jetbrains
.annotations
.NotNull
;
40 import org
.jetbrains
.annotations
.Nullable
;
42 import java
.util
.List
;
46 * @author Dmitry Avdeev
48 public abstract class XmlExtension
{
50 private static final ExtensionPointName
<XmlExtension
> EP_NAME
= new ExtensionPointName
<XmlExtension
>("com.intellij.xml.xmlExtension");
52 public static final XmlExtension DEFAULT_EXTENSION
= new DefaultXmlExtension();
54 public static XmlExtension
getExtension(PsiFile file
) {
55 for (XmlExtension extension
: Extensions
.getExtensions(EP_NAME
)) {
56 if (extension
.isAvailable(file
)) {
60 return DEFAULT_EXTENSION
;
64 public static XmlExtension
getExtensionByElement(PsiElement element
) {
65 final PsiFile psiFile
= element
.getContainingFile();
66 if (psiFile
!= null) {
67 return getExtension(psiFile
);
72 public abstract boolean isAvailable(PsiFile file
);
75 public abstract List
<Pair
<String
,String
>> getAvailableTagNames(@NotNull final XmlFile file
, @NotNull final XmlTag context
);
77 public abstract Set
<String
> getNamespacesByTagName(@NotNull final String tagName
, @NotNull final XmlFile context
);
80 public abstract Set
<String
> guessUnboundNamespaces(@NotNull PsiElement element
, final XmlFile file
);
82 public TagNameReference
createTagNameReference(final ASTNode nameElement
, final boolean startTagFlag
) {
83 return new TagNameReference(nameElement
, startTagFlag
);
87 public String
[][] getNamespacesFromDocument(final XmlDocument parent
, boolean declarationsExist
) {
88 return declarationsExist ?
null : XmlUtil
.getDefaultNamespaces(parent
);
91 public interface Runner
<P
, T
extends Throwable
> {
92 void run(P param
) throws T
;
95 public abstract void insertNamespaceDeclaration(@NotNull final XmlFile file
,
96 @NotNull final Editor editor
,
97 @NonNls @NotNull final Set
<String
> possibleNamespaces
,
98 @NonNls @Nullable final String nsPrefix
,
99 @Nullable Runner
<String
, IncorrectOperationException
> runAfter
) throws IncorrectOperationException
;
102 public String
getNamespacePrefix(PsiElement element
) {
103 final PsiElement tag
= element
instanceof XmlTag ? element
: element
.getParent();
104 if (tag
instanceof XmlTag
) {
105 return ((XmlTag
)tag
).getNamespacePrefix();
111 public boolean qualifyWithPrefix(final String namespacePrefix
, final PsiElement element
, final Document document
) throws
112 IncorrectOperationException
{
113 final PsiElement tag
= element
instanceof XmlTag ? element
: element
.getParent();
114 if (tag
instanceof XmlTag
) {
115 final String prefix
= ((XmlTag
)tag
).getNamespacePrefix();
116 if (!prefix
.equals(namespacePrefix
)) {
117 final String name
= namespacePrefix
+ ":" + ((XmlTag
)tag
).getLocalName();
118 ((XmlTag
)tag
).setName(name
);
125 public String
getNamespaceAlias(@NotNull final XmlFile file
) {
126 return XmlBundle
.message("namespace.alias");
129 public void createAddAttributeFix(@NotNull final XmlAttribute attribute
, final HighlightInfo highlightInfo
) {
130 final XmlTag tag
= attribute
.getParent();
131 String namespace
= attribute
.getNamespace();
133 if(StringUtil
.isEmptyOrSpaces(namespace
)) namespace
= tag
.getNamespace();
135 final XmlNSDescriptor nsDescriptor
= tag
.getNSDescriptor(namespace
, true);
136 if (nsDescriptor
instanceof XmlUndefinedElementFixProvider
) {
137 final IntentionAction
[] actions
= ((XmlUndefinedElementFixProvider
)nsDescriptor
).createFixes(attribute
);
138 for (IntentionAction action
: actions
) {
139 QuickFixAction
.registerQuickFixAction(highlightInfo
, action
);
144 public boolean canBeDuplicated(XmlAttribute attribute
) {
148 public boolean isRequiredAttributeImplicitlyPresent(XmlTag tag
, String attrName
) {
152 public HighlightInfoType
getHighlightInfoType(XmlFile file
) {
153 return HighlightInfoType
.ERROR
;
156 public abstract boolean isPrefixDeclared(final XmlTag context
, String namespacePrefix
);
158 public boolean shouldBeHighlightedAsTag(XmlTag tag
) {
163 public XmlElementDescriptor
getElementDescriptor(XmlTag tag
, XmlTag contextTag
, final XmlElementDescriptor parentDescriptor
) {
164 return parentDescriptor
.getElementDescriptor(tag
, contextTag
);
168 public XmlNSDescriptor
getNSDescriptor(final XmlTag element
, final String namespace
, final boolean strict
) {
169 return element
.getNSDescriptor(namespace
, strict
);
173 public XmlTag
getParentTagForNamespace(XmlTag tag
, XmlNSDescriptor namespace
) {
174 return tag
.getParentTag();
178 public XmlFile
getContainingFile(PsiElement element
) {
179 if (element
== null) {
182 final PsiFile psiFile
= element
.getContainingFile();
183 return psiFile
instanceof XmlFile ?
(XmlFile
)psiFile
: null;
186 public XmlNSDescriptor
getDescriptorFromDoctype(final XmlFile containingFile
, XmlNSDescriptor descr
) {
190 public boolean hasDynamicComponents(final PsiElement element
) {
194 public boolean isIndirectSyntax(final XmlAttributeDescriptor descriptor
) {
198 public boolean isCustomTagAllowed(final XmlTag tag
) {