diff options
Diffstat (limited to 'xml')
36 files changed, 691 insertions, 615 deletions
diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java index 88bc70044268..a0529b60a8fc 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomInvocationHandler.java @@ -170,7 +170,10 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription @Override public void run() { ensureXmlElementExists(); - final DomGenericInfoEx genericInfo = getGenericInfo(); + final DomInvocationHandler otherInvocationHandler = DomManagerImpl.getDomInvocationHandler(other); + assert otherInvocationHandler != null : other; + + final DomGenericInfoEx genericInfo = otherInvocationHandler.getGenericInfo(); for (final AttributeChildDescriptionImpl description : genericInfo.getAttributeChildrenDescriptions()) { description.getDomAttributeValue(DomInvocationHandler.this).setStringValue(description.getDomAttributeValue(other).getStringValue()); } @@ -197,7 +200,7 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription } } - final String stringValue = DomManagerImpl.getDomInvocationHandler(other).getValue(); + final String stringValue = otherInvocationHandler.getValue(); if (StringUtil.isNotEmpty(stringValue)) { setValue(stringValue); } @@ -659,12 +662,12 @@ public abstract class DomInvocationHandler<T extends AbstractDomChildDescription return new AttributeChildInvocationHandler(evaluatedXmlName, description, myManager, strategy, stub); } final XmlTag tag = getXmlTag(); - + if (tag != null) { // TODO: this seems ugly String ns = evaluatedXmlName.getNamespace(tag, getFile()); final XmlAttribute attribute = tag.getAttribute(description.getXmlName().getLocalName(), ns.equals(tag.getNamespace())? null:ns); - + if (attribute != null) { PsiUtilCore.ensureValid(attribute); AttributeChildInvocationHandler semElement = diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/IndexedElementInvocationHandler.java b/xml/dom-impl/src/com/intellij/util/xml/impl/IndexedElementInvocationHandler.java index b77a838eb0ec..9a90fbf0fcec 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/impl/IndexedElementInvocationHandler.java +++ b/xml/dom-impl/src/com/intellij/util/xml/impl/IndexedElementInvocationHandler.java @@ -44,7 +44,7 @@ public class IndexedElementInvocationHandler extends DomInvocationHandler<FixedC final DomParentStrategy strategy, final DomManagerImpl manager, @Nullable ElementStub stub) { - super(description.getType(), strategy, tagName, description, manager, strategy.getXmlElement() != null, stub); + super(description.getType(), strategy, tagName, description, manager, strategy.isPhysical(), stub); myIndex = index; } diff --git a/xml/dom-impl/src/com/intellij/util/xml/stubs/StubParentStrategy.java b/xml/dom-impl/src/com/intellij/util/xml/stubs/StubParentStrategy.java index b827c6221746..951c6f576249 100644 --- a/xml/dom-impl/src/com/intellij/util/xml/stubs/StubParentStrategy.java +++ b/xml/dom-impl/src/com/intellij/util/xml/stubs/StubParentStrategy.java @@ -20,6 +20,7 @@ import com.intellij.psi.xml.XmlElement; import com.intellij.psi.xml.XmlFile; import com.intellij.psi.xml.XmlTag; import com.intellij.util.xml.impl.*; +import com.intellij.xml.util.XmlUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,6 +33,11 @@ import java.util.List; public class StubParentStrategy implements DomParentStrategy { private final static Logger LOG = Logger.getInstance(StubParentStrategy.class); + protected final DomStub myStub; + + public StubParentStrategy(@NotNull DomStub stub) { + myStub = stub; + } public static StubParentStrategy createAttributeStrategy(@Nullable AttributeStub stub, @NotNull final DomStub parent) { if (stub == null) { @@ -59,12 +65,6 @@ public class StubParentStrategy implements DomParentStrategy { } } - protected final DomStub myStub; - - public StubParentStrategy(@NotNull DomStub stub) { - myStub = stub; - } - @Override public DomInvocationHandler getParentHandler() { DomStub parentStub = myStub.getParentStub(); @@ -82,7 +82,14 @@ public class StubParentStrategy implements DomParentStrategy { // for custom elements, namespace information is lost // todo: propagate ns info through DomChildDescriptions - XmlTag[] tags = parentTag.getSubTags(); + XmlTag[] tags; + try { + XmlUtil.BUILDING_DOM_STUBS.set(true); + tags = parentTag.getSubTags(); + } + finally { + XmlUtil.BUILDING_DOM_STUBS.set(false); + } int i = 0; String nameToFind = myStub.getName(); diff --git a/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubTest.java b/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubTest.java index d0c2174c01d0..a31bc6650aac 100644 --- a/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubTest.java +++ b/xml/dom-tests/tests/com/intellij/util/xml/stubs/DomStubTest.java @@ -52,6 +52,19 @@ public abstract class DomStubTest extends LightCodeInsightFixtureTestCase { } }; + public static ElementStub getRootStub(@TestDataFile String filePath, JavaCodeInsightTestFixture fixture) { + PsiFile psiFile = fixture.configureByFile(filePath); + + StubTreeLoader loader = StubTreeLoader.getInstance(); + VirtualFile file = psiFile.getVirtualFile(); + assertTrue(loader.canHaveStub(file)); + ObjectStubTree stubTree = loader.readFromVFile(fixture.getProject(), file); + assertNotNull(stubTree); + ElementStub root = (ElementStub)stubTree.getRoot(); + assertNotNull(root); + return root; + } + @Override public void setUp() throws Exception { super.setUp(); @@ -67,19 +80,6 @@ public abstract class DomStubTest extends LightCodeInsightFixtureTestCase { return getRootStub(filePath, myFixture); } - public static ElementStub getRootStub(@TestDataFile String filePath, JavaCodeInsightTestFixture fixture) { - PsiFile psiFile = fixture.configureByFile(filePath); - - StubTreeLoader loader = StubTreeLoader.getInstance(); - VirtualFile file = psiFile.getVirtualFile(); - assertTrue(loader.canHaveStub(file)); - ObjectStubTree stubTree = loader.readFromVFile(fixture.getProject(), file); - assertNotNull(stubTree); - ElementStub root = (ElementStub)stubTree.getRoot(); - assertNotNull(root); - return root; - } - protected void doBuilderTest(@TestDataFile String file, String stubText) { ElementStub stub = getRootStub(file); assertEquals(stubText, DebugUtil.stubTreeToString(stub)); @@ -99,7 +99,7 @@ public abstract class DomStubTest extends LightCodeInsightFixtureTestCase { XmlFile file = (XmlFile)((PsiManagerEx)getPsiManager()).getFileManager().findFile(virtualFile); assertFalse(file.getNode().isParsed()); ObjectStubTree tree = StubTreeLoader.getInstance().readOrBuild(getProject(), virtualFile, file); - assertNotNull(tree); + assertNotNull("Can't build stubs for " + path, tree); ((PsiManagerImpl)getPsiManager()).cleanupForNextTest(); diff --git a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form index bccba832488c..c24cc51f68f9 100644 --- a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form +++ b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form @@ -8,7 +8,7 @@ <properties/> <border type="none"/> <children> - <grid id="247ce" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <grid id="247ce" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0"/> <constraints> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/> @@ -24,7 +24,7 @@ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> - <text value="Automatically insert closing tag"/> + <text value="Insert closing tag on tag completion"/> </properties> </component> <component id="9f825" class="javax.swing.JCheckBox" binding="myAutomaticallyInsertRequiredAttributesCheckBox" default-binding="true"> @@ -32,7 +32,7 @@ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> - <text value="Automatically insert required attributes"/> + <text value="Insert required attributes on tag completion"/> </properties> </component> <component id="4bf74" class="javax.swing.JCheckBox" binding="myAutomaticallyStartAttributeAfterCheckBox" default-binding="true"> @@ -41,7 +41,7 @@ </constraints> <properties> <selected value="false"/> - <text value="Automatically start attribute"/> + <text value="Start attribute on tag completion"/> </properties> </component> <component id="c21d3" class="javax.swing.JCheckBox" binding="myAutomaticallyInsertRequiredSubTagsCheckBox" default-binding="true"> @@ -49,7 +49,7 @@ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> - <text value="Automatically insert required subtags"/> + <text value="Insert required subtags on tag completion"/> </properties> </component> <component id="8169b" class="com.intellij.ui.components.JBCheckBox" binding="myAddQuotasForAttributeValue"> @@ -57,7 +57,16 @@ <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> </constraints> <properties> - <text value="Automatically add quotes for attribute value"/> + <text value="Add quotes for attribute value on typing '='"/> + </properties> + </component> + <component id="76e81" class="com.intellij.ui.components.JBCheckBox" binding="myAutoCloseTagCheckBox"> + <constraints> + <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/> + </constraints> + <properties> + <horizontalAlignment value="2"/> + <text value="Auto-close tag on typing '</'"/> </properties> </component> </children> diff --git a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java index 1341f95acd16..2202cc561c96 100644 --- a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java +++ b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsProvider.java @@ -33,6 +33,7 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider { private JCheckBox myAutomaticallyStartAttributeAfterCheckBox; private JBCheckBox mySelectWholeCssIdentifierOnDoubleClick; private JBCheckBox myAddQuotasForAttributeValue; + private JBCheckBox myAutoCloseTagCheckBox; @Override @@ -58,7 +59,8 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider { xmlEditorOptions.isAutomaticallyStartAttribute() != myAutomaticallyStartAttributeAfterCheckBox.isSelected() || xmlEditorOptions.isSelectWholeCssIdentifierOnDoubleClick() != mySelectWholeCssIdentifierOnDoubleClick.isSelected() || xmlEditorOptions.isAutomaticallyInsertRequiredSubTags() != myAutomaticallyInsertRequiredSubTagsCheckBox.isSelected() || - xmlEditorOptions.isInsertQuotesForAttributeValue() != myAddQuotasForAttributeValue.isSelected(); + xmlEditorOptions.isInsertQuotesForAttributeValue() != myAddQuotasForAttributeValue.isSelected() || + xmlEditorOptions.isAutoCloseTag() != myAutoCloseTagCheckBox.isSelected(); } @Override @@ -70,6 +72,7 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider { xmlEditorOptions.setAutomaticallyStartAttribute(myAutomaticallyStartAttributeAfterCheckBox.isSelected()); xmlEditorOptions.setSelectWholeCssIdentifierOnDoubleClick(mySelectWholeCssIdentifierOnDoubleClick.isSelected()); xmlEditorOptions.setInsertQuotesForAttributeValue(myAddQuotasForAttributeValue.isSelected()); + xmlEditorOptions.setAutoCloseTag(myAutoCloseTagCheckBox.isSelected()); } @Override @@ -81,6 +84,7 @@ public class WebEditorOptionsProvider implements EditorOptionsProvider { myAutomaticallyStartAttributeAfterCheckBox.setSelected(xmlEditorOptions.isAutomaticallyStartAttribute()); mySelectWholeCssIdentifierOnDoubleClick.setSelected(xmlEditorOptions.isSelectWholeCssIdentifierOnDoubleClick()); myAddQuotasForAttributeValue.setSelected(xmlEditorOptions.isInsertQuotesForAttributeValue()); + myAutoCloseTagCheckBox.setSelected(xmlEditorOptions.isAutoCloseTag()); } @Override diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java index 656a061b9b4a..bd0d76c42d38 100644 --- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlEqTypedHandler.java @@ -38,7 +38,7 @@ public class XmlEqTypedHandler extends TypedHandlerDelegate { PsiElement at = file.findElementAt(editor.getCaretModel().getOffset() - 1); PsiElement atParent = at != null ? at.getParent() : null; if(atParent instanceof XmlAttribute && ((XmlAttribute)atParent).getValueElement() == null) { - needToInsertQuotes = atParent instanceof XmlAttribute && ((XmlAttribute)atParent).getValueElement() == null; + needToInsertQuotes = ((XmlAttribute)atParent).getValueElement() == null; } } } diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java index c5e0ff307a94..729e6062c626 100644 --- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlSlashTypedHandler.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInsight.editorActions; +import com.intellij.application.options.editor.WebEditorOptions; import com.intellij.lang.ASTNode; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.editor.Editor; @@ -71,6 +72,7 @@ public class XmlSlashTypedHandler extends TypedHandlerDelegate { @Override public Result charTyped(final char c, final Project project, @NotNull final Editor editor, @NotNull final PsiFile editedFile) { + if (!WebEditorOptions.getInstance().isAutoCloseTag()) return Result.CONTINUE; if ((editedFile.getLanguage() instanceof XMLLanguage || editedFile.getViewProvider().getBaseLanguage() instanceof XMLLanguage) && c == '/') { PsiDocumentManager.getInstance(project).commitAllDocuments(); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java index 6bc71f9f8549..aa7e62cbcd54 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/EmmetParser.java @@ -80,6 +80,10 @@ public abstract class EmmetParser { ZenCodingNode mul = parseMul(); ZenCodingToken operationToken = getToken(); + if (operationToken == ZenCodingTokens.OPENING_R_BRACKET) { + mul = new MoreOperationNode(notNullNode(mul), parseExpression()); + operationToken = getToken(); + } if (!(operationToken instanceof OperationToken)) { return mul; } @@ -132,7 +136,7 @@ public abstract class EmmetParser { @Nullable private ZenCodingNode parseMul() { - ZenCodingNode exp = parseExpressionInBraces(); + ZenCodingNode exp = parseExpression(); if (exp == null) { return null; } @@ -153,7 +157,7 @@ public abstract class EmmetParser { } @Nullable - private ZenCodingNode parseExpressionInBraces() { + private ZenCodingNode parseExpression() { ZenCodingToken token = getToken(); if (token == ZenCodingTokens.OPENING_R_BRACKET) { advance(); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java index 4ab715a404bf..01ddc3ca563f 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java @@ -202,7 +202,7 @@ public class XmlEmmetParser extends EmmetParser { int loremWordsCount = DEFAULT_LOREM_LENGTH; if (matcher.groupCount() > 1) { String group = matcher.group(2); - loremWordsCount = group.isEmpty() ? DEFAULT_LOREM_LENGTH : Integer.parseInt(group); + loremWordsCount = group == null || group.isEmpty() ? DEFAULT_LOREM_LENGTH : Integer.parseInt(group); } final List<Couple<String>> attrList = parseSelectors(); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/MoreOperationNode.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/MoreOperationNode.java index 0a1bea140d6b..56d440abc538 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/MoreOperationNode.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/nodes/MoreOperationNode.java @@ -89,8 +89,12 @@ public class MoreOperationNode extends ZenCodingNode { } return result; } - List<GenerationNode> leftGenNodes = myLeftOperand.expand(numberInIteration, totalIterations, surroundedText, callback, insertSurroundedTextAtTheEnd, - parent); + List<GenerationNode> leftGenNodes = myLeftOperand.expand(numberInIteration, totalIterations, surroundedText, callback, insertSurroundedTextAtTheEnd, parent); + + if (leftGenNodes.isEmpty()) { + return myRightOperand.expand(numberInIteration, totalIterations, surroundedText, callback, insertSurroundedTextAtTheEnd, parent); + } + for (GenerationNode leftGenNode : leftGenNodes) { myRightOperand.expand(numberInIteration,totalIterations , surroundedText, callback, insertSurroundedTextAtTheEnd, leftGenNode); } diff --git a/xml/impl/src/com/intellij/xml/arrangement/XmlArrangementVisitor.java b/xml/impl/src/com/intellij/xml/arrangement/XmlArrangementVisitor.java index 7f118e889588..4055b9cffb9f 100644 --- a/xml/impl/src/com/intellij/xml/arrangement/XmlArrangementVisitor.java +++ b/xml/impl/src/com/intellij/xml/arrangement/XmlArrangementVisitor.java @@ -74,7 +74,7 @@ public class XmlArrangementVisitor extends XmlElementVisitor { @Nullable String name, @Nullable String namespace, boolean canBeMatched) { - if (!isWithinBounds(range)) { + if (range.getStartOffset() == 0 && range.getEndOffset() == 0 || !isWithinBounds(range)) { return null; } final DefaultArrangementEntry current = getCurrent(); diff --git a/xml/impl/src/com/intellij/xml/refactoring/SchemaPrefixRenameHandler.java b/xml/impl/src/com/intellij/xml/refactoring/SchemaPrefixRenameHandler.java index bc4ba667afa4..2c1f5a781fcb 100644 --- a/xml/impl/src/com/intellij/xml/refactoring/SchemaPrefixRenameHandler.java +++ b/xml/impl/src/com/intellij/xml/refactoring/SchemaPrefixRenameHandler.java @@ -15,7 +15,6 @@ */ package com.intellij.xml.refactoring; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -35,12 +34,6 @@ import java.util.Collection; */ public class SchemaPrefixRenameHandler extends VariableInplaceRenameHandler { - @Override - protected boolean isAvailable(PsiElement element, Editor editor, PsiFile file) { - PossiblePrefixReference ref = getReference(file, editor); - return ref != null && ref.resolve() instanceof SchemaPrefix; - } - @Nullable private static PossiblePrefixReference getReference(PsiFile file, Editor editor) { if (file != null && editor != null) { @@ -55,6 +48,12 @@ public class SchemaPrefixRenameHandler extends VariableInplaceRenameHandler { } @Override + protected boolean isAvailable(PsiElement element, Editor editor, PsiFile file) { + PossiblePrefixReference ref = getReference(file, editor); + return ref != null && ref.resolve() instanceof SchemaPrefix; + } + + @Override protected VariableInplaceRenamer createRenamer(@NotNull PsiElement elementToRename, Editor editor) { PossiblePrefixReference reference = getReference(elementToRename.getContainingFile(), editor); if (reference != null) { @@ -71,12 +70,6 @@ public class SchemaPrefixRenameHandler extends VariableInplaceRenameHandler { }; } } - if (ApplicationManager.getApplication().isUnitTestMode()) { - System.out.println("Reference: " + reference); - if (reference != null) { - System.out.println("Resolved: " + reference.resolve()); - } - } return null; } } diff --git a/xml/impl/src/com/intellij/xml/refactoring/XmlInlineHandler.java b/xml/impl/src/com/intellij/xml/refactoring/XmlInlineHandler.java index bd3b6b0c8c80..865805796322 100644 --- a/xml/impl/src/com/intellij/xml/refactoring/XmlInlineHandler.java +++ b/xml/impl/src/com/intellij/xml/refactoring/XmlInlineHandler.java @@ -3,22 +3,23 @@ package com.intellij.xml.refactoring; import com.intellij.lang.refactoring.InlineHandler; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; /** * @author Eugene.Kudelevsky */ public class XmlInlineHandler implements InlineHandler { @Override - public Settings prepareInlineElement(PsiElement element, Editor editor, boolean invokedOnReference) { + public Settings prepareInlineElement(@NotNull PsiElement element, Editor editor, boolean invokedOnReference) { return null; } @Override - public void removeDefinition(PsiElement element, Settings settings) { + public void removeDefinition(@NotNull PsiElement element, @NotNull Settings settings) { } @Override - public Inliner createInliner(PsiElement element, Settings settings) { + public Inliner createInliner(@NotNull PsiElement element, @NotNull Settings settings) { return null; } } diff --git a/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiChannelHandler.java b/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiChannelHandler.java index d24078221b30..4a83b637500e 100644 --- a/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiChannelHandler.java +++ b/xml/impl/src/org/jetbrains/io/fastCgi/FastCgiChannelHandler.java @@ -92,7 +92,14 @@ public class FastCgiChannelHandler extends SimpleChannelInboundHandlerAdapter<Fa String value = builder.toString(); if (key.equalsIgnoreCase("status")) { - response.setStatus(HttpResponseStatus.valueOf(Integer.parseInt(value.substring(0, value.indexOf(' '))))); + int index = value.indexOf(' '); + if (index == -1) { + LOG.warn("Cannot parse status: " + value); + response.setStatus(HttpResponseStatus.OK); + } + else { + response.setStatus(HttpResponseStatus.valueOf(Integer.parseInt(value.substring(0, index)))); + } } else if (!(key.startsWith("http") || key.startsWith("HTTP"))) { response.headers().add(key, value); diff --git a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java index 08ada22129d9..b287e6b50777 100644 --- a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java +++ b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java @@ -69,6 +69,9 @@ public class RelaxedHtmlFromRngElementDescriptor implements XmlElementDescriptor @Override public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute) { + XmlAttributeDescriptor descriptor = myDelegate.getAttributeDescriptor(attribute); + if (descriptor != null) return descriptor; + return getAttributeDescriptor(attribute.getName(), attribute.getParent()); } diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/convert/ConvertSchemaSettingsImpl.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/convert/ConvertSchemaSettingsImpl.java index 56fe4c92f733..3161c522b586 100644 --- a/xml/relaxng/src/org/intellij/plugins/relaxNG/convert/ConvertSchemaSettingsImpl.java +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/convert/ConvertSchemaSettingsImpl.java @@ -131,7 +131,7 @@ public class ConvertSchemaSettingsImpl implements ConvertSchemaSettings { final int indent = styleSettings.getIndentSize(type); myIndent.setText(String.valueOf(indent)); - myLineLength.setText(String.valueOf(styleSettings.RIGHT_MARGIN)); + myLineLength.setText(String.valueOf(styleSettings.getDefaultRightMargin())); final SchemaType outputType = getOutputType(); myLineLength.setEnabled(outputType == SchemaType.DTD || outputType == SchemaType.RNC); diff --git a/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc b/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc index fe154b8f57bf..095868dee70a 100644 --- a/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc +++ b/xml/relaxng/src/resources/html5-schema/html5-svg-mathml.rnc @@ -1,7 +1,7 @@ namespace svg = "http://www.w3.org/2000/svg" namespace math = "http://www.w3.org/1998/Math/MathML" -include "svg11/svg11-tiny-inc.rnc" +include "svg11/svg11-inc.rnc" include "mml3/mathml3-inc.rnc" common.elem.phrasing |= svg diff --git a/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc b/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc index 74f188644741..98d6fbd597e4 100644 --- a/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc +++ b/xml/relaxng/src/resources/html5-schema/xhtml5-svg-mathml.rnc @@ -2,7 +2,7 @@ namespace svg = "http://www.w3.org/2000/svg" namespace math = "http://www.w3.org/1998/Math/MathML" namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" -include "svg11/svg11-tiny-inc.rnc" +include "svg11/svg11-inc.rnc" include "inkscape/inkscape.rnc" include "mml3/mathml3-inc.rnc" include "rdf/rdf.rnc" diff --git a/xml/relaxng/src/resources/patches/0007_html5_svg_tiny.patch b/xml/relaxng/src/resources/patches/0007_html5_svg_tiny.patch deleted file mode 100644 index 6a3cc10cc8e2..000000000000 --- a/xml/relaxng/src/resources/patches/0007_html5_svg_tiny.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- /Users/denofevil/Code/sandbox/checker/validator/schema/html5-svg-mathml.rnc 2014-01-24 12:18:54.000000000 +0400 -+++ html5-svg-mathml.rnc 2014-01-25 15:32:10.000000000 +0400 -@@ -1,7 +1,7 @@ - namespace svg = "http://www.w3.org/2000/svg" - namespace math = "http://www.w3.org/1998/Math/MathML" - --include "svg11/svg11-inc.rnc" -+include "svg11/svg11-tiny-inc.rnc" - include "mml3/mathml3-inc.rnc" - - common.elem.phrasing |= svg diff --git a/xml/relaxng/src/resources/patches/0008_xhtml5_svg_tiny.patch b/xml/relaxng/src/resources/patches/0008_xhtml5_svg_tiny.patch deleted file mode 100644 index 773c8969c177..000000000000 --- a/xml/relaxng/src/resources/patches/0008_xhtml5_svg_tiny.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- /Users/denofevil/Code/sandbox/checker/validator/schema/xhtml5-svg-mathml.rnc 2014-01-24 12:18:54.000000000 +0400 -+++ xhtml5-svg-mathml.rnc 2014-01-25 15:50:41.000000000 +0400 -@@ -2,7 +2,7 @@ - namespace math = "http://www.w3.org/1998/Math/MathML" - namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" - --include "svg11/svg11-inc.rnc" -+include "svg11/svg11-tiny-inc.rnc" - include "inkscape/inkscape.rnc" - include "mml3/mathml3-inc.rnc" - include "rdf/rdf.rnc" diff --git a/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java b/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java index c658068ae88e..a5222d701c35 100644 --- a/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java +++ b/xml/xml-analysis-impl/src/com/intellij/application/options/editor/WebEditorOptions.java @@ -44,6 +44,7 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio private boolean myAutomaticallyInsertClosingTag = true; private boolean myAutomaticallyInsertRequiredAttributes = true; private boolean myAutomaticallyInsertRequiredSubTags = true; + private boolean myAutoCloseTag = true; private boolean myAutomaticallyStartAttribute = true; private boolean myInsertQuotesForAttributeValue = true; @@ -51,30 +52,30 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio private int myTagTreeHighlightingLevelCount = 6; private int myTagTreeHighlightingOpacity = 10; - public static WebEditorOptions getInstance() { - return ServiceManager.getService(WebEditorOptions.class); - } - public WebEditorOptions() { setTagTreeHighlightingEnabled(!ApplicationManager.getApplication().isUnitTestMode()); } - public void setBreadcrumbsEnabled(boolean b) { - myBreadcrumbsEnabled = b; + public static WebEditorOptions getInstance() { + return ServiceManager.getService(WebEditorOptions.class); } public boolean isBreadcrumbsEnabled() { return myBreadcrumbsEnabled; } - public void setBreadcrumbsEnabledInXml(boolean b) { - myBreadcrumbsEnabledInXml = b; + public void setBreadcrumbsEnabled(boolean b) { + myBreadcrumbsEnabled = b; } public boolean isBreadcrumbsEnabledInXml() { return myBreadcrumbsEnabledInXml; } + public void setBreadcrumbsEnabledInXml(boolean b) { + myBreadcrumbsEnabledInXml = b; + } + public boolean isShowCssInlineColorPreview() { return myShowCssInlineColorPreview; } @@ -121,30 +122,30 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio myAutomaticallyInsertRequiredSubTags = automaticallyInsertRequiredSubTags; } - public void setTagTreeHighlightingLevelCount(int tagTreeHighlightingLevelCount) { - myTagTreeHighlightingLevelCount = tagTreeHighlightingLevelCount; - } - public int getTagTreeHighlightingLevelCount() { return myTagTreeHighlightingLevelCount; } - public void setTagTreeHighlightingOpacity(int tagTreeHighlightingOpacity) { - myTagTreeHighlightingOpacity = tagTreeHighlightingOpacity; + public void setTagTreeHighlightingLevelCount(int tagTreeHighlightingLevelCount) { + myTagTreeHighlightingLevelCount = tagTreeHighlightingLevelCount; } public int getTagTreeHighlightingOpacity() { return myTagTreeHighlightingOpacity; } - public void setTagTreeHighlightingEnabled(boolean tagTreeHighlightingEnabled) { - myTagTreeHighlightingEnabled = tagTreeHighlightingEnabled; + public void setTagTreeHighlightingOpacity(int tagTreeHighlightingOpacity) { + myTagTreeHighlightingOpacity = tagTreeHighlightingOpacity; } public boolean isTagTreeHighlightingEnabled() { return myTagTreeHighlightingEnabled; } + public void setTagTreeHighlightingEnabled(boolean tagTreeHighlightingEnabled) { + myTagTreeHighlightingEnabled = tagTreeHighlightingEnabled; + } + @Override @NotNull public File[] getExportFiles() { @@ -193,4 +194,12 @@ public class WebEditorOptions implements PersistentStateComponent<WebEditorOptio public void setInsertQuotesForAttributeValue(boolean insertQuotesForAttributeValue) { myInsertQuotesForAttributeValue = insertQuotesForAttributeValue; } + + public boolean isAutoCloseTag() { + return myAutoCloseTag; + } + + public void setAutoCloseTag(boolean autoCloseTag) { + myAutoCloseTag = autoCloseTag; + } } diff --git a/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java b/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java index a5f70c2227dc..a9f91bce7d8b 100644 --- a/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java +++ b/xml/xml-analysis-impl/src/com/intellij/xml/util/XmlRefCountHolder.java @@ -105,10 +105,24 @@ public class XmlRefCountHolder { myId2AttributeListMap.put(id, list); } else if (!soft) { + final boolean html = HtmlUtil.isHtmlFile(attributeValue); + final boolean html5 = HtmlUtil.isHtml5Context(attributeValue); + // mark as duplicate List<XmlAttributeValue> notSoft = ContainerUtil.mapNotNull(list, new NullableFunction<Pair<XmlAttributeValue, Boolean>, XmlAttributeValue>() { @Override public XmlAttributeValue fun(Pair<XmlAttributeValue, Boolean> pair) { + if (html5 && !"id".equalsIgnoreCase(((XmlAttribute)pair.first.getParent()).getName())) { + // according to HTML 5 (http://www.w3.org/TR/html5/dom.html#the-id-attribute) spec + // only id attribute is unique identifier + return null; + } + if (html && pair.first.getParent().getParent() == attributeValue.getParent().getParent()) { + // according to HTML 4 (http://www.w3.org/TR/html401/struct/global.html#adef-id, + // http://www.w3.org/TR/html401/struct/links.html#h-12.2.3) spec id and name occupy + // same namespace, but having same values on one tag is ok + return null; + } return pair.second ? null : pair.first; } }); diff --git a/xml/xml-psi-impl/resources/standardSchemas/xlink.dtd b/xml/xml-psi-impl/resources/standardSchemas/xlink.dtd new file mode 100644 index 000000000000..1a8f153e55db --- /dev/null +++ b/xml/xml-psi-impl/resources/standardSchemas/xlink.dtd @@ -0,0 +1,66 @@ +<!ELEMENT simple ANY> +<!ATTLIST simple + xlink:type (simple) #FIXED "simple" + xlink:href CDATA #IMPLIED + xlink:role CDATA #IMPLIED + xlink:arcrole CDATA #IMPLIED + xlink:title CDATA #IMPLIED + xlink:show (new + |replace + |embed + |other + |none) #IMPLIED + xlink:actuate (onLoad + |onRequest + |other + |none) #IMPLIED> + +<!ELEMENT extended ((title|resource|locator|arc)*)> +<!ATTLIST extended + xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink" + xlink:type (extended) #FIXED "extended" + xlink:role CDATA #IMPLIED + xlink:title CDATA #IMPLIED> + +<!ELEMENT title ANY> +<!-- xml:lang is not required, but provides much of the motivation + for title elements in addition to attributes, and so is provided + here for convenience --> +<!ATTLIST title + xlink:type (title) #FIXED "title" + xml:lang CDATA #IMPLIED> + +<!ELEMENT resource ANY> +<!ATTLIST resource + xlink:type (resource) #FIXED "resource" + xlink:role CDATA #IMPLIED + xlink:title CDATA #IMPLIED + xlink:label NMTOKEN #IMPLIED> + +<!ELEMENT locator (title*)> +<!-- label is not required, but locators have no particular XLink + function if they are not labeled --> +<!ATTLIST locator + xlink:type (locator) #FIXED "locator" + xlink:href CDATA #REQUIRED + xlink:role CDATA #IMPLIED + xlink:title CDATA #IMPLIED + xlink:label NMTOKEN #IMPLIED> + +<!ELEMENT arc (title*)> +<!-- from and to have default behavior when values are missing --> +<!ATTLIST arc + xlink:type (arc) #FIXED "arc" + xlink:arcrole CDATA #IMPLIED + xlink:title CDATA #IMPLIED + xlink:show (new + |replace + |embed + |other + |none) #IMPLIED + xlink:actuate (onLoad + |onRequest + |other + |none) #IMPLIED + xlink:from NMTOKEN #IMPLIED + xlink:to NMTOKEN #IMPLIED>
\ No newline at end of file diff --git a/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java b/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java index d030ccf9f189..13cfa9e13d2a 100644 --- a/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/javaee/ExternalResourceManagerExImpl.java @@ -24,7 +24,10 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.*; +import com.intellij.openapi.util.AtomicNotNullLazyValue; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.NotNullLazyKey; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; @@ -46,9 +49,9 @@ import java.net.URL; import java.util.*; @State(name = "ExternalResourceManagerImpl", - storages = {@Storage( file = StoragePathMacros.APP_CONFIG + "/other.xml")}) -public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx implements JDOMExternalizable { - static final Logger LOG = Logger.getInstance("#com.intellij.j2ee.openapi.impl.ExternalResourceManagerImpl"); + storages = {@Storage(file = StoragePathMacros.APP_CONFIG + "/other.xml")}) +public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx implements PersistentStateComponent<Element> { + static final Logger LOG = Logger.getInstance(ExternalResourceManagerExImpl.class); @NonNls public static final String J2EE_1_3 = "http://java.sun.com/dtd/"; @NonNls public static final String J2EE_1_2 = "http://java.sun.com/j2ee/dtds/"; @@ -92,7 +95,6 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx imp } private final List<ExternalResourceListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); - private final PathMacrosImpl myPathMacros; @NonNls private static final String RESOURCE_ELEMENT = "resource"; @NonNls private static final String URL_ATTR = "url"; @NonNls private static final String LOCATION_ATTR = "location"; @@ -100,10 +102,6 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx imp @NonNls private static final String HTML_DEFAULT_DOCTYPE_ELEMENT = "default-html-doctype"; private static final String DEFAULT_VERSION = null; - public ExternalResourceManagerExImpl(@NotNull PathMacrosImpl pathMacros) { - myPathMacros = pathMacros; - } - @Override public boolean isStandardResource(VirtualFile file) { VirtualFile parent = file.getParent(); @@ -374,39 +372,11 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx imp return getProjectResources(project).getModificationCount(); } - @Override - public void readExternal(Element element) { - final ExpandMacroToPathMap macroExpands = new ExpandMacroToPathMap(); - myPathMacros.addMacroExpands(macroExpands); - macroExpands.substitute(element, SystemInfo.isFileSystemCaseSensitive); - - incModificationCount(); - for (final Object o1 : element.getChildren(RESOURCE_ELEMENT)) { - Element e = (Element)o1; - addSilently(e.getAttributeValue(URL_ATTR), DEFAULT_VERSION, e.getAttributeValue(LOCATION_ATTR).replace('/', File.separatorChar)); - } - - for (final Object o : element.getChildren(IGNORED_RESOURCE_ELEMENT)) { - Element e = (Element)o; - addIgnoredSilently(e.getAttributeValue(URL_ATTR)); - } - - Element child = element.getChild(HTML_DEFAULT_DOCTYPE_ELEMENT); - if (child != null) { - String text = child.getText(); - if (FileUtil.toSystemIndependentName(text).endsWith(".jar!/resources/html5-schema/html5.rnc")) { - text = HTML5_DOCTYPE_ELEMENT; - } - myDefaultHtmlDoctype = text; - } - Element catalogElement = element.getChild(CATALOG_PROPERTIES_ELEMENT); - if (catalogElement != null) { - myCatalogPropertiesFile = catalogElement.getTextTrim(); - } - } + @Nullable @Override - public void writeExternal(Element element) { + public Element getState() { + Element element = new Element("state"); final String[] urls = getAvailableUrls(); for (String url : urls) { if (url == null) continue; @@ -440,9 +410,42 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx imp final ReplacePathToMacroMap macroReplacements = new ReplacePathToMacroMap(); PathMacrosImpl.getInstanceEx().addMacroReplacements(macroReplacements); macroReplacements.substitute(element, SystemInfo.isFileSystemCaseSensitive); + return element; } @Override + public void loadState(Element element) { + final ExpandMacroToPathMap macroExpands = new ExpandMacroToPathMap(); + PathMacrosImpl.getInstanceEx().addMacroExpands(macroExpands); + macroExpands.substitute(element, SystemInfo.isFileSystemCaseSensitive); + + incModificationCount(); + for (final Object o1 : element.getChildren(RESOURCE_ELEMENT)) { + Element e = (Element)o1; + addSilently(e.getAttributeValue(URL_ATTR), DEFAULT_VERSION, e.getAttributeValue(LOCATION_ATTR).replace('/', File.separatorChar)); + } + + for (final Object o : element.getChildren(IGNORED_RESOURCE_ELEMENT)) { + Element e = (Element)o; + addIgnoredSilently(e.getAttributeValue(URL_ATTR)); + } + + Element child = element.getChild(HTML_DEFAULT_DOCTYPE_ELEMENT); + if (child != null) { + String text = child.getText(); + if (FileUtil.toSystemIndependentName(text).endsWith(".jar!/resources/html5-schema/html5.rnc")) { + text = HTML5_DOCTYPE_ELEMENT; + } + myDefaultHtmlDoctype = text; + } + Element catalogElement = element.getChild(CATALOG_PROPERTIES_ELEMENT); + if (catalogElement != null) { + myCatalogPropertiesFile = catalogElement.getTextTrim(); + } + } + + + @Override public void addExternalResourceListener(ExternalResourceListener listener) { myListeners.add(listener); } @@ -465,7 +468,7 @@ public class ExternalResourceManagerExImpl extends ExternalResourceManagerEx imp private static final NotNullLazyKey<ExternalResourceManagerExImpl, Project> INSTANCE_CACHE = ServiceManager.createLazyKey(ExternalResourceManagerExImpl.class); - private ExternalResourceManagerExImpl getProjectResources(Project project) { + private static ExternalResourceManagerExImpl getProjectResources(Project project) { return INSTANCE_CACHE.getValue(project); } diff --git a/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java b/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java index 673540ef38e8..38777922ee35 100644 --- a/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java +++ b/xml/xml-psi-impl/src/com/intellij/javaee/InternalResourceProvider.java @@ -63,5 +63,6 @@ public class InternalResourceProvider implements StandardResourceProvider{ // svg and mathML impl.addIgnoredResource(HtmlUtil.MATH_ML_NAMESPACE); impl.addIgnoredResource(HtmlUtil.SVG_NAMESPACE); + impl.addInternalResource("http://www.w3.org/1999/xlink", "xlink.dtd"); } } diff --git a/xml/xml-psi-impl/src/com/intellij/javaee/ProjectResources.java b/xml/xml-psi-impl/src/com/intellij/javaee/ProjectResources.java index 916090996e7c..4b9541b0ebe2 100644 --- a/xml/xml-psi-impl/src/com/intellij/javaee/ProjectResources.java +++ b/xml/xml-psi-impl/src/com/intellij/javaee/ProjectResources.java @@ -16,42 +16,21 @@ package com.intellij.javaee; import com.intellij.application.options.PathMacrosImpl; -import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.components.StoragePathMacros; -import com.intellij.openapi.util.JDOMExternalizable; -import com.intellij.openapi.util.JDOMExternalizableAdapter; -import org.jdom.Element; import org.jetbrains.annotations.NotNull; import java.util.Collections; import java.util.Map; /** -* @author Dmitry Avdeev -*/ -@State(name = "ProjectResources", storages = {@Storage( file = StoragePathMacros.PROJECT_FILE)}) -public class ProjectResources extends ExternalResourceManagerExImpl implements PersistentStateComponent<Element>, JDOMExternalizable { - private final JDOMExternalizableAdapter myAdapter; - - public ProjectResources(@NotNull PathMacrosImpl pathMacros) { - super(pathMacros); - myAdapter = new JDOMExternalizableAdapter(this, "ProjectResources"); - } - + * @author Dmitry Avdeev + */ +@State(name = "ProjectResources", storages = {@Storage(file = StoragePathMacros.PROJECT_FILE)}) +public class ProjectResources extends ExternalResourceManagerExImpl { @Override protected Map<String, Map<String, Resource>> computeStdResources() { - return Collections.emptyMap(); - } - - @Override - public Element getState() { - return myAdapter.getState(); - } - - @Override - public void loadState(Element state) { - myAdapter.loadState(state); + return Collections.emptyMap(); } } diff --git a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlHighlightingLexer.java b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlHighlightingLexer.java index eeae1d318e15..1d20283aa708 100644 --- a/xml/xml-psi-impl/src/com/intellij/lexer/HtmlHighlightingLexer.java +++ b/xml/xml-psi-impl/src/com/intellij/lexer/HtmlHighlightingLexer.java @@ -15,74 +15,41 @@ */ package com.intellij.lexer; -import com.intellij.lang.*; +import com.intellij.lang.HtmlInlineScriptTokenTypesProvider; +import com.intellij.lang.HtmlScriptContentProvider; +import com.intellij.lang.Language; +import com.intellij.lang.LanguageHtmlInlineScriptTokenTypesProvider; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileTypes.*; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.PlainTextLanguage; +import com.intellij.openapi.fileTypes.SyntaxHighlighter; +import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory; import com.intellij.psi.tree.IElementType; import com.intellij.psi.xml.XmlTokenType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; +import java.util.Map; + public class HtmlHighlightingLexer extends BaseHtmlLexer { private static final Logger LOG = Logger.getInstance("#com.intellij.lexer.HtmlHighlightingLexer"); private static final int EMBEDDED_LEXER_ON = 0x1 << BASE_STATE_SHIFT; private static final int EMBEDDED_LEXER_STATE_SHIFT = BASE_STATE_SHIFT + 1; - - private Lexer embeddedLexer; - private Lexer styleLexer; - private Lexer scriptLexer; - protected Lexer elLexer; - private boolean hasNoEmbeddments; - private final FileType ourStyleFileType;// = FileTypeManager.getInstance().getStdFileType("CSS"); private static final FileType ourInlineScriptFileType; - - static { // At the moment only JS. HtmlInlineScriptTokenTypesProvider provider = LanguageHtmlInlineScriptTokenTypesProvider.getInlineScriptProvider(Language.findLanguageByID("JavaScript")); ourInlineScriptFileType = provider != null ? provider.getFileType() : null; } - - public class XmlEmbeddmentHandler implements TokenHandler { - @Override - public void handleElement(Lexer lexer) { - if (!hasSeenStyle() && !hasSeenScript() || hasNoEmbeddments) return; - final IElementType tokenType = lexer.getTokenType(); - - if (tokenType == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN && hasSeenAttribute() || - tokenType == XmlTokenType.XML_DATA_CHARACTERS && hasSeenTag() || - tokenType == XmlTokenType.XML_COMMENT_CHARACTERS && hasSeenTag() - ) { - setEmbeddedLexer(); - - if (embeddedLexer != null) { - embeddedLexer.start( - getBufferSequence(), - HtmlHighlightingLexer.super.getTokenStart(), - skipToTheEndOfTheEmbeddment(), - embeddedLexer instanceof EmbedmentLexer ? ((EmbedmentLexer)embeddedLexer).getEmbeddedInitialState(tokenType) : 0 - ); - - if (embeddedLexer.getTokenType() == null) { - // no content for embeddment - embeddedLexer = null; - } - } - } - } - } - - public class ElEmbeddmentHandler implements TokenHandler { - @Override - public void handleElement(Lexer lexer) { - setEmbeddedLexer(); - if (embeddedLexer != null) { - embeddedLexer.start(getBufferSequence(), HtmlHighlightingLexer.super.getTokenStart(), HtmlHighlightingLexer.super.getTokenEnd()); - } - } - } + private final FileType ourStyleFileType;// = FileTypeManager.getInstance().getStdFileType("CSS"); + protected Lexer elLexer; + private Lexer embeddedLexer; + private Lexer styleLexer; + private Map<String, Lexer> scriptLexers = new HashMap<String, Lexer>(); + private boolean hasNoEmbeddments; public HtmlHighlightingLexer() { this(null); @@ -114,7 +81,7 @@ public class HtmlHighlightingLexer extends BaseHtmlLexer { } else { embeddedLexer = null; - scriptLexer = null; + scriptLexers.clear(); } } @@ -122,14 +89,20 @@ public class HtmlHighlightingLexer extends BaseHtmlLexer { Lexer newLexer = null; if (hasSeenStyle()) { if (styleLexer == null) { - styleLexer = ourStyleFileType == null - ? null - : SyntaxHighlighterFactory.getSyntaxHighlighter(ourStyleFileType, null, null).getHighlightingLexer(); + if (ourStyleFileType == null) { + styleLexer = null; + } + else { + SyntaxHighlighter highlighter = SyntaxHighlighterFactory.getSyntaxHighlighter(ourStyleFileType, null, null); + LOG.assertTrue(highlighter != null, ourStyleFileType); + styleLexer = highlighter.getHighlightingLexer(); + } } newLexer = styleLexer; } else if (hasSeenScript()) { + Lexer scriptLexer = scriptLexers.get(scriptType); if (scriptLexer == null) { if (hasSeenTag()) { HtmlScriptContentProvider provider = findScriptContentProvider(scriptType); @@ -145,6 +118,7 @@ public class HtmlHighlightingLexer extends BaseHtmlLexer { ourInlineScriptFileType != null ? SyntaxHighlighterFactory.getSyntaxHighlighter(ourInlineScriptFileType, null, null) : null; scriptLexer = syntaxHighlighter != null ? syntaxHighlighter.getHighlightingLexer() : null; } + scriptLexers.put(scriptType, scriptLexer); } newLexer = scriptLexer; } @@ -254,4 +228,43 @@ public class HtmlHighlightingLexer extends BaseHtmlLexer { public void setHasNoEmbeddments(boolean hasNoEmbeddments) { this.hasNoEmbeddments = hasNoEmbeddments; } + + public class XmlEmbeddmentHandler implements TokenHandler { + @Override + public void handleElement(Lexer lexer) { + if (!hasSeenStyle() && !hasSeenScript() || hasNoEmbeddments) return; + final IElementType tokenType = lexer.getTokenType(); + + if (tokenType == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN && hasSeenAttribute() || + tokenType == XmlTokenType.XML_DATA_CHARACTERS && hasSeenTag() || + tokenType == XmlTokenType.XML_COMMENT_CHARACTERS && hasSeenTag() + ) { + setEmbeddedLexer(); + + if (embeddedLexer != null) { + embeddedLexer.start( + getBufferSequence(), + HtmlHighlightingLexer.super.getTokenStart(), + skipToTheEndOfTheEmbeddment(), + embeddedLexer instanceof EmbedmentLexer ? ((EmbedmentLexer)embeddedLexer).getEmbeddedInitialState(tokenType) : 0 + ); + + if (embeddedLexer.getTokenType() == null) { + // no content for embeddment + embeddedLexer = null; + } + } + } + } + } + + public class ElEmbeddmentHandler implements TokenHandler { + @Override + public void handleElement(Lexer lexer) { + setEmbeddedLexer(); + if (embeddedLexer != null) { + embeddedLexer.start(getBufferSequence(), HtmlHighlightingLexer.super.getTokenStart(), HtmlHighlightingLexer.super.getTokenEnd()); + } + } + } } diff --git a/xml/xml-psi-impl/src/com/intellij/psi/XmlElementFactoryImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/XmlElementFactoryImpl.java index 6f40f853b777..20abde77589e 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/XmlElementFactoryImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/XmlElementFactoryImpl.java @@ -23,6 +23,7 @@ import com.intellij.lang.Language; import com.intellij.lang.xml.XMLLanguage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.xml.*; @@ -109,7 +110,17 @@ public class XmlElementFactoryImpl extends XmlElementFactory { } private XmlDocument createXmlDocument(@NonNls final CharSequence text, @NonNls final String fileName, FileType fileType) { - final XmlDocument document = ((XmlFile)PsiFileFactory.getInstance(myProject).createFileFromText(fileName, fileType, text)).getDocument(); + PsiFile fileFromText = PsiFileFactory.getInstance(myProject).createFileFromText(fileName, fileType, text); + + XmlFile xmlFile; + if (fileFromText instanceof XmlFile) { + xmlFile = (XmlFile)fileFromText; + } + else { + xmlFile = (XmlFile)fileFromText.getViewProvider().getPsi(((LanguageFileType)fileType).getLanguage()); + assert xmlFile != null; + } + XmlDocument document = xmlFile.getDocument(); assert document != null; return document; } diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java index a32b51f5fc3f..92c287e8fdbe 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlAttributeValueManipulator.java @@ -30,6 +30,7 @@ import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlTokenType; import com.intellij.util.CharTable; import com.intellij.util.IncorrectOperationException; +import com.intellij.xml.util.XmlUtil; import org.jetbrains.annotations.NotNull; /** @@ -63,7 +64,7 @@ public class XmlAttributeValueManipulator extends AbstractElementManipulator<Xml final int offsetInParent = elementToReplace.getStartOffsetInParent(); String textBeforeRange = text.substring(0, range.getStartOffset() - offsetInParent); String textAfterRange = text.substring(range.getEndOffset()- offsetInParent, text.length()); - text = textBeforeRange + newContent + textAfterRange; + text = textBeforeRange + XmlUtil.escape(newContent) + textAfterRange; } catch(StringIndexOutOfBoundsException e) { LOG.error("Range: " + range + " in text: '" + element.getText() + "'", e); throw e; diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java index de4f9eb6cbc7..e160ba4c14db 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java @@ -51,6 +51,9 @@ public class XmlTextManipulator extends AbstractElementManipulator<XmlText> { else { text.deleteChildRange(text.getFirstChild(), text.getLastChild()); } + //String oldText = text.getText(); + //((PsiLanguageInjectionHost)text).updateText( + // oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset())); return text; } diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java index 1c33789dfd57..dd70733533f8 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java @@ -75,27 +75,8 @@ import java.util.*; public class XmlTagImpl extends XmlElementImpl implements XmlTag { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.xml.XmlTagImpl"); - - private volatile String myName = null; - private volatile String myLocalName; - private volatile XmlAttribute[] myAttributes = null; - private volatile Map<String, String> myAttributeValueMap = null; - private volatile XmlTagValue myValue = null; - private volatile Map<String, CachedValue<XmlNSDescriptor>> myNSDescriptorsMap = null; - private volatile String myCachedNamespace; - private volatile long myModCount; - - private volatile XmlElementDescriptor myCachedDescriptor; - private volatile long myDescriptorModCount = -1; - private volatile long myExtResourcesModCount = -1; - - private volatile boolean myHasNamespaceDeclarations = false; - private volatile BidirectionalMap<String, String> myNamespaceMap = null; @NonNls private static final String XML_NS_PREFIX = "xml"; - - private final int myHC = ourHC++; private static final RecursionGuard ourGuard = RecursionManager.createGuard("xmlTag"); - private static final Key<ParameterizedCachedValue<XmlTag[], XmlTagImpl>> SUBTAGS_KEY = Key.create("subtags"); private static final ParameterizedCachedValueProvider<XmlTag[],XmlTagImpl> CACHED_VALUE_PROVIDER = new ParameterizedCachedValueProvider<XmlTag[], XmlTagImpl>() { @@ -111,11 +92,20 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag { .create(tags, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, tag.getContainingFile()); } }; - - @Override - public final int hashCode() { - return myHC; - } + private final int myHC = ourHC++; + private volatile String myName = null; + private volatile String myLocalName; + private volatile XmlAttribute[] myAttributes = null; + private volatile Map<String, String> myAttributeValueMap = null; + private volatile XmlTagValue myValue = null; + private volatile Map<String, CachedValue<XmlNSDescriptor>> myNSDescriptorsMap = null; + private volatile String myCachedNamespace; + private volatile long myModCount; + private volatile XmlElementDescriptor myCachedDescriptor; + private volatile long myDescriptorModCount = -1; + private volatile long myExtResourcesModCount = -1; + private volatile boolean myHasNamespaceDeclarations = false; + private volatile BidirectionalMap<String, String> myNamespaceMap = null; public XmlTagImpl() { this(XmlElementType.XML_TAG); @@ -125,6 +115,33 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag { super(type); } + @Nullable + private static XmlNSDescriptor getDtdDescriptor(@NotNull XmlFile containingFile) { + final XmlDocument document = containingFile.getDocument(); + if (document == null) { + return null; + } + final String url = XmlUtil.getDtdUri(document); + if (url == null) { + return null; + } + return document.getDefaultNSDescriptor(url, true); + } + + @Nullable + private static String getNSVersion(String ns, final XmlTagImpl xmlTag) { + String versionValue = xmlTag.getAttributeValue("version"); + if (versionValue != null && xmlTag.getNamespace().equals(ns)) { + return versionValue; + } + return null; + } + + @Override + public final int hashCode() { + return myHC; + } + @Override public void clearCaches() { myName = null; @@ -215,19 +232,6 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag { return parentTag.getNSDescriptor(namespace, strict); } - @Nullable - private static XmlNSDescriptor getDtdDescriptor(@NotNull XmlFile containingFile) { - final XmlDocument document = containingFile.getDocument(); - if (document == null) { - return null; - } - final String url = XmlUtil.getDtdUri(document); - if (url == null) { - return null; - } - return document.getDefaultNSDescriptor(url, true); - } - @Override public boolean isEmpty() { return XmlChildRole.CLOSING_TAG_START_FINDER.findChild(this) == null; @@ -325,15 +329,6 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag { return map == null ? Collections.<String, CachedValue<XmlNSDescriptor>>emptyMap() : map; } - @Nullable - private static String getNSVersion(String ns, final XmlTagImpl xmlTag) { - String versionValue = xmlTag.getAttributeValue("version"); - if (versionValue != null && xmlTag.getNamespace().equals(ns)) { - return versionValue; - } - return null; - } - private Map<String, CachedValue<XmlNSDescriptor>> initializeSchema(@NotNull final String namespace, @Nullable final String version, final String fileLocation, @@ -921,7 +916,7 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag { } } } - return ns; + return XmlUtil.getSchemaLocation(this, ns); } protected String getRealNs(final String value) { 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; + } + } } |