blob: 8d92c019129fd205a6f1afe247f3617af3eeb83f [file] [log] [blame]
/*
* 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();
}
}