summaryrefslogtreecommitdiff
path: root/xml/xml-psi-impl/src/com/intellij/xml
diff options
context:
space:
mode:
Diffstat (limited to 'xml/xml-psi-impl/src/com/intellij/xml')
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java13
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/XmlCoreEnvironment.java5
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java520
-rw-r--r--xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java122
4 files changed, 313 insertions, 347 deletions
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java b/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java
index 4ece939ffac0..e54a93394242 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/HtmlXmlExtension.java
@@ -3,6 +3,7 @@ package com.intellij.xml;
import com.intellij.ide.highlighter.HtmlFileType;
import com.intellij.psi.PsiFile;
import com.intellij.psi.xml.XmlDocument;
+import com.intellij.xml.util.HtmlUtil;
import org.jetbrains.annotations.Nullable;
/**
@@ -19,6 +20,16 @@ public class HtmlXmlExtension extends DefaultXmlExtension {
@Nullable
@Override
public String[][] getNamespacesFromDocument(XmlDocument parent, boolean declarationsExist) {
- return super.getNamespacesFromDocument(parent, false);
+ String[][] namespaces = super.getNamespacesFromDocument(parent, false);
+ if (namespaces == null || !HtmlUtil.isHtml5Document(parent)) return namespaces;
+
+ for (String[] namespace : namespaces) {
+ if ("xlink".equals(namespace[0])) return namespaces;
+ }
+
+ String[][] newNamespaces = new String[namespaces.length + 1][2];
+ System.arraycopy(namespaces, 0, newNamespaces, 0, namespaces.length);
+ newNamespaces[namespaces.length] = new String[] {"xlink", "http://www.w3.org/1999/xlink"};
+ return newNamespaces;
}
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/XmlCoreEnvironment.java b/xml/xml-psi-impl/src/com/intellij/xml/XmlCoreEnvironment.java
index b7704fb3b981..4610c2fa97e0 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/XmlCoreEnvironment.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/XmlCoreEnvironment.java
@@ -119,7 +119,7 @@ public class XmlCoreEnvironment {
appEnvironment.addExtension(StandardResourceProvider.EP_NAME, new InternalResourceProvider());
appEnvironment.registerApplicationComponent(PathMacros.class, new PathMacrosImpl());
- appEnvironment.registerApplicationService(ExternalResourceManager.class, new ExternalResourceManagerExImpl(PathMacrosImpl.getInstanceEx()));
+ appEnvironment.registerApplicationService(ExternalResourceManager.class, new ExternalResourceManagerExImpl());
appEnvironment.registerApplicationService(XmlFoldingSettings.class, new XmlFoldingSettings());
Language[] myLanguages = new Language[]{XMLLanguage.INSTANCE, HTMLLanguage.INSTANCE, XHTMLLanguage.INSTANCE, DTDLanguage.INSTANCE};
for (Language myLanguage : myLanguages) {
@@ -137,8 +137,7 @@ public class XmlCoreEnvironment {
public static class ProjectEnvironment {
public ProjectEnvironment(CoreProjectEnvironment projectEnvironment) {
projectEnvironment.getProject().registerService(XmlElementFactory.class, new XmlElementFactoryImpl(projectEnvironment.getProject()));
- projectEnvironment.getProject().registerService(ExternalResourceManagerExImpl.class,
- new ProjectResources(PathMacrosImpl.getInstanceEx()));
+ projectEnvironment.getProject().registerService(ExternalResourceManagerExImpl.class, new ProjectResources());
}
}
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
index 192c272a5f23..17c6f1ab37ae 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/impl/schema/XmlNSDescriptorImpl.java
@@ -30,7 +30,6 @@ import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
-import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
@@ -56,35 +55,35 @@ import java.util.*;
*/
@SuppressWarnings({"HardCodedStringLiteral"})
public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocument>, DumbAware, XmlNSTypeDescriptorProvider {
- private static final Logger LOG = Logger.getInstance("#com.intellij.xml.impl.schema.XmlNSDescriptorImpl");
- @NonNls private static final Set<String> STD_TYPES = new HashSet<String>();
- private static final Set<String> UNDECLARED_STD_TYPES = new HashSet<String>();
- private XmlFile myFile;
- private XmlTag myTag;
- private String myTargetNamespace;
@NonNls
public static final String XSD_PREFIX = "xsd";
-
+ @NonNls public static final String SCHEMA_TAG_NAME = "schema";
+ @NonNls public static final String IMPORT_TAG_NAME = "import";
@NonNls static final String ELEMENT_TAG_NAME = "element";
@NonNls static final String ATTRIBUTE_TAG_NAME = "attribute";
@NonNls static final String COMPLEX_TYPE_TAG_NAME = "complexType";
@NonNls static final String SEQUENCE_TAG_NAME = "sequence";
- @NonNls public static final String SCHEMA_TAG_NAME = "schema";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.xml.impl.schema.XmlNSDescriptorImpl");
+ @NonNls private static final Set<String> STD_TYPES = new HashSet<String>();
+ private static final Set<String> UNDECLARED_STD_TYPES = new HashSet<String>();
@NonNls private static final String INCLUDE_TAG_NAME = "include";
- @NonNls public static final String IMPORT_TAG_NAME = "import";
@NonNls private static final String REDEFINE_TAG_NAME = "redefine";
+ private static final ThreadLocal<Set<PsiFile>> myRedefinedDescriptorsInProcessing = new ThreadLocal<Set<PsiFile>>();
+ private final Map<QNameKey, CachedValue<XmlElementDescriptor>> myDescriptorsMap = Collections.synchronizedMap(new HashMap<QNameKey, CachedValue<XmlElementDescriptor>>());
+ private final Map<Pair<QNameKey, XmlTag>, CachedValue<TypeDescriptor>> myTypesMap = Collections.synchronizedMap(new HashMap<Pair<QNameKey,XmlTag>, CachedValue<TypeDescriptor>>());
+ private XmlFile myFile;
+ private XmlTag myTag;
+ private String myTargetNamespace;
+ private volatile Object[] dependencies;
+ private MultiMap<String,XmlTag> mySubstitutions;
public XmlNSDescriptorImpl(XmlFile file) {
init(file.getDocument());
}
-
+
public XmlNSDescriptorImpl() {
}
- private volatile Object[] dependencies;
-
- private static final ThreadLocal<Set<PsiFile>> myRedefinedDescriptorsInProcessing = new ThreadLocal<Set<PsiFile>>();
-
private static void collectDependencies(@Nullable XmlTag myTag, @NotNull XmlFile myFile, @NotNull Set<PsiFile> visited) {
if (visited.contains(myFile)) return;
visited.add( myFile );
@@ -121,7 +120,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
if(tokenizer.hasMoreTokens()){
PsiFile resourceLocation = ExternalResourceManager.getInstance().getResourceLocation(tokenizer.nextToken(), myFile, null);
- if (resourceLocation == null && uri != null) resourceLocation = ExternalResourceManager.getInstance().getResourceLocation(uri, myFile, null);
+ if (resourceLocation == null) resourceLocation = ExternalResourceManager.getInstance().getResourceLocation(uri, myFile, null);
if (resourceLocation instanceof XmlFile) addDependency((XmlFile)resourceLocation, visited);
}
@@ -136,6 +135,211 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
}
}
+ private static boolean checkSchemaNamespace(String name, XmlTag context){
+ final String namespace = context.getNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(name));
+ if(namespace.length() > 0){
+ return checkSchemaNamespace(namespace);
+ }
+ return XSD_PREFIX.equals(XmlUtil.findPrefixByQualifiedName(name));
+ }
+
+ public static boolean checkSchemaNamespace(String namespace) {
+ return XmlUtil.XML_SCHEMA_URI.equals(namespace) ||
+ XmlUtil.XML_SCHEMA_URI2.equals(namespace) ||
+ XmlUtil.XML_SCHEMA_URI3.equals(namespace);
+ }
+
+ public static boolean checkSchemaNamespace(XmlTag context) {
+ LOG.assertTrue(context.isValid());
+ final String namespace = context.getNamespace();
+ if (namespace.length() > 0) {
+ return checkSchemaNamespace(namespace);
+ }
+ return StringUtil.startsWithConcatenation(context.getName(), XSD_PREFIX, ":");
+ }
+
+ static @NotNull XmlNSDescriptorImpl getNSDescriptorToSearchIn(XmlTag rootTag, final String name, XmlNSDescriptorImpl defaultNSDescriptor) {
+ if (name == null) return defaultNSDescriptor;
+ final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(name);
+
+ if (namespacePrefix.length() > 0) {
+ final String namespace = rootTag.getNamespaceByPrefix(namespacePrefix);
+ final XmlNSDescriptor nsDescriptor = rootTag.getNSDescriptor(namespace, true);
+
+ if (nsDescriptor instanceof XmlNSDescriptorImpl) {
+ return (XmlNSDescriptorImpl)nsDescriptor;
+ }
+ }
+
+ return defaultNSDescriptor;
+ }
+
+ @Nullable
+ private static XmlElementDescriptor getDescriptorFromParent(final XmlTag tag, XmlElementDescriptor elementDescriptor) {
+ final PsiElement parent = tag.getParent();
+ if (parent instanceof XmlTag) {
+ final XmlElementDescriptor descriptor = ((XmlTag)parent).getDescriptor();
+ if (descriptor != null) elementDescriptor = descriptor.getElementDescriptor(tag, (XmlTag)parent);
+ }
+ return elementDescriptor;
+ }
+
+ public static boolean processTagsInNamespace(@NotNull final XmlTag rootTag, String[] tagNames, PsiElementProcessor<XmlTag> processor) {
+ return processTagsInNamespaceInner(rootTag, tagNames, processor, null);
+ }
+
+ private static boolean processTagsInNamespaceInner(@NotNull final XmlTag rootTag, final String[] tagNames,
+ final PsiElementProcessor<XmlTag> processor, Set<XmlTag> visitedTags) {
+ if (visitedTags == null) visitedTags = new HashSet<XmlTag>(3);
+ else if (visitedTags.contains(rootTag)) return true;
+
+ visitedTags.add(rootTag);
+ XmlTag[] tags = rootTag.getSubTags();
+
+ NextTag:
+ for (XmlTag tag : tags) {
+ for(String tagName:tagNames) {
+ if (equalsToSchemaName(tag, tagName)) {
+ final String name = tag.getAttributeValue("name");
+
+ if (name != null) {
+ if (!processor.execute(tag)) {
+ return false;
+ }
+ }
+
+ continue NextTag;
+ }
+ }
+
+ if (equalsToSchemaName(tag, INCLUDE_TAG_NAME)) {
+ final String schemaLocation = tag.getAttributeValue("schemaLocation");
+
+ if (schemaLocation != null) {
+ final XmlFile xmlFile = XmlUtil.findNamespace(rootTag.getContainingFile(), schemaLocation);
+
+ if (xmlFile != null) {
+ final XmlDocument includedDocument = xmlFile.getDocument();
+
+ if (includedDocument != null) {
+ if (!processTagsInNamespaceInner(includedDocument.getRootTag(), tagNames, processor, visitedTags)) return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean equalsToSchemaName(@NotNull XmlTag tag, @NonNls String schemaName) {
+ return schemaName.equals(tag.getLocalName()) && checkSchemaNamespace(tag);
+ }
+
+ private static @Nullable XmlTag findSpecialTag(@NonNls String name, @NonNls String specialName, XmlTag rootTag, XmlNSDescriptorImpl descriptor,
+ HashSet<XmlTag> visited) {
+ XmlNSDescriptorImpl nsDescriptor = getNSDescriptorToSearchIn(rootTag, name, descriptor);
+
+ if (nsDescriptor != descriptor) {
+ final XmlDocument document = nsDescriptor.getDescriptorFile() != null ? nsDescriptor.getDescriptorFile().getDocument():null;
+ if (document == null) return null;
+
+ return findSpecialTag(
+ XmlUtil.findLocalNameByQualifiedName(name),
+ specialName,
+ document.getRootTag(),
+ nsDescriptor,
+ visited
+ );
+ }
+
+ if (visited == null) visited = new HashSet<XmlTag>(1);
+ else if (visited.contains(rootTag)) return null;
+ visited.add(rootTag);
+
+ XmlTag[] tags = rootTag.getSubTags();
+
+ return findSpecialTagIn(tags, specialName, name, rootTag, descriptor, visited);
+ }
+
+ private static XmlTag findSpecialTagIn(final XmlTag[] tags,
+ final String specialName,
+ final String name,
+ final XmlTag rootTag,
+ final XmlNSDescriptorImpl descriptor, final HashSet<XmlTag> visited) {
+ for (XmlTag tag : tags) {
+ if (equalsToSchemaName(tag, specialName)) {
+ String attribute = tag.getAttributeValue("name");
+
+ if (name.equals(attribute)
+ || name.contains(":") && name.substring(name.indexOf(":") + 1).equals(attribute)) {
+ return tag;
+ }
+ } else if (equalsToSchemaName(tag, INCLUDE_TAG_NAME) ||
+ ( equalsToSchemaName(tag, IMPORT_TAG_NAME) &&
+ rootTag.getNamespaceByPrefix(
+ XmlUtil.findPrefixByQualifiedName(name)
+ ).equals(tag.getAttributeValue("namespace"))
+ )
+ ) {
+ final String schemaLocation = tag.getAttributeValue("schemaLocation");
+
+ if (schemaLocation != null) {
+ final XmlFile xmlFile = XmlUtil.findNamespace(rootTag.getContainingFile(), schemaLocation);
+
+ if (xmlFile != null) {
+ final XmlDocument document = xmlFile.getDocument();
+ if (document != null) {
+ final XmlTag rTag = findSpecialTag(name, specialName, document.getRootTag(), descriptor, visited);
+
+ if (rTag != null) return rTag;
+ }
+ }
+ }
+ } else if (equalsToSchemaName(tag, REDEFINE_TAG_NAME)) {
+ XmlTag rTag = findSpecialTagIn(tag.getSubTags(), specialName, name, rootTag, descriptor, visited);
+ if (rTag != null) return rTag;
+
+ final XmlNSDescriptorImpl nsDescriptor = getRedefinedElementDescriptor(tag);
+ if (nsDescriptor != null) {
+ final XmlTag redefinedRootTag = ((XmlDocument)nsDescriptor.getDeclaration()).getRootTag();
+
+ rTag = findSpecialTagIn(redefinedRootTag.getSubTags(), specialName, name, redefinedRootTag, nsDescriptor, visited);
+ if (rTag != null) return rTag;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public static XmlNSDescriptorImpl getRedefinedElementDescriptor(final XmlTag parentTag) {
+ XmlFile file = getRedefinedElementDescriptorFile(parentTag);
+ if (file != null) {
+ final XmlDocument document = file.getDocument();
+ final PsiMetaData metaData = document != null ? document.getMetaData():null;
+ if (metaData instanceof XmlNSDescriptorImpl) return (XmlNSDescriptorImpl)metaData;
+ }
+ return null;
+ }
+
+ public static XmlFile getRedefinedElementDescriptorFile(final XmlTag parentTag) {
+ final String schemaL = parentTag.getAttributeValue(XmlUtil.SCHEMA_LOCATION_ATT);
+
+ if (schemaL != null) {
+ final PsiReference[] references = parentTag.getAttribute(XmlUtil.SCHEMA_LOCATION_ATT, null).getValueElement().getReferences();
+
+ if (references.length > 0) {
+ final PsiElement psiElement = references[references.length - 1].resolve();
+
+ if (psiElement instanceof XmlFile) {
+ return ((XmlFile)psiElement);
+ }
+ }
+ }
+ return null;
+ }
+
@Override
public XmlFile getDescriptorFile() {
return myFile;
@@ -150,18 +354,10 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
return myTargetNamespace != null ? myTargetNamespace : "";
}
- static class QNameKey extends Pair<String, String>{
- QNameKey(String name, String namespace) {
- super(name, namespace);
- }
- }
- private final Map<QNameKey, CachedValue<XmlElementDescriptor>> myDescriptorsMap = Collections.synchronizedMap(new HashMap<QNameKey, CachedValue<XmlElementDescriptor>>());
- private final Map<Pair<QNameKey, XmlTag>, CachedValue<TypeDescriptor>> myTypesMap = Collections.synchronizedMap(new HashMap<Pair<QNameKey,XmlTag>, CachedValue<TypeDescriptor>>());
-
@Override
@Nullable
public XmlElementDescriptor getElementDescriptor(String localName, String namespace) {
- return getElementDescriptor(localName, namespace, new HashSet<XmlNSDescriptorImpl>(),false);
+ return getElementDescriptor(localName, namespace, new HashSet<XmlNSDescriptorImpl>(), false);
}
@Nullable
@@ -213,9 +409,9 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
)
)
) {
- final XmlAttribute schemaLocation = tag.getAttribute("schemaLocation");
+ final String schemaLocation = tag.getAttributeValue("schemaLocation");
if (schemaLocation != null) {
- final XmlFile xmlFile = XmlUtil.findNamespace(rootTag.getContainingFile(), schemaLocation.getValue());
+ final XmlFile xmlFile = XmlUtil.findNamespace(rootTag.getContainingFile(), schemaLocation);
if (xmlFile != null) {
final XmlDocument includedDocument = xmlFile.getDocument();
if (includedDocument != null) {
@@ -266,8 +462,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
return true;
}
else {
- final boolean b = myTargetNamespace.equals(namespace);
- if (b) return b;
+ if (myTargetNamespace.equals(namespace)) return true;
return context.getNSDescriptor(namespace, true) == this; // schema's targetNamespace could be different from file systemId
}
return false;
@@ -311,10 +506,10 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
namespace.equals(tag.getAttributeValue("namespace"))
)
) {
- final XmlAttribute schemaLocation = tag.getAttribute("schemaLocation");
+ final String schemaLocation = tag.getAttributeValue("schemaLocation");
if (schemaLocation != null) {
- final XmlFile xmlFile = XmlUtil.findNamespace(myTag.getContainingFile(), schemaLocation.getValue());
+ final XmlFile xmlFile = XmlUtil.findNamespace(myTag.getContainingFile(), schemaLocation);
if (xmlFile != null) {
@@ -370,7 +565,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
public TypeDescriptor getTypeDescriptor(final String name, XmlTag context) {
if(checkSchemaNamespace(name, context)){
final String localNameByQualifiedName = XmlUtil.findLocalNameByQualifiedName(name);
-
+
if (STD_TYPES.contains(localNameByQualifiedName) &&
( name.length() == localNameByQualifiedName.length() ||
UNDECLARED_STD_TYPES.contains(localNameByQualifiedName)
@@ -390,45 +585,6 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
return new XmlElementDescriptorByType(instanceTag, (ComplexTypeDescriptor)typeDescriptor);
}
- private static boolean checkSchemaNamespace(String name, XmlTag context){
- final String namespace = context.getNamespaceByPrefix(XmlUtil.findPrefixByQualifiedName(name));
- if(namespace.length() > 0){
- return checkSchemaNamespace(namespace);
- }
- return XSD_PREFIX.equals(XmlUtil.findPrefixByQualifiedName(name));
- }
-
- public static boolean checkSchemaNamespace(String namespace) {
- return XmlUtil.XML_SCHEMA_URI.equals(namespace) ||
- XmlUtil.XML_SCHEMA_URI2.equals(namespace) ||
- XmlUtil.XML_SCHEMA_URI3.equals(namespace);
- }
-
- public static boolean checkSchemaNamespace(XmlTag context) {
- LOG.assertTrue(context.isValid());
- final String namespace = context.getNamespace();
- if (namespace.length() > 0) {
- return checkSchemaNamespace(namespace);
- }
- return StringUtil.startsWithConcatenation(context.getName(), XSD_PREFIX, ":");
- }
-
- static @NotNull XmlNSDescriptorImpl getNSDescriptorToSearchIn(XmlTag rootTag, final String name, XmlNSDescriptorImpl defaultNSDescriptor) {
- if (name == null) return defaultNSDescriptor;
- final String namespacePrefix = XmlUtil.findPrefixByQualifiedName(name);
-
- if (namespacePrefix != null && namespacePrefix.length() > 0) {
- final String namespace = rootTag.getNamespaceByPrefix(namespacePrefix);
- final XmlNSDescriptor nsDescriptor = rootTag.getNSDescriptor(namespace, true);
-
- if (nsDescriptor instanceof XmlNSDescriptorImpl) {
- return (XmlNSDescriptorImpl)nsDescriptor;
- }
- }
-
- return defaultNSDescriptor;
- }
-
@Nullable
protected TypeDescriptor findTypeDescriptor(final String qname) {
return findTypeDescriptor(qname, myTag);
@@ -587,7 +743,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
private boolean isSameName(@NotNull String name, String namespace, String nameAttribute) {
return nameAttribute != null &&
- (nameAttribute.equals(name) || (name.indexOf(":") >= 0 && nameAttribute.equals(name.substring(name.indexOf(":") + 1)))) &&
+ (nameAttribute.equals(name) || (name.contains(":") && nameAttribute.equals(name.substring(name.indexOf(":") + 1)))) &&
(namespace == null || namespace.length() == 0 || namespace.equals(getDefaultNamespace()))
;
}
@@ -619,23 +775,24 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
}
private CachedValue<TypeDescriptor> createAndPutTypesCachedValue(final XmlTag tag, final Pair<QNameKey, XmlTag> pair) {
- final CachedValue<TypeDescriptor> value = CachedValuesManager.getManager(tag.getProject()).createCachedValue(new CachedValueProvider<TypeDescriptor>() {
- @Override
- public CachedValueProvider.Result<TypeDescriptor> compute() {
- final String name = tag.getAttributeValue("name");
-
- if (name != null &&
- pair.first != null &&
- pair.first.first != null &&
- !name.equals(XmlUtil.findLocalNameByQualifiedName(pair.first.first))
- ) {
- myTypesMap.remove(pair);
- return new Result<TypeDescriptor>(null, PsiModificationTracker.MODIFICATION_COUNT);
+ final CachedValue<TypeDescriptor> value = CachedValuesManager.getManager(tag.getProject()).createCachedValue(
+ new CachedValueProvider<TypeDescriptor>() {
+ @Override
+ public CachedValueProvider.Result<TypeDescriptor> compute() {
+ final String name = tag.getAttributeValue("name");
+
+ if (name != null &&
+ pair.first != null &&
+ pair.first.first != null &&
+ !name.equals(XmlUtil.findLocalNameByQualifiedName(pair.first.first))
+ ) {
+ myTypesMap.remove(pair);
+ return new Result<TypeDescriptor>(null, PsiModificationTracker.MODIFICATION_COUNT);
+ }
+ final ComplexTypeDescriptor complexTypeDescriptor = new ComplexTypeDescriptor(XmlNSDescriptorImpl.this, tag);
+ return new Result<TypeDescriptor>(complexTypeDescriptor, tag);
}
- final ComplexTypeDescriptor complexTypeDescriptor = new ComplexTypeDescriptor(XmlNSDescriptorImpl.this, tag);
- return new Result<TypeDescriptor>(complexTypeDescriptor, tag);
- }
- }, false);
+ }, false);
myTypesMap.put(pair, value);
return value;
}
@@ -668,7 +825,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
}
else {
XmlElementDescriptor elementDescriptor = getElementDescriptor(tag.getLocalName(), tag.getNamespace());
-
+
if (elementDescriptor == null) {
elementDescriptor = getDescriptorFromParent(tag, elementDescriptor);
}
@@ -677,29 +834,19 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
}
}
- @Nullable
- private static XmlElementDescriptor getDescriptorFromParent(final XmlTag tag, XmlElementDescriptor elementDescriptor) {
- final PsiElement parent = tag.getParent();
- if (parent instanceof XmlTag) {
- final XmlElementDescriptor descriptor = ((XmlTag)parent).getDescriptor();
- if (descriptor != null) elementDescriptor = descriptor.getElementDescriptor(tag, (XmlTag)parent);
- }
- return elementDescriptor;
- }
-
@Override
@NotNull
public XmlElementDescriptor[] getRootElementsDescriptors(@Nullable final XmlDocument doc) {
class CollectElementsProcessor implements PsiElementProcessor<XmlTag> {
final List<XmlElementDescriptor> result = new ArrayList<XmlElementDescriptor>();
-
+
@Override
public boolean execute(@NotNull final XmlTag element) {
ContainerUtil.addIfNotNull(result, getElementDescriptor(element.getAttributeValue("name"), getDefaultNamespace()));
return true;
}
}
-
+
CollectElementsProcessor processor = new CollectElementsProcessor() {
@Override
public boolean execute(@NotNull final XmlTag element) {
@@ -729,135 +876,6 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
return processor.result.toArray(new XmlAttributeDescriptor[processor.result.size()]);
}
- public static boolean processTagsInNamespace(@NotNull final XmlTag rootTag, String[] tagNames, PsiElementProcessor<XmlTag> processor) {
- return processTagsInNamespaceInner(rootTag, tagNames, processor, null);
- }
-
- private static boolean processTagsInNamespaceInner(@NotNull final XmlTag rootTag, final String[] tagNames,
- final PsiElementProcessor<XmlTag> processor, Set<XmlTag> visitedTags) {
- if (visitedTags == null) visitedTags = new HashSet<XmlTag>(3);
- else if (visitedTags.contains(rootTag)) return true;
-
- visitedTags.add(rootTag);
- XmlTag[] tags = rootTag.getSubTags();
-
- NextTag:
- for (XmlTag tag : tags) {
- for(String tagName:tagNames) {
- if (equalsToSchemaName(tag, tagName)) {
- final String name = tag.getAttributeValue("name");
-
- if (name != null) {
- if (!processor.execute(tag)) {
- return false;
- }
- }
-
- continue NextTag;
- }
- }
-
- if (equalsToSchemaName(tag, INCLUDE_TAG_NAME)) {
- final String schemaLocation = tag.getAttributeValue("schemaLocation");
-
- if (schemaLocation != null) {
- final XmlFile xmlFile = XmlUtil.findNamespace(rootTag.getContainingFile(), schemaLocation);
-
- if (xmlFile != null) {
- final XmlDocument includedDocument = xmlFile.getDocument();
-
- if (includedDocument != null) {
- if (!processTagsInNamespaceInner(includedDocument.getRootTag(), tagNames, processor, visitedTags)) return false;
- }
- }
- }
- }
- }
-
- return true;
- }
-
- public static boolean equalsToSchemaName(@NotNull XmlTag tag, @NonNls String schemaName) {
- return schemaName.equals(tag.getLocalName()) && checkSchemaNamespace(tag);
- }
-
- private static @Nullable XmlTag findSpecialTag(@NonNls String name, @NonNls String specialName, XmlTag rootTag, XmlNSDescriptorImpl descriptor,
- HashSet<XmlTag> visited) {
- XmlNSDescriptorImpl nsDescriptor = getNSDescriptorToSearchIn(rootTag, name, descriptor);
-
- if (nsDescriptor != descriptor) {
- final XmlDocument document = nsDescriptor.getDescriptorFile() != null ? nsDescriptor.getDescriptorFile().getDocument():null;
- if (document == null) return null;
-
- return findSpecialTag(
- XmlUtil.findLocalNameByQualifiedName(name),
- specialName,
- document.getRootTag(),
- nsDescriptor,
- visited
- );
- }
-
- if (visited == null) visited = new HashSet<XmlTag>(1);
- else if (visited.contains(rootTag)) return null;
- visited.add(rootTag);
-
- XmlTag[] tags = rootTag.getSubTags();
-
- return findSpecialTagIn(tags, specialName, name, rootTag, descriptor, visited);
- }
-
- private static XmlTag findSpecialTagIn(final XmlTag[] tags,
- final String specialName,
- final String name,
- final XmlTag rootTag,
- final XmlNSDescriptorImpl descriptor, final HashSet<XmlTag> visited) {
- for (XmlTag tag : tags) {
- if (equalsToSchemaName(tag, specialName)) {
- String attribute = tag.getAttributeValue("name");
-
- if (name.equals(attribute)
- || name.indexOf(":") >= 0 && name.substring(name.indexOf(":") + 1).equals(attribute)) {
- return tag;
- }
- } else if (equalsToSchemaName(tag, INCLUDE_TAG_NAME) ||
- ( equalsToSchemaName(tag, IMPORT_TAG_NAME) &&
- rootTag.getNamespaceByPrefix(
- XmlUtil.findPrefixByQualifiedName(name)
- ).equals(tag.getAttributeValue("namespace"))
- )
- ) {
- final String schemaLocation = tag.getAttributeValue("schemaLocation");
-
- if (schemaLocation != null) {
- final XmlFile xmlFile = XmlUtil.findNamespace(rootTag.getContainingFile(), schemaLocation);
-
- if (xmlFile != null) {
- final XmlDocument document = xmlFile.getDocument();
- if (document != null) {
- final XmlTag rTag = findSpecialTag(name, specialName, document.getRootTag(), descriptor, visited);
-
- if (rTag != null) return rTag;
- }
- }
- }
- } else if (equalsToSchemaName(tag, REDEFINE_TAG_NAME)) {
- XmlTag rTag = findSpecialTagIn(tag.getSubTags(), specialName, name, rootTag, descriptor, visited);
- if (rTag != null) return rTag;
-
- final XmlNSDescriptorImpl nsDescriptor = getRedefinedElementDescriptor(tag);
- if (nsDescriptor != null) {
- final XmlTag redefinedRootTag = ((XmlDocument)nsDescriptor.getDeclaration()).getRootTag();
-
- rTag = findSpecialTagIn(redefinedRootTag.getSubTags(), specialName, name, redefinedRootTag, nsDescriptor, visited);
- if (rTag != null) return rTag;
- }
- }
- }
-
- return null;
- }
-
@Nullable
public XmlTag findGroup(String name) {
return findSpecialTag(name,"group",myTag, this, null);
@@ -865,11 +883,9 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
@Nullable
public XmlTag findAttributeGroup(String name) {
- return findSpecialTag(name,"attributeGroup",myTag,this, null);
+ return findSpecialTag(name, "attributeGroup", myTag, this, null);
}
- private MultiMap<String,XmlTag> mySubstitutions;
-
public XmlElementDescriptor[] getSubstitutes(String localName, String namespace) {
if (!initSubstitutes()) {
return XmlElementDescriptor.EMPTY_ARRAY;
@@ -926,7 +942,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
@Override
public void init(PsiElement element){
myFile = (XmlFile) element.getContainingFile();
-
+
if (element instanceof XmlTag) {
myTag = (XmlTag)element;
} else {
@@ -955,7 +971,6 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
if (dependencies == null) dependencies = myFile == null ? ArrayUtil.EMPTY_OBJECT_ARRAY : new Object[] {myFile}; // init was not called
return dependencies;
}
-
static {
STD_TYPES.add("string");
STD_TYPES.add("normalizedString");
@@ -1002,7 +1017,7 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
STD_TYPES.add("NMTOKEN");
STD_TYPES.add("NMTOKENS");
STD_TYPES.add("anySimpleType");
-
+
UNDECLARED_STD_TYPES.add("anySimpleType");
}
@@ -1015,33 +1030,6 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
return myTag;
}
- public static XmlNSDescriptorImpl getRedefinedElementDescriptor(final XmlTag parentTag) {
- XmlFile file = getRedefinedElementDescriptorFile(parentTag);
- if (file != null) {
- final XmlDocument document = file.getDocument();
- final PsiMetaData metaData = document != null ? document.getMetaData():null;
- if (metaData instanceof XmlNSDescriptorImpl) return (XmlNSDescriptorImpl)metaData;
- }
- return null;
- }
-
- public static XmlFile getRedefinedElementDescriptorFile(final XmlTag parentTag) {
- final String schemaL = parentTag.getAttributeValue(XmlUtil.SCHEMA_LOCATION_ATT);
-
- if (schemaL != null) {
- final PsiReference[] references = parentTag.getAttribute(XmlUtil.SCHEMA_LOCATION_ATT, null).getValueElement().getReferences();
-
- if (references.length > 0) {
- final PsiElement psiElement = references[references.length - 1].resolve();
-
- if (psiElement instanceof XmlFile) {
- return ((XmlFile)psiElement);
- }
- }
- }
- return null;
- }
-
public boolean hasSubstitutions() {
initSubstitutes();
return mySubstitutions != null && mySubstitutions.size() > 0;
@@ -1050,4 +1038,10 @@ public class XmlNSDescriptorImpl implements XmlNSDescriptorEx,Validator<XmlDocum
public boolean isValid() {
return myFile != null && getDeclaration().isValid();
}
+
+ static class QNameKey extends Pair<String, String>{
+ QNameKey(String name, String namespace) {
+ super(name, namespace);
+ }
+ }
}
diff --git a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
index a513db49b121..9de6d6e7e1d6 100644
--- a/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
+++ b/xml/xml-psi-impl/src/com/intellij/xml/util/XmlUtil.java
@@ -82,19 +82,14 @@ import java.util.*;
* @author Mike
*/
public class XmlUtil {
- private static final Logger LOG = Logger.getInstance("#com.intellij.xml.util.XmlUtil");
-
@NonNls public static final String TAGLIB_1_2_URI = "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd";
-
@NonNls public static final String XML_SCHEMA_URI = "http://www.w3.org/2001/XMLSchema";
@NonNls public static final String XML_SCHEMA_URI2 = "http://www.w3.org/1999/XMLSchema";
@NonNls public static final String XML_SCHEMA_URI3 = "http://www.w3.org/2000/10/XMLSchema";
public static final String[] SCHEMA_URIS = {XML_SCHEMA_URI, XML_SCHEMA_URI2, XML_SCHEMA_URI3};
@NonNls public static final String XML_SCHEMA_INSTANCE_URI = "http://www.w3.org/2001/XMLSchema-instance";
-
@NonNls public static final String XSLT_URI = "http://www.w3.org/1999/XSL/Transform";
@NonNls public static final String XINCLUDE_URI = XmlPsiUtil.XINCLUDE_URI;
-
@NonNls public static final String ANT_URI = "http://ant.apache.org/schema.xsd";
@NonNls public static final String XHTML_URI = "http://www.w3.org/1999/xhtml";
@NonNls public static final String HTML_URI = "http://www.w3.org/1999/html";
@@ -102,31 +97,21 @@ public class XmlUtil {
@NonNls public static final Key<String> TEST_PATH = Key.create("TEST PATH");
@NonNls public static final String JSP_URI = "http://java.sun.com/JSP/Page";
@NonNls public static final String ANY_URI = "http://www.intellij.net/ns/any";
-
@NonNls public static final String JSTL_CORE_URI = "http://java.sun.com/jsp/jstl/core";
@NonNls public static final String JSTL_CORE_URI2 = "http://java.sun.com/jstl/core";
@NonNls public static final String JSTL_CORE_URI3 = "http://java.sun.com/jstl/core_rt";
@NonNls public static final String JSTL_CORE_URI_JAVAEE_7 = "http://xmlns.jcp.org/jsp/jstl/core";
-
@NonNls public static final String[] JSTL_CORE_URIS = {JSTL_CORE_URI, JSTL_CORE_URI2, JSTL_CORE_URI3, JSTL_CORE_URI_JAVAEE_7};
-
-
@NonNls public static final String JSF_HTML_URI = "http://java.sun.com/jsf/html";
@NonNls public static final String JSF_HTML_URI_JAVAEE_7 = "http://xmlns.jcp.org/jsf/html";
@NonNls public static final String[] JSF_HTML_URIS = {JSF_HTML_URI, JSF_HTML_URI_JAVAEE_7};
-
@NonNls public static final String JSF_CORE_URI = "http://java.sun.com/jsf/core";
@NonNls public static final String JSF_CORE_URI_JAVAEE_7 = "http://xmlns.jcp.org/jsf/core";
@NonNls public static final String[] JSF_CORE_URIS = {JSF_CORE_URI, JSF_CORE_URI_JAVAEE_7};
-
@NonNls public static final String JSF_PASS_THROUGH_ATTR_URI_JAVAEE7 = "http://xmlns.jcp.org/jsf";
@NonNls public static final String JSF_PASSTHROUGH_URI = "http://xmlns.jcp.org/jsf/passthrough";
-
@NonNls public static final String JSTL_FORMAT_URI = "http://java.sun.com/jsp/jstl/fmt";
@NonNls public static final String JSTL_FORMAT_URI2 = "http://java.sun.com/jstl/fmt";
- @NonNls private static final String JSTL_FORMAT_URI3 = "http://java.sun.com/jstl/fmt_rt";
- @NonNls public static final String[] JSTL_FORMAT_URIS = {JSTL_FORMAT_URI, JSTL_FORMAT_URI2, JSTL_FORMAT_URI3};
-
@NonNls public static final String SPRING_URI = "http://www.springframework.org/tags";
@NonNls public static final String SPRING_FORMS_URI = "http://www.springframework.org/tags/form";
@NonNls public static final String STRUTS_BEAN_URI = "http://struts.apache.org/tags-bean";
@@ -135,26 +120,21 @@ public class XmlUtil {
@NonNls public static final String STRUTS_LOGIC_URI = "http://struts.apache.org/tags-logic";
@NonNls public static final String STRUTS_HTML_URI = "http://struts.apache.org/tags-html";
@NonNls public static final String STRUTS_HTML_URI2 = "http://jakarta.apache.org/struts/tags-html";
-
@NonNls public static final String APACHE_TRINIDAD_URI = "http://myfaces.apache.org/trinidad";
@NonNls public static final String APACHE_TRINIDAD_HTML_URI = "http://myfaces.apache.org/trinidad/html";
-
@NonNls public static final String XSD_SIMPLE_CONTENT_TAG = "simpleContent";
@NonNls public static final String NO_NAMESPACE_SCHEMA_LOCATION_ATT = "noNamespaceSchemaLocation";
@NonNls public static final String SCHEMA_LOCATION_ATT = "schemaLocation";
@NonNls public static final String[] WEB_XML_URIS =
{"http://java.sun.com/xml/ns/j2ee", "http://java.sun.com/xml/ns/javaee", "http://xmlns.jcp.org/xml/ns/javaee", "http://java.sun.com/dtd/web-app_2_3.dtd",
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"};
-
@NonNls public static final String FACELETS_URI = "http://java.sun.com/jsf/facelets";
@NonNls public static final String FACELETS_URI_JAVAEE_7 = "http://xmlns.jcp.org/jsf/facelets";
@NonNls public static final String[] FACELETS_URIS = {FACELETS_URI, FACELETS_URI_JAVAEE_7};
-
@NonNls public static final String JSTL_FUNCTIONS_URI = "http://java.sun.com/jsp/jstl/functions";
@NonNls public static final String JSTL_FUNCTIONS_URI2 = "http://java.sun.com/jstl/functions";
@NonNls public static final String JSTL_FUNCTIONS_JAVAEE_7 = "http://xmlns.jcp.org/jsp/jstl/functions";
@NonNls public static final String[] JSTL_FUNCTIONS_URIS = {JSTL_FUNCTIONS_URI, JSTL_FUNCTIONS_URI2};
-
@NonNls public static final String JSTL_FN_FACELET_URI = "com.sun.facelets.tag.jstl.fn.JstlFnLibrary";
@NonNls public static final String JSTL_CORE_FACELET_URI = "com.sun.facelets.tag.jstl.core.JstlCoreLibrary";
@NonNls public static final String TARGET_NAMESPACE_ATTR_NAME = "targetNamespace";
@@ -166,7 +146,6 @@ public class XmlUtil {
@NonNls public static final String ENUMERATION_TAG_NAME = "enumeration";
@NonNls public static final String HTML4_LOOSE_URI = "http://www.w3.org/TR/html4/loose.dtd";
@NonNls public static final String WSDL_SCHEMA_URI = "http://schemas.xmlsoap.org/wsdl/";
-
public static final String XHTML4_SCHEMA_LOCATION;
public final static ThreadLocal<Boolean> BUILDING_DOM_STUBS = new ThreadLocal<Boolean>() {
@Override
@@ -174,52 +153,38 @@ public class XmlUtil {
return Boolean.FALSE;
}
};
+ private static final Logger LOG = Logger.getInstance("#com.intellij.xml.util.XmlUtil");
+ @NonNls private static final String JSTL_FORMAT_URI3 = "http://java.sun.com/jstl/fmt_rt";
+ @NonNls public static final String[] JSTL_FORMAT_URIS = {JSTL_FORMAT_URI, JSTL_FORMAT_URI2, JSTL_FORMAT_URI3};
@NonNls private static final String FILE = "file:";
@NonNls private static final String CLASSPATH = "classpath:/";
@NonNls private static final String URN = "urn:";
+ private final static Set<String> doNotVisitTags = new HashSet<String>(Arrays.asList("annotation", "element", "attribute"));
private XmlUtil() {
}
-
static {
final URL xhtml4SchemaLocationUrl = XmlUtil.class.getResource(ExternalResourceManagerEx.STANDARD_SCHEMAS + "xhtml1-transitional.xsd");
XHTML4_SCHEMA_LOCATION = VfsUtilCore.urlToPath(VfsUtilCore.toIdeaUrl(FileUtil.unquote(xhtml4SchemaLocationUrl.toExternalForm()), false));
}
- @Nullable
- public static String getSchemaLocation(XmlTag tag, String namespace) {
- final String uri = ExternalResourceManagerEx.getInstanceEx().getResourceLocation(namespace, tag.getProject());
- if (uri != null && !uri.equals(namespace)) return uri;
-
- while (true) {
- if (namespace.isEmpty()) {
- final String attributeValue = tag.getAttributeValue("noNamespaceSchemaLocation", XML_SCHEMA_INSTANCE_URI);
- if (attributeValue != null) return attributeValue;
- }
- else {
- String schemaLocation = tag.getAttributeValue("schemaLocation", XML_SCHEMA_INSTANCE_URI);
- if (schemaLocation != null) {
- int start = schemaLocation.indexOf(namespace);
- if (start >= 0) {
- start += namespace.length();
- final StringTokenizer tokenizer = new StringTokenizer(schemaLocation.substring(start + 1));
- if (tokenizer.hasMoreTokens()) {
- return tokenizer.nextToken();
- }
- else {
- return null;
- }
+ public static String getSchemaLocation(XmlTag tag, final String namespace) {
+ while (tag != null) {
+ String schemaLocation = tag.getAttributeValue(SCHEMA_LOCATION_ATT, XML_SCHEMA_INSTANCE_URI);
+ if (schemaLocation != null) {
+ StringTokenizer tokenizer = new StringTokenizer(schemaLocation);
+ int i = 0;
+ while (tokenizer.hasMoreTokens()) {
+ String token = tokenizer.nextToken();
+ if (i % 2 == 0 && namespace.equals(token) && tokenizer.hasMoreTokens()) {
+ return tokenizer.nextToken();
}
+ i++;
}
}
- if (tag.getParent() instanceof XmlTag) {
- tag = (XmlTag)tag.getParent();
- }
- else {
- break;
- }
+ tag = tag.getParentTag();
}
- return null;
+ return namespace;
}
@Nullable
@@ -965,8 +930,6 @@ public class XmlUtil {
});
}
- private final static Set<String> doNotVisitTags = new HashSet<String>(Arrays.asList("annotation", "element", "attribute"));
-
/**
* @return true if enumeration is exhaustive
*/
@@ -1189,31 +1152,6 @@ public class XmlUtil {
return ExternalResourceManager.getInstance().getResourceLocation(s, project) != s;
}
- private static class MyAttributeInfo implements Comparable {
- boolean myRequired = true;
- String myName = null;
-
- MyAttributeInfo(String name) {
- myName = name;
- }
-
- MyAttributeInfo(String name, boolean flag) {
- myName = name;
- myRequired = flag;
- }
-
- @Override
- public int compareTo(Object o) {
- if (o instanceof MyAttributeInfo) {
- return myName.compareTo(((MyAttributeInfo)o).myName);
- }
- else if (o instanceof XmlAttribute) {
- return myName.compareTo(((XmlAttribute)o).getName());
- }
- return -1;
- }
- }
-
public static String generateDocumentDTD(XmlDocument doc, boolean full) {
final Map<String, List<String>> tags = new LinkedHashMap<String, List<String>>();
final Map<String, List<MyAttributeInfo>> attributes = new LinkedHashMap<String, List<MyAttributeInfo>>();
@@ -1303,7 +1241,6 @@ public class XmlUtil {
return name == null ? null : name.substring(name.indexOf(':') + 1);
}
-
public static XmlFile getContainingFile(PsiElement element) {
while (!(element instanceof XmlFile) && element != null) {
final PsiElement context = element.getContext();
@@ -1482,4 +1419,29 @@ public class XmlUtil {
@NotNull
PsiElement getNodeForMessage(@NotNull T t);
}
+
+ private static class MyAttributeInfo implements Comparable {
+ boolean myRequired = true;
+ String myName = null;
+
+ MyAttributeInfo(String name) {
+ myName = name;
+ }
+
+ MyAttributeInfo(String name, boolean flag) {
+ myName = name;
+ myRequired = flag;
+ }
+
+ @Override
+ public int compareTo(Object o) {
+ if (o instanceof MyAttributeInfo) {
+ return myName.compareTo(((MyAttributeInfo)o).myName);
+ }
+ else if (o instanceof XmlAttribute) {
+ return myName.compareTo(((XmlAttribute)o).getName());
+ }
+ return -1;
+ }
+ }
}