| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.util.xml; |
| |
| import com.intellij.openapi.application.Result; |
| import com.intellij.openapi.command.WriteCommandAction; |
| import com.intellij.psi.xml.XmlFile; |
| import com.intellij.psi.xml.XmlTag; |
| import com.intellij.util.xml.impl.DomFileElementImpl; |
| import com.intellij.util.xml.impl.DomTestCase; |
| import com.intellij.util.xml.reflect.DomGenericInfo; |
| |
| import java.util.List; |
| |
| /** |
| * @author peter |
| */ |
| public class DomNamespacesTest extends DomTestCase { |
| |
| public void testUseExistingNamespace() throws Throwable { |
| final MyElement element = createElement("<a xmlns=\"foo\" xmlns:bar=\"bar\"/>", MyElement.class); |
| registerNamespacePolicies(element); |
| |
| final XmlTag fooChildTag = element.getFooChild().ensureTagExists(); |
| assertEquals("foo-child", fooChildTag.getName()); |
| assertEquals("foo", fooChildTag.getNamespace()); |
| assertEquals("", fooChildTag.getNamespacePrefix()); |
| |
| final XmlTag barChildTag = element.getBarChild().ensureTagExists(); |
| assertEquals("bar:bar-child", barChildTag.getName()); |
| assertEquals("bar", barChildTag.getNamespace()); |
| assertEquals("bar", barChildTag.getNamespacePrefix()); |
| } |
| |
| public void testDefineNewNamespace() throws Throwable { |
| final MyElement element = createElement("<a/>", MyElement.class); |
| registerNamespacePolicies(element); |
| |
| final XmlTag fooChildTag = element.getFooChild().ensureTagExists(); |
| assertEquals("foo-child", fooChildTag.getName()); |
| assertEquals("foo", fooChildTag.getNamespace()); |
| assertEquals("", fooChildTag.getNamespacePrefix()); |
| assertEquals("foo", fooChildTag.getAttributeValue("xmlns")); |
| |
| final XmlTag barChildTag = element.getBarChild().ensureTagExists(); |
| assertEquals("bar-child", barChildTag.getName()); |
| assertEquals("bar", barChildTag.getNamespace()); |
| assertEquals("", barChildTag.getNamespacePrefix()); |
| assertEquals("bar", barChildTag.getAttributeValue("xmlns")); |
| } |
| |
| public void testCollectionChildNamespace() throws Throwable { |
| final MyElement element = createElement("<a xmlns:foo=\"foo\"/>", MyElement.class); |
| registerNamespacePolicies(element); |
| |
| final XmlTag fooChildTag = element.addFooElement().getXmlTag(); |
| assertEquals("foo:foo-element", fooChildTag.getName()); |
| assertEquals("foo", fooChildTag.getNamespace()); |
| assertEquals("foo", fooChildTag.getNamespacePrefix()); |
| assertNull(fooChildTag.getAttributeValue("xmlns")); |
| } |
| |
| public void testNoNamespaceForFixedChild() throws Throwable { |
| final MyElement element = createElement("<a xmlns:foo=\"foo\"/>", MyElement.class); |
| registerNamespacePolicies(element); |
| |
| final XmlTag childTag = element.getSomeChild().ensureTagExists(); |
| assertEquals("some-child", childTag.getName()); |
| assertEquals("", childTag.getNamespace()); |
| assertEquals("", childTag.getNamespacePrefix()); |
| assertNull(childTag.getAttributeValue("xmlns")); |
| } |
| |
| public void testNoNamespaceForCollectionChild() throws Throwable { |
| final MyElement element = createElement("<a xmlns:foo=\"foo\"/>", MyElement.class); |
| registerNamespacePolicies(element); |
| |
| final XmlTag childTag = element.addChild().getXmlTag(); |
| assertEquals("child", childTag.getName()); |
| assertEquals("", childTag.getNamespace()); |
| assertEquals("", childTag.getNamespacePrefix()); |
| assertNull(childTag.getAttributeValue("xmlns")); |
| } |
| |
| public void testNamespaceEqualToParent() throws Throwable { |
| final MyElement element = createElement("<a xmlns=\"foo\"/>", MyElement.class); |
| registerNamespacePolicies(element); |
| |
| final XmlTag childTag = element.addChild().getXmlTag(); |
| assertEquals("child", childTag.getName()); |
| assertEquals("foo", childTag.getNamespace()); |
| assertEquals("", childTag.getNamespacePrefix()); |
| assertNull(childTag.getAttributeValue("xmlns")); |
| } |
| |
| public void testNamespaceEqualToParent2() throws Throwable { |
| final MyElement root = createElement("<a xmlns=\"foo\"/>", MyElement.class); |
| registerNamespacePolicies(root); |
| final MyFooElement element = root.addFooElement(); |
| |
| final MyElement child = element.addChild(); |
| final XmlTag childTag = child.getXmlTag(); |
| assertEquals("child", childTag.getName()); |
| assertEquals("foo", childTag.getNamespace()); |
| assertEquals("", childTag.getNamespacePrefix()); |
| assertNull(childTag.getAttributeValue("xmlns")); |
| |
| assertEquals("foo", element.getXmlElementNamespaceKey()); |
| assertNull(child.getXmlElementNamespaceKey()); |
| } |
| |
| public void testHardcodedNamespacePrefix() throws Throwable { |
| final XmlFile xmlFile = createXmlFile("<a xmlns:sys=\"\"/>"); |
| final MyElement element = getDomManager().getFileElement(xmlFile, MyElement.class, "a").getRootElement(); |
| final MyElement hardcodedElement = element.getHardcodedElement(); |
| new WriteCommandAction(getProject()) { |
| @Override |
| protected void run(Result result) throws Throwable { |
| hardcodedElement.ensureTagExists(); |
| } |
| }.execute(); |
| assertTrue(element.isValid()); |
| assertTrue(hardcodedElement.isValid()); |
| assertNotNull(hardcodedElement.getXmlElement()); |
| assertEquals("<sys:aaa/>", hardcodedElement.getXmlElement().getText()); |
| assertEquals("sys:aaa", hardcodedElement.getXmlTag().getName()); |
| |
| new WriteCommandAction(getProject()) { |
| @Override |
| protected void run(Result result) throws Throwable { |
| hardcodedElement.getHardcodedElement().getHardcodedElement().ensureTagExists(); |
| } |
| }.execute(); |
| |
| assertTrue(element.isValid()); |
| assertTrue(hardcodedElement.isValid()); |
| assertNotNull(hardcodedElement.getXmlElement()); |
| assertEquals("sys:aaa", hardcodedElement.getHardcodedElement().getHardcodedElement().getXmlTag().getName()); |
| |
| assertEquals(1, element.getXmlTag().getSubTags().length); |
| } |
| |
| public void testAutoChooseNamespaceIfPresent() throws Throwable { |
| final MyElement root = createElement("<a xmlns=\"foo\"/>", MyElement.class); |
| getDomManager().getDomFileDescription(root.getXmlElement()).registerNamespacePolicy("foo", "bar", "foo"); |
| |
| final XmlTag fooChildTag = root.getFooChild().ensureTagExists(); |
| assertEquals("foo-child", fooChildTag.getName()); |
| assertEquals("foo", fooChildTag.getNamespace()); |
| assertEquals("", fooChildTag.getNamespacePrefix()); |
| assertEquals(0, fooChildTag.getAttributes().length); |
| } |
| |
| public void testNonemptyRootTagPrefix() throws Throwable { |
| getDomManager().registerFileDescription(new DomFileDescription<MyFooElement>(MyFooElement.class, "a", "foons") { |
| |
| @Override |
| protected void initializeFileDescription() { |
| super.initializeFileDescription(); |
| registerNamespacePolicy("foo", "foons"); |
| } |
| }, getTestRootDisposable()); |
| |
| final XmlFile psiFile = createXmlFile("<f:a xmlns:f=\"foons\"/>"); |
| final DomFileElementImpl<MyFooElement> element = getDomManager().getFileElement(psiFile, MyFooElement.class); |
| assertNotNull(element); |
| |
| final MyFooElement root = element.getRootElement(); |
| assertNotNull(root); |
| assertSame(psiFile.getDocument().getRootTag(), root.getXmlElement()); |
| } |
| |
| public void testSpringAopLike() throws Throwable { |
| getDomManager().registerFileDescription(new DomFileDescription<MyBeans>(MyBeans.class, "beans", "beans", "aop") { |
| |
| @Override |
| protected void initializeFileDescription() { |
| super.initializeFileDescription(); |
| registerNamespacePolicy("beans", "beans"); |
| registerNamespacePolicy("aop", "aop"); |
| } |
| }, getTestRootDisposable()); |
| |
| final XmlFile psiFile = createXmlFile("<beans xmlns=\"beans\" xmlns:aop=\"aop\">" + |
| "<aop:config>" + |
| "<aop:pointcut/>" + |
| "</aop:config>" + |
| "</beans>"); |
| final MyBeans beans = getDomManager().getFileElement(psiFile, MyBeans.class).getRootElement(); |
| final DomElement pointcut = |
| getDomManager().getDomElement(beans.getXmlTag().findFirstSubTag("aop:config").findFirstSubTag("aop:pointcut")); |
| assertNotNull(pointcut); |
| final MyAopConfig aopConfig = beans.getConfig(); |
| assertEquals(assertOneElement(aopConfig.getPointcuts()), pointcut); |
| } |
| |
| public void testSpringUtilLike() throws Throwable { |
| getDomManager().registerFileDescription(new DomFileDescription<MyBeans>(MyBeans.class, "beans", "beans", "util") { |
| |
| @Override |
| protected void initializeFileDescription() { |
| super.initializeFileDescription(); |
| registerNamespacePolicy("beans", "beans"); |
| registerNamespacePolicy("util", "util"); |
| } |
| }, getTestRootDisposable()); |
| |
| final XmlFile psiFile = createXmlFile("<beans xmlns=\"beans\" xmlns:util=\"util\">" + |
| "<util:list>" + |
| "<ref>aaa</ref>" + |
| "<util:child>bbb</util:child>" + |
| "</util:list></beans>"); |
| |
| final MyList listOrSet = assertInstanceOf(getDomManager().getFileElement(psiFile, MyBeans.class).getRootElement().getList(), MyList.class); |
| assertNotNull(listOrSet.getXmlTag()); |
| |
| final XmlTag listTag = psiFile.getDocument().getRootTag().findFirstSubTag("util:list"); |
| assertNotNull(getDomManager().getDomElement(listTag.findFirstSubTag("ref"))); |
| assertNotNull(getDomManager().getDomElement(listTag.findFirstSubTag("util:child"))); |
| |
| assertEquals("aaa", listOrSet.getRef().getValue()); |
| assertEquals("bbb", listOrSet.getChild().getValue()); |
| } |
| |
| private void registerNamespacePolicies(final MyElement element) { |
| registerNamespacePolicies(element, "foo", "bar"); |
| } |
| |
| private void registerNamespacePolicies(final MyElement element, final String foo, final String bar) { |
| final DomFileDescription description = getDomManager().getDomFileDescription(element.getXmlElement()); |
| description.registerNamespacePolicy("foo", foo); |
| description.registerNamespacePolicy("bar", bar); |
| } |
| |
| public void testFindChildDescriptionWithoutNamespace() throws Throwable { |
| final DomGenericInfo info = getDomManager().getGenericInfo(MyListOrSet.class); |
| assertNotNull(info.getAttributeChildDescription("attr")); |
| assertNotNull(info.getAttributeChildDescription("attr").getType()); |
| assertNotNull(info.getCollectionChildDescription("child")); |
| assertNotNull(info.getCollectionChildDescription("child").getType()); |
| assertNotNull(info.getFixedChildDescription("ref")); |
| assertNotNull(info.getFixedChildDescription("ref").getType()); |
| } |
| |
| public void testCopyFromHonorsNamespaces() throws Throwable { |
| final MyElement element = createElement("<a xmlns=\"foo\" xmlns:bar=\"bar\"/>", MyElement.class); |
| registerNamespacePolicies(element); |
| |
| final MyElement element2 = createElement("<f:a xmlns:f=\"foo1\" xmlns:b=\"bar1\" xmlns=\"foo1\">" + |
| "<foo-child/>" + |
| "<b:bar-child/>" + |
| "<f:some-child/>" + |
| "<f:foo-element attr-2=\"239\" attr=\"42\"/>" + |
| "<f:foo-element/>" + |
| "<f:bool/>" + |
| "<sys:aaa/>" + |
| "</f:a>", MyElement.class); |
| registerNamespacePolicies(element2, "foo1", "bar1"); |
| new WriteCommandAction(getProject()) { |
| @Override |
| protected void run(Result result) throws Throwable { |
| element.copyFrom(element2); |
| } |
| }.execute(); |
| |
| assertEquals("<a xmlns=\"foo\" xmlns:bar=\"bar\">" + |
| "<bar:bar-child/>" + |
| "<bool/>" + |
| "<foo-child/>" + |
| "<some-child/>" + |
| "<sys:aaa/>" + |
| "<foo-element attr=\"42\" attr-2=\"239\"/>" + |
| "<foo-element/>" + |
| "</a>", |
| element.getXmlTag().getText()); |
| } |
| |
| public void testAttributeWithAnotherNamespace() throws Throwable { |
| final MyElement element = createElement("<a xmlns=\"foo\" xmlns:bar=\"bar\"><foo-child bar:my-attribute=\"xxx\"/></a>", MyElement.class); |
| registerNamespacePolicies(element); |
| final MyFooElement fooElement = element.getFooChild(); |
| final MyAttribute myAttribute = fooElement.getMyAttribute(); |
| assertNotNull(myAttribute.getXmlAttribute()); |
| assertEquals("xxx", myAttribute.getStringValue()); |
| } |
| |
| public interface MyElement extends DomElement { |
| MyFooElement getFooChild(); |
| MyBarElement getBarChild(); |
| |
| MyElement getSomeChild(); |
| |
| List<MyFooElement> getFooElements(); |
| MyFooElement addFooElement(); |
| |
| List<MyElement> getChildren(); |
| MyElement addChild(); |
| |
| GenericAttributeValue<String> getAttr(); |
| GenericAttributeValue<String> getAttr2(); |
| |
| @SubTag(indicator = true) |
| GenericDomValue<Boolean> getBool(); |
| |
| @SubTag("sys:aaa") |
| MyElement getHardcodedElement(); |
| } |
| |
| @Namespace("foo") |
| public interface MyFooElement extends MyElement { |
| MyAttribute getMyAttribute(); |
| } |
| |
| @Namespace("bar") |
| public interface MyBarElement extends MyElement { |
| |
| } |
| |
| @Namespace("bar") |
| public interface MyAttribute extends GenericAttributeValue<String> { |
| |
| } |
| |
| @Namespace("beans") |
| public interface MyBeans extends DomElement { |
| MyAopConfig getConfig(); |
| MyList getList(); |
| } |
| |
| @Namespace("aop") |
| public interface MyAopConfig extends DomElement { |
| List<MySpringPointcut> getPointcuts(); |
| } |
| |
| @Namespace("aop") |
| public interface MySpringPointcut extends DomElement { |
| |
| } |
| |
| @Namespace("beans") |
| public interface MyListOrSet extends DomElement { |
| GenericDomValue<String> getRef(); |
| List<GenericDomValue<String>> getChildren(); |
| GenericAttributeValue<String> getAttr(); |
| } |
| |
| @Namespace("util") |
| public interface MyList extends MyListOrSet { |
| GenericDomValue<String> getChild(); |
| } |
| |
| |
| } |