mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
dom-tests moved to community
This commit is contained in:
Generated
+1
@@ -36,6 +36,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/devkit/jps-plugin/devkit-jps-plugin.iml" filepath="$PROJECT_DIR$/plugins/devkit/jps-plugin/devkit-jps-plugin.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/xml/dom-impl/dom-impl.iml" filepath="$PROJECT_DIR$/xml/dom-impl/dom-impl.iml" group="xml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/xml/dom-openapi/dom-openapi.iml" filepath="$PROJECT_DIR$/xml/dom-openapi/dom-openapi.iml" group="xml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/xml/dom-tests/dom-tests.iml" filepath="$PROJECT_DIR$/xml/dom-tests/dom-tests.iml" group="xml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/eclipse/eclipse.iml" filepath="$PROJECT_DIR$/plugins/eclipse/eclipse.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/java/execution/impl/execution-impl.iml" filepath="$PROJECT_DIR$/java/execution/impl/execution-impl.iml" group="java" />
|
||||
<module fileurl="file://$PROJECT_DIR$/java/execution/openapi/execution-openapi.iml" filepath="$PROJECT_DIR$/java/execution/openapi/execution-openapi.iml" group="java" />
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
<orderEntry type="module" module-name="gradle" />
|
||||
<orderEntry type="module" module-name="rearranger" />
|
||||
<orderEntry type="module" module-name="xml-tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="dom-tests" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="dom-impl" />
|
||||
<orderEntry type="library" name="CGLIB" level="project" />
|
||||
<orderEntry type="module" module-name="xml" />
|
||||
<orderEntry type="module" module-name="testFramework-java" />
|
||||
<orderEntry type="module" module-name="java-psi-impl" />
|
||||
<orderEntry type="module" module-name="java-impl" scope="TEST" />
|
||||
</component>
|
||||
<component name="copyright">
|
||||
<Base>
|
||||
<setting name="state" value="1" />
|
||||
</Base>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<foo/>
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.util.xml.converters.DelimitedListProcessor;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
*/
|
||||
public class DelimitedListProcessorTest extends TestCase {
|
||||
|
||||
public void testProcessor() {
|
||||
doTest("a; ; ", Arrays.asList("a", " ", " "));
|
||||
}
|
||||
|
||||
private void doTest(final String text, final List<String> expected) {
|
||||
final ArrayList<String> tokens = new ArrayList<String>();
|
||||
new DelimitedListProcessor(";") {
|
||||
@Override
|
||||
protected void processToken(final int start, final int end, final boolean delimitersOnly) {
|
||||
tokens.add(text.substring(start, end));
|
||||
}
|
||||
}.processText(text);
|
||||
assertEquals(expected, tokens);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xml.highlighting.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomAnnotationsTest extends DomTestCase{
|
||||
|
||||
@Override
|
||||
protected <T extends DomElement> T createElement(final String xml, final Class<T> aClass) {
|
||||
final String name = "a.xml";
|
||||
final XmlFile file = (XmlFile)PsiFileFactory.getInstance(getProject()).createFileFromText(name, StdFileTypes.XML, xml, 0,
|
||||
true);
|
||||
final XmlTag tag = file.getDocument().getRootTag();
|
||||
final String rootTagName = tag != null ? tag.getName() : "root";
|
||||
final T element = getDomManager().getFileElement(file, aClass, rootTagName).getRootElement();
|
||||
assertNotNull(element);
|
||||
assertSame(tag, element.getXmlTag());
|
||||
return element;
|
||||
}
|
||||
|
||||
public void testResolveProblemsAreReportedOnlyOnce() throws Throwable {
|
||||
final MyElement myElement = createElement("<a><my-class>abc</my-class></a>", MyElement.class);
|
||||
|
||||
new MockDomInspection(MyElement.class).checkFile(DomUtil.getFile(myElement), InspectionManager.getInstance(getProject()), true);
|
||||
final DomElementsProblemsHolder holder = DomElementAnnotationsManager.getInstance(getProject()).getProblemHolder(myElement);
|
||||
|
||||
final DomElement element = myElement.getMyClass();
|
||||
assertEquals(0, holder.getProblems(myElement).size());
|
||||
assertEquals(0, holder.getProblems(myElement).size());
|
||||
assertEquals(1, holder.getProblems(element).size());
|
||||
assertEquals(1, holder.getProblems(element).size());
|
||||
assertEquals(1, holder.getProblems(myElement, true, true).size());
|
||||
assertEquals(1, holder.getProblems(myElement, true, true).size());
|
||||
}
|
||||
|
||||
public void testMinSeverity() throws Throwable {
|
||||
final MyElement element = createElement("<a/>", MyElement.class);
|
||||
final DomElementsProblemsHolderImpl holder = new DomElementsProblemsHolderImpl(DomUtil.getFileElement(element));
|
||||
final DomElementProblemDescriptorImpl error = new DomElementProblemDescriptorImpl(element, "abc", HighlightSeverity.ERROR);
|
||||
final DomElementProblemDescriptorImpl warning = new DomElementProblemDescriptorImpl(element, "abc", HighlightSeverity.WARNING);
|
||||
holder.addProblem(error, MockDomInspection.class);
|
||||
holder.addProblem(warning, MockDomInspection.class);
|
||||
assertEquals(Arrays.asList(error), holder.getProblems(element, true, true, HighlightSeverity.ERROR));
|
||||
assertEquals(Arrays.asList(error, warning), holder.getProblems(element, true, true, HighlightSeverity.WARNING));
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement{
|
||||
GenericDomValue<PsiClass> getMyClass();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,606 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.mock.MockModule;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.Factory;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
import com.intellij.util.xml.impl.*;
|
||||
import com.intellij.util.xml.reflect.DomAttributeChildDescription;
|
||||
import com.intellij.util.xml.reflect.DomCollectionChildDescription;
|
||||
import com.intellij.util.xml.reflect.DomFixedChildDescription;
|
||||
import com.intellij.util.xml.reflect.DomGenericInfo;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomBasicsTest extends DomTestCase {
|
||||
@Override
|
||||
protected void invokeTestRunnable(final Runnable runnable) throws Exception {
|
||||
new WriteCommandAction.Simple(null) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
runnable.run();
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testFileElementCaching() throws Throwable {
|
||||
final XmlFile file = createXmlFile("<a/>");
|
||||
final DomManagerImpl manager = getDomManager();
|
||||
final DomFileElementImpl<DomElement> fileElement = manager.getFileElement(file, DomElement.class, "a");
|
||||
assertEquals(fileElement, manager.getFileElement(file, DomElement.class, "a"));
|
||||
assertCached(fileElement, file);
|
||||
|
||||
assertEquals(fileElement.getRootElement(), fileElement.getRootElement());
|
||||
}
|
||||
|
||||
public void testElementCaching() throws Throwable {
|
||||
final MyElement element = createElement("<a><child/></a>");
|
||||
assertSame(element.getChild(), element.getChild());
|
||||
assertSame(element.getXmlTag().getSubTags()[0], element.getChild().getXmlTag());
|
||||
assertCached(element.getChild(), element.getChild().getXmlTag());
|
||||
}
|
||||
|
||||
public void testGetParentAndRoot() throws Throwable {
|
||||
final XmlFile file = createXmlFile("<a><foo/><child-element/><child-element/></a>");
|
||||
final DomFileElementImpl<MyElement> fileElement = getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
assertNull(fileElement.getParent());
|
||||
assertSame(fileElement, DomUtil.getFileElement(fileElement));
|
||||
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
assertSame(fileElement, rootElement.getParent());
|
||||
assertSame(fileElement, DomUtil.getFileElement(rootElement));
|
||||
|
||||
assertParent(rootElement.getFoo(), rootElement);
|
||||
assertParent(rootElement.getChildElements().get(0), rootElement);
|
||||
assertParent(rootElement.getChildElements().get(1), rootElement);
|
||||
}
|
||||
|
||||
private static void assertParent(final DomElement element, final DomElement parent) {
|
||||
assertEquals(parent, element.getParent());
|
||||
}
|
||||
|
||||
public void testEnsureTagExists() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
myCallRegistry.clear();
|
||||
final MyElement child = element.getChild();
|
||||
assertNull(child.getXmlTag());
|
||||
|
||||
child.ensureTagExists();
|
||||
final XmlTag[] subTags = element.getXmlTag().getSubTags();
|
||||
assertEquals(1, subTags.length);
|
||||
final XmlTag childTag = subTags[0];
|
||||
assertEquals("child", childTag.getName());
|
||||
assertCached(child, childTag);
|
||||
assertSame(child.getXmlTag(), childTag);
|
||||
|
||||
final DomElement element1 = child;
|
||||
myCallRegistry.putExpected(new DomEvent(element1, true));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
|
||||
final MyElement childElement = element.addChildElement();
|
||||
final XmlTag childElementTag = childElement.getXmlTag();
|
||||
assertSame(childElementTag, childElement.ensureTagExists());
|
||||
}
|
||||
|
||||
public void testEnsureRootTagExists() throws Throwable {
|
||||
final MyElement rootElement = createEmptyElement();
|
||||
myCallRegistry.clear();
|
||||
assertNull(rootElement.getXmlTag());
|
||||
rootElement.ensureTagExists();
|
||||
final DomElement element = rootElement;
|
||||
myCallRegistry.putExpected(new DomEvent(element, true));
|
||||
|
||||
assertCached(rootElement, assertRootTag(rootElement));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
}
|
||||
|
||||
private XmlTag assertRootTag(final DomElement rootElement) {
|
||||
return assertRootTag(DomUtil.getFile(rootElement));
|
||||
}
|
||||
|
||||
private static XmlTag assertRootTag(final XmlFile file) {
|
||||
final XmlTag rootTag = file.getDocument().getRootTag();
|
||||
assertNotNull(rootTag);
|
||||
assertEquals("root", rootTag.getName());
|
||||
return rootTag;
|
||||
}
|
||||
|
||||
protected MyElement createEmptyElement() throws IncorrectOperationException {
|
||||
final XmlFile file = createXmlFile("");
|
||||
return getDomManager().getFileElement(file, MyElement.class, "root").getRootElement();
|
||||
}
|
||||
|
||||
public void testFile() throws Throwable {
|
||||
final XmlFile file = createXmlFile("<a>foo</a>");
|
||||
DomFileElementImpl<MyElement> fileElement = getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
assertNotNull(rootElement);
|
||||
assertEquals("foo", rootElement.getValue());
|
||||
}
|
||||
|
||||
public void testAcceptChidren() throws Throwable {
|
||||
final MyElement element = createElement("<a><child-element/><child/><child-element/></a>");
|
||||
final Set<DomElement> visited = new HashSet<DomElement>();
|
||||
element.acceptChildren(new DomElementVisitor() {
|
||||
@Override
|
||||
public void visitDomElement(DomElement element) {
|
||||
visited.add(element);
|
||||
}
|
||||
});
|
||||
final MyElement foo = element.getFoo();
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child1 = element.getChildElements().get(0);
|
||||
final MyElement child2 = element.getChildElements().get(1);
|
||||
final GenericDomValue<Boolean> genericValue = element.getGenericValue();
|
||||
assertSameElements(visited, foo, child, child1, child2, genericValue, element.getAttr());
|
||||
}
|
||||
|
||||
public void testChildrenReflection() throws Throwable {
|
||||
final MyElement element =
|
||||
createElement("<a><child/><child-element/><child-element/></a>");
|
||||
final DomGenericInfo info = element.getGenericInfo();
|
||||
|
||||
final DomFixedChildDescription foo = info.getFixedChildDescription("foo");
|
||||
assertFixedChildDescription(foo, element.getFoo(), "foo");
|
||||
|
||||
final DomFixedChildDescription child = info.getFixedChildDescription("child");
|
||||
assertFixedChildDescription(child, element.getChild(), "child");
|
||||
|
||||
final DomFixedChildDescription genericChild = info.getFixedChildDescription("generic-value");
|
||||
assertGenericChildDescription(genericChild, element.getGenericValue(), "generic-value");
|
||||
|
||||
final DomCollectionChildDescription collectionChild = info.getCollectionChildDescription("child-element");
|
||||
assertEquals(element.getChildElements(), collectionChild.getValues(element));
|
||||
assertEquals("child-element", collectionChild.getXmlElementName());
|
||||
assertEquals(MyElement.class, collectionChild.getType());
|
||||
assertEquals(MyElement.class.getMethod("getChildElements"), collectionChild.getGetterMethod().getMethod());
|
||||
|
||||
assertEquals(new HashSet(Arrays.asList(foo, child, collectionChild, genericChild,
|
||||
info.getAttributeChildrenDescriptions().get(0))),
|
||||
new HashSet(info.getChildrenDescriptions()));
|
||||
}
|
||||
|
||||
private void assertFixedChildDescription(final DomFixedChildDescription description,
|
||||
final DomElement child,
|
||||
final String tagName) throws NoSuchMethodException {
|
||||
assertEquals(1, description.getCount());
|
||||
assertEquals(Arrays.asList(child), description.getValues(child.getParent()));
|
||||
assertEquals(tagName, description.getXmlElementName());
|
||||
assertEquals(MyElement.class, description.getType());
|
||||
assertEquals(JavaMethod.getMethod(MyElement.class, new JavaMethodSignature("get" + StringUtil.capitalize(tagName))), description.getGetterMethod(0));
|
||||
}
|
||||
|
||||
private static void assertGenericChildDescription(final DomFixedChildDescription description,
|
||||
final DomElement child,
|
||||
final String tagName) throws NoSuchMethodException {
|
||||
assertEquals(1, description.getCount());
|
||||
assertEquals(Arrays.asList(child), description.getValues(child.getParent()));
|
||||
assertEquals(tagName, description.getXmlElementName());
|
||||
assertEquals(GenericDomValue.class, ((ParameterizedType)description.getType()).getRawType());
|
||||
assertEquals(JavaMethod.getMethod(MyElement.class, new JavaMethodSignature("getGenericValue")), description.getGetterMethod(0));
|
||||
}
|
||||
|
||||
public void testGetDomElementType() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
assertEquals(MyElement.class.getMethod("getGenericValue").getGenericReturnType(), element.getGenericValue().getDomElementType());
|
||||
}
|
||||
|
||||
public void testAddChildrenByReflection() throws Throwable {
|
||||
final MyElement element =
|
||||
createElement("<a><child-element/></a>");
|
||||
final DomGenericInfo info = element.getGenericInfo();
|
||||
final DomCollectionChildDescription collectionChild = info.getCollectionChildDescription("child-element");
|
||||
final List<? extends DomElement> values = collectionChild.getValues(element);
|
||||
|
||||
MyElement newChild = (MyElement) collectionChild.addValue(element);
|
||||
List<DomElement> newChildren = Arrays.asList(values.get(0), newChild);
|
||||
assertEquals(newChildren, element.getChildElements());
|
||||
assertEquals(newChildren, collectionChild.getValues(element));
|
||||
|
||||
MyElement lastChild = (MyElement) collectionChild.addValue(element, 0);
|
||||
newChildren = Arrays.asList(lastChild, values.get(0), newChild);
|
||||
assertEquals(newChildren, element.getChildElements());
|
||||
assertEquals(newChildren, collectionChild.getValues(element));
|
||||
}
|
||||
|
||||
public void testGetPresentableName() throws Throwable {
|
||||
assertCollectionPresentableName("Aaas", "aaa", DomNameStrategy.HYPHEN_STRATEGY);
|
||||
assertCollectionPresentableName("Aaa Bbbs", "aaa-bbb", DomNameStrategy.HYPHEN_STRATEGY);
|
||||
|
||||
assertCollectionPresentableName("Aaas", "aaa", DomNameStrategy.JAVA_STRATEGY);
|
||||
assertCollectionPresentableName("Aaa Children", "aaaChild", DomNameStrategy.JAVA_STRATEGY);
|
||||
|
||||
assertFixedPresentableName("Aaa Bbbs", "aaa-bbbs", DomNameStrategy.HYPHEN_STRATEGY);
|
||||
assertFixedPresentableName("Aaa Child", "aaaChild", DomNameStrategy.JAVA_STRATEGY);
|
||||
}
|
||||
|
||||
private void assertCollectionPresentableName(final String expected, final String tagName, final DomNameStrategy strategy) {
|
||||
assertEquals(expected, new CollectionChildDescriptionImpl(new XmlName(tagName), DomElement.class, null).getCommonPresentableName(strategy));
|
||||
}
|
||||
|
||||
private void assertFixedPresentableName(final String expected, final String tagName, final DomNameStrategy strategy) {
|
||||
assertEquals(expected, new FixedChildDescriptionImpl(new XmlName(tagName), DomElement.class, 0, new Collection[0]).getCommonPresentableName(strategy));
|
||||
}
|
||||
|
||||
public void testNameStrategy() throws Throwable {
|
||||
assertTrue(createElement("<a/>").getNameStrategy() instanceof HyphenNameStrategy);
|
||||
|
||||
final AnotherElement anotherElement = createElement("<a/>", AnotherElement.class);
|
||||
assertTrue(anotherElement.getNameStrategy() instanceof JavaNameStrategy);
|
||||
assertTrue(anotherElement.getChild().getNameStrategy() instanceof JavaNameStrategy);
|
||||
}
|
||||
|
||||
public void testModificationCount() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
final long count = DomUtil.getFileElement(element).getModificationCount();
|
||||
element.addChildElement();
|
||||
assertTrue(DomUtil.getFileElement(element).getModificationCount() > count);
|
||||
}
|
||||
|
||||
public void testIsTagValueElement() throws Throwable {
|
||||
assertTrue(getDomManager().getGenericInfo(MyElement.class).isTagValueElement());
|
||||
assertFalse(getDomManager().getGenericInfo(AnotherElement.class).isTagValueElement());
|
||||
}
|
||||
|
||||
public void testAttributeChildrenGenerics() throws Throwable {
|
||||
final StaticGenericInfo genericInfo = DomApplicationComponent.getInstance().getStaticGenericInfo(MyElement.class);
|
||||
final List<? extends DomAttributeChildDescription> descriptions = genericInfo.getAttributeChildrenDescriptions();
|
||||
assertEquals(1, descriptions.size());
|
||||
final DomAttributeChildDescription description = descriptions.get(0);
|
||||
|
||||
final MyElement element = createElement("");
|
||||
assertEquals(element.getAttr(), description.getValues(element).get(0));
|
||||
assertEquals(element.getAttr(), description.getDomAttributeValue(element));
|
||||
}
|
||||
|
||||
private MyElement createElement(final String xml) throws IncorrectOperationException {
|
||||
return createElement(xml, MyElement.class);
|
||||
}
|
||||
|
||||
public void testSubPropertyAccessing() throws Throwable {
|
||||
final MyElement element = createElement("");
|
||||
final GenericAttributeValue<String> attr = element.getChild().getChild().getAttr();
|
||||
assertNotNull(attr);
|
||||
assertEquals(element.getChildChildAttr(), attr);
|
||||
|
||||
final GenericAttributeValue<String> attr1 = element.getChild().addChildElement().getAttr();
|
||||
final GenericAttributeValue<String> attr2 = element.getChild().addChildElement().getAttr();
|
||||
assertOrderedEquals(element.getChildChildrenAttr(), attr1, attr2);
|
||||
}
|
||||
|
||||
public void testInstanceImplementation() throws Throwable {
|
||||
MyElement element = createElement("");
|
||||
final Object o = new Object();
|
||||
element.setObject(o);
|
||||
assertSame(o, element.getObject());
|
||||
|
||||
element = createElement("", InheritedElement.class);
|
||||
element.setObject(o);
|
||||
assertSame(o, element.getObject());
|
||||
assertSame(o, element.getObject());
|
||||
}
|
||||
|
||||
public void testSeveralInstanceImplementations() throws Throwable {
|
||||
InheritedElement element = createElement("", InheritedElement.class);
|
||||
final Object o = new Object();
|
||||
element.setObject(o);
|
||||
assertSame(o, element.getObject());
|
||||
assertSame(o, element._getObject());
|
||||
element.setString("foo");
|
||||
assertEquals("foo", element.getString());
|
||||
}
|
||||
|
||||
public void testVisitor() throws Throwable {
|
||||
final Integer[] visits = new Integer[]{0, 0, 0};
|
||||
DomElementVisitor visitor = new MyVisitor() {
|
||||
@Override
|
||||
public void visit(InheritedElement element) {
|
||||
visits[0]++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDomElement(DomElement element) {
|
||||
visits[1]++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMyElement(MyElement element) {
|
||||
visits[2]++;
|
||||
}
|
||||
};
|
||||
|
||||
createElement("", MyElement.class).accept(visitor);
|
||||
final List<Integer> visitsList = Arrays.asList(visits);
|
||||
assertEquals(Arrays.asList(0, 0, 1), visitsList);
|
||||
|
||||
createElement("", InheritedElement.class).accept(visitor);
|
||||
assertEquals(Arrays.asList(1, 0, 1), visitsList);
|
||||
|
||||
createElement("", AnotherElement.class).accept(visitor);
|
||||
assertEquals(Arrays.asList(1, 1, 1), visitsList);
|
||||
|
||||
createElement("", DomElement.class).accept(visitor);
|
||||
assertEquals(Arrays.asList(1, 2, 1), visitsList);
|
||||
|
||||
createElement("", InheritedElement.class).accept(new DomElementVisitor() {
|
||||
@Override
|
||||
public void visitDomElement(DomElement element) {
|
||||
visits[1]++;
|
||||
}
|
||||
});
|
||||
assertEquals(Arrays.asList(1, 3, 1), visitsList);
|
||||
}
|
||||
|
||||
public void testRegisteringImplementation() throws Throwable {
|
||||
DomApplicationComponent.getInstance().registerImplementation(AnotherElement.class, EmptyImpl.class, getTestRootDisposable());
|
||||
DomApplicationComponent.getInstance().registerImplementation(DomElement.class, BaseImpl.class, getTestRootDisposable());
|
||||
final AnotherElement element = createElement("", AnotherElement.class);
|
||||
assertTrue(element.getClass().getSuperclass().getName(), element instanceof EmptyImpl);
|
||||
}
|
||||
|
||||
public void testMockElements() throws Throwable {
|
||||
Module module = new MockModule(getTestRootDisposable());
|
||||
final MyElement element = getDomManager().createMockElement(MyElement.class, module, false);
|
||||
assertSame(module, element.getModule());
|
||||
assertTrue(element.isValid());
|
||||
assertNull(element.getXmlTag());
|
||||
assertEquals(element, DomUtil.getFileElement(element).getRootElement());
|
||||
assertFalse(DomUtil.getFile(element).isPhysical());
|
||||
|
||||
final MyElement element2 = getDomManager().createMockElement(MyElement.class, null, false);
|
||||
assertNull(element2.getModule());
|
||||
assertNull(element2.getXmlTag());
|
||||
element2.addChildElement().getGenericValue().setStringValue("xxx");
|
||||
assertNotNull(element2.getXmlTag());
|
||||
final MyElement oldChild = element2.getChild();
|
||||
|
||||
element.getAttr().setValue("attr");
|
||||
element.getGenericValue().setValue(Boolean.TRUE);
|
||||
element.getChild().getGenericValue().setStringValue("abc");
|
||||
element.addChildElement().getGenericValue().setStringValue("def");
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
element2.copyFrom(element);
|
||||
}
|
||||
}.execute();
|
||||
assertEquals("attr", element2.getAttr().getValue());
|
||||
assertEquals("true", element2.getGenericValue().getStringValue());
|
||||
|
||||
final MyElement newChild = element2.getChild();
|
||||
assertEquals("abc", newChild.getGenericValue().getStringValue());
|
||||
|
||||
final List<MyElement> childElements = element2.getChildElements();
|
||||
assertEquals(1, childElements.size());
|
||||
assertEquals("def", childElements.get(0).getGenericValue().getStringValue());
|
||||
}
|
||||
|
||||
public void testCopyingFromEmptyToEmpty() throws Throwable {
|
||||
Module module = new MockModule(getTestRootDisposable());
|
||||
MyElement element1 = getDomManager().createMockElement(MyElement.class, module, false);
|
||||
MyElement element2 = getDomManager().createMockElement(MyElement.class, module, false);
|
||||
element2.copyFrom(element1);
|
||||
assertNull(element2.getXmlTag());
|
||||
}
|
||||
|
||||
public void testCopyingFromNonEmptyToEmpty() throws Throwable {
|
||||
Module module = new MockModule(getTestRootDisposable());
|
||||
final MyElement element1 = getDomManager().createMockElement(MyElement.class, module, false);
|
||||
final MyElement element2 = getDomManager().createMockElement(MyElement.class, module, false);
|
||||
element2.ensureTagExists();
|
||||
assertNull(element2.getChild().getChild().getGenericValue().getStringValue());
|
||||
element1.getChild().getChild().getGenericValue().setStringValue("abc");
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
element2.copyFrom(element1);
|
||||
}
|
||||
}.execute();
|
||||
assertEquals("abc", element2.getChild().getChild().getGenericValue().getStringValue());
|
||||
}
|
||||
|
||||
public void testStableValues() throws Throwable {
|
||||
final MyElement[] element = new MyElement[]{null};
|
||||
final MyElement stable = getDomManager().createStableValue(new Factory<MyElement>() {
|
||||
@Override
|
||||
public MyElement create() {
|
||||
try {
|
||||
return element[0] = createElement("<root/>").addChildElement();
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
assertNotNull(element[0]);
|
||||
assertSame(element[0], ((StableElement)stable).getWrappedElement());
|
||||
assertEquals(element[0], stable);
|
||||
assertEquals(stable, element[0]);
|
||||
MyElement oldElement = element[0];
|
||||
assertFalse(stable.getChild().equals(stable));
|
||||
final GenericDomValue<Boolean> oldGenericValue = stable.getGenericValue();
|
||||
assertEquals(oldGenericValue, oldElement.getGenericValue());
|
||||
assertEquals(stable.getChild(), oldElement.getChild());
|
||||
assertSame(element[0], oldElement);
|
||||
final MyElement child1 = stable.addChildElement();
|
||||
final MyElement child2 = stable.addChildElement();
|
||||
|
||||
MyElement oldChild1 = oldElement.getChildElements().get(0);
|
||||
assertEquals(oldChild1, child1);
|
||||
assertEquals(child1, oldChild1);
|
||||
final MyElement oldElement1 = oldElement;
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
oldElement1.undefine();
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(oldChild1.isValid());
|
||||
|
||||
assertFalse(oldElement.isValid());
|
||||
assertFalse(element[0].isValid());
|
||||
assertTrue(stable.isValid());
|
||||
assertTrue(element[0].isValid());
|
||||
assertNotSame(element[0], oldElement);
|
||||
|
||||
assertFalse(child1.isValid());
|
||||
assertFalse(child2.isValid());
|
||||
assertEquals(DomUtil.getFileElement(element[0]), DomUtil.getFileElement(stable));
|
||||
assertEquals(element[0].getParent(), stable.getParent());
|
||||
|
||||
oldElement = element[0];
|
||||
oldChild1 = oldElement.getChild();
|
||||
((StableElement)stable).invalidate();
|
||||
assertTrue(oldElement.isValid());
|
||||
assertTrue(oldChild1.isValid());
|
||||
assertFalse(oldElement.equals(((StableElement)stable).getWrappedElement()));
|
||||
}
|
||||
|
||||
public void testStable_Revalidate() throws Throwable {
|
||||
final MyElement[] element = new MyElement[]{createElement("")};
|
||||
final MyElement stable = getDomManager().createStableValue(new Factory<MyElement>() {
|
||||
@Override
|
||||
public MyElement create() {
|
||||
return element[0];
|
||||
}
|
||||
});
|
||||
MyElement oldElement = element[0];
|
||||
((StableElement) stable).revalidate();
|
||||
assertSame(oldElement, ((StableElement) stable).getWrappedElement());
|
||||
|
||||
element[0] = createElement("");
|
||||
assertTrue(oldElement.isValid());
|
||||
((StableElement) stable).revalidate();
|
||||
assertTrue(oldElement.isValid());
|
||||
assertNotSame(oldElement, ((StableElement) stable).getWrappedElement());
|
||||
assertSame(element[0], ((StableElement) stable).getWrappedElement());
|
||||
}
|
||||
|
||||
public void testStable_Invalidate() throws Throwable {
|
||||
final MyElement oldElement = createElement("");
|
||||
final MyElement[] element = new MyElement[]{oldElement};
|
||||
final MyElement stable = getDomManager().createStableValue(new Factory<MyElement>() {
|
||||
@Override
|
||||
public MyElement create() {
|
||||
return element[0];
|
||||
}
|
||||
});
|
||||
element[0] = null;
|
||||
((StableElement) stable).invalidate();
|
||||
assertTrue(stable.equals(stable));
|
||||
assertEquals(oldElement.toString(), stable.toString());
|
||||
}
|
||||
|
||||
public void testStableCopies() throws Throwable {
|
||||
final MyElement element = createElement("<a><child-element/><child-element><child/></child-element></a>");
|
||||
final MyElement parent = element.getChildElements().get(1);
|
||||
final MyElement child = parent.getChild();
|
||||
final MyElement copy = (MyElement) child.createStableCopy();
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
parent.undefine();
|
||||
element.addChildElement().getChild().ensureXmlElementExists();
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(child.isValid());
|
||||
assertTrue(copy.isValid());
|
||||
}
|
||||
|
||||
@Implementation(Impl.class)
|
||||
public interface MyElement extends DomElement {
|
||||
GenericAttributeValue<String> getAttr();
|
||||
|
||||
String getValue();
|
||||
|
||||
MyElement getFoo();
|
||||
|
||||
MyElement getChild();
|
||||
MyElement addChildElement();
|
||||
@SuppressWarnings({"UnusedDeclaration"})
|
||||
MyElement addChildElement(int index);
|
||||
|
||||
List<MyElement> getChildElements();
|
||||
|
||||
GenericDomValue<Boolean> getGenericValue();
|
||||
|
||||
Object getObject();
|
||||
|
||||
void setObject(Object o);
|
||||
|
||||
@PropertyAccessor({"child", "child", "attr"})
|
||||
GenericAttributeValue<String> getChildChildAttr();
|
||||
|
||||
@PropertyAccessor({"child", "childElements", "attr"})
|
||||
List<GenericAttributeValue<String>> getChildChildrenAttr();
|
||||
|
||||
}
|
||||
|
||||
public static abstract class Impl implements MyElement {
|
||||
private Object myObject;
|
||||
|
||||
public Object _getObject() {
|
||||
return myObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() {
|
||||
return myObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setObject(final Object object) {
|
||||
myObject = object;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static abstract class AnotherImpl extends Impl implements InheritedElement{
|
||||
private String myString;
|
||||
|
||||
@Override
|
||||
public String getString() {
|
||||
return myString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setString(final String string) {
|
||||
myString = string;
|
||||
}
|
||||
}
|
||||
|
||||
@NameStrategy(JavaNameStrategy.class)
|
||||
public interface AnotherElement extends DomElement {
|
||||
DomElement getChild();
|
||||
}
|
||||
|
||||
public static abstract class BaseImpl implements DomElement{}
|
||||
|
||||
public static abstract class EmptyImpl extends BaseImpl implements AnotherElement{}
|
||||
|
||||
@Implementation(AnotherImpl.class)
|
||||
public interface InheritedElement extends MyElement, DomElement {
|
||||
String getString();
|
||||
|
||||
void setString(final String string);
|
||||
|
||||
Object _getObject();
|
||||
}
|
||||
|
||||
public interface MyVisitor extends DomElementVisitor{
|
||||
void visitMyElement(MyElement element);
|
||||
void visit(InheritedElement element);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,614 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomChildrenTest extends DomTestCase {
|
||||
|
||||
private MyElement createElement(final String xml) throws IncorrectOperationException {
|
||||
return createElement(xml, MyElement.class);
|
||||
}
|
||||
|
||||
public void testGetChild() throws Throwable {
|
||||
final MyElement element = createElement("<a>" + "<child>foo</child>" + "</a>");
|
||||
element.toString();
|
||||
assertEquals("foo", element.getMyChild().getValue());
|
||||
assertEquals("foo", element.getChild().getValue());
|
||||
assertSame(element.getChild(), element.getMyChild());
|
||||
assertNull(element.getChild239().getXmlTag());
|
||||
}
|
||||
|
||||
public void testGetChild239() throws Throwable {
|
||||
final MyElement element = createElement("<a><child/><child-239/></a>");
|
||||
assertNotNull(element.getChild239().getXmlTag());
|
||||
}
|
||||
|
||||
public void testGetChildren() throws Throwable {
|
||||
final MyElement element = createElement("<a>" + "<child-element>foo</child-element>" + "<child-element>bar</child-element>" + "</a>");
|
||||
assertSubBars(element.getMyChildren());
|
||||
assertSubBars(element.getChildElements());
|
||||
assertSubBars(element.getMyChildren2());
|
||||
}
|
||||
|
||||
public void testGetChildrenMultipleTimes() throws Throwable {
|
||||
final MyElement element = createElement("<a>" + "<child-element>" + " <child-element/>" + "</child-element>" + "</a>");
|
||||
for (int i = 0; i < 239; i++) {
|
||||
final List<MyElement> children = element.getChildElements();
|
||||
final MyElement child = children.get(0);
|
||||
final List<MyElement> children1 = child.getChildElements();
|
||||
final MyElement child1 = children1.get(0);
|
||||
assertNotNull(child1.getChild());
|
||||
}
|
||||
}
|
||||
|
||||
private void assertSubBars(final List<? extends MyElement> subBars) {
|
||||
assertEquals(2, subBars.size());
|
||||
assertEquals("foo", subBars.get(0).getValue());
|
||||
assertEquals("bar", subBars.get(1).getValue());
|
||||
}
|
||||
|
||||
public void testClassChoosers() throws Throwable {
|
||||
getTypeChooserManager().registerTypeChooser(MyAbstractElement.class, new MyTypeChooser());
|
||||
try {
|
||||
MyElement element = createElement("<a>" +
|
||||
"<abstract-child>Foo</abstract-child>" +
|
||||
"<abstract-element>Foo</abstract-element>" +
|
||||
"<abstract-element>bar</abstract-element>" + "</a>");
|
||||
assertFalse(element.getAbstractChild()instanceof MyBarConcreteElement);
|
||||
final List<MyAbstractElement> abstractElements = element.getAbstractElements();
|
||||
assertTrue(abstractElements.get(0)instanceof MyFooConcreteElement);
|
||||
assertTrue(abstractElements.get(1)instanceof MyBarConcreteElement);
|
||||
}
|
||||
finally {
|
||||
getTypeChooserManager().unregisterTypeChooser(MyAbstractElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAddConcreteElements() throws Throwable {
|
||||
getTypeChooserManager().registerTypeChooser(MyAbstractElement.class, new MyTypeChooser());
|
||||
try {
|
||||
MyElement element = createElement("<a/>");
|
||||
element.addBarChild();
|
||||
element.addFooChild();
|
||||
element.addAbstractElement(MyFooConcreteElement.class);
|
||||
element.addAbstractElement(MyFooConcreteElement.class, 1);
|
||||
element.addAbstractElement(2, MyBarConcreteElement.class);
|
||||
Class[] classes = new Class[]{MyBarConcreteElement.class, MyFooConcreteElement.class, MyBarConcreteElement.class,
|
||||
MyFooConcreteElement.class, MyFooConcreteElement.class};
|
||||
final List<MyAbstractElement> abstractElements = element.getAbstractElements();
|
||||
for (int i = 0; i < abstractElements.size(); i++) {
|
||||
MyAbstractElement abstractElement = abstractElements.get(i);
|
||||
assertTrue(String.valueOf(i) + " " + abstractElement.getClass(), classes[i].isInstance(abstractElement));
|
||||
assertEquals(String.valueOf(i), classes[i].getName(), abstractElement.getXmlTag().getAttributeValue("foo"));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
getTypeChooserManager().unregisterTypeChooser(MyAbstractElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
public void testIndexedChild() throws Throwable {
|
||||
MyElement element = createElement("<a>" + "<child>foo</child>" + "<child>bar</child>" + "</a>");
|
||||
assertCached(element.getChild2(), element.getXmlTag().getSubTags()[1]);
|
||||
assertEquals(0, element.getChildElements().size());
|
||||
}
|
||||
|
||||
public void testDefiningIndexedChild() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
final XmlTag tag = element.getChild2().ensureTagExists();
|
||||
final XmlTag[] subTags = element.getXmlTag().findSubTags("child");
|
||||
assertEquals(2, subTags.length);
|
||||
assertSame(tag, subTags[1]);
|
||||
|
||||
assertCached(element.getChild(), subTags[0]);
|
||||
final DomElement element1 = element.getChild();
|
||||
putExpected(new DomEvent(element1, true));
|
||||
final DomElement element2 = element.getChild().getAttr();
|
||||
putExpected(new DomEvent(element2, true));
|
||||
final DomElement element3 = element.getChild().isGenericValue();
|
||||
putExpected(new DomEvent(element3, true));
|
||||
final DomElement element4 = element.getChild2();
|
||||
putExpected(new DomEvent(element4, true));
|
||||
final DomElement element5 = element.getChild2().getAttr();
|
||||
putExpected(new DomEvent(element5, true));
|
||||
final DomElement element6 = element.getChild2().isGenericValue();
|
||||
putExpected(new DomEvent(element6, true));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAddChild() throws Throwable {
|
||||
final MyElement element = createElement("<a><child-element/></a>");
|
||||
assertEquals(1, element.getChildElements().size());
|
||||
final MyElement firstChild = element.getChildElements().get(0);
|
||||
final XmlTag firstChildTag = element.getXmlTag().findSubTags("child-element")[0];
|
||||
assertCached(firstChild, firstChildTag);
|
||||
|
||||
final MyElement child = element.addChildElement();
|
||||
assertEquals(Arrays.asList(firstChild, child), element.getChildElements());
|
||||
final XmlTag childTag = element.getXmlTag().findSubTags("child-element")[1];
|
||||
putExpected(new DomEvent(element, false));
|
||||
final DomElement element1 = child.getAttr();
|
||||
putExpected(new DomEvent(element1, true));
|
||||
final DomElement element2 = child.isGenericValue();
|
||||
putExpected(new DomEvent(element2, true));
|
||||
|
||||
final MyElement newChild = element.addChildElement(1);
|
||||
assertEquals(Arrays.asList(firstChild, newChild, child), element.getChildElements());
|
||||
final XmlTag newChildTag = element.getXmlTag().findSubTags("child-element")[1];
|
||||
putExpected(new DomEvent(element, false));
|
||||
final DomElement element3 = newChild.getAttr();
|
||||
putExpected(new DomEvent(element3, true));
|
||||
final DomElement element4 = newChild.isGenericValue();
|
||||
putExpected(new DomEvent(element4, true));
|
||||
|
||||
final MyElement lastChild = element.addChildElement(239);
|
||||
assertEquals(Arrays.asList(firstChild, newChild, child, lastChild), element.getChildElements());
|
||||
final XmlTag lastChildTag = element.getXmlTag().findSubTags("child-element")[3];
|
||||
putExpected(new DomEvent(element, false));
|
||||
final DomElement element5 = lastChild.getAttr();
|
||||
putExpected(new DomEvent(element5, true));
|
||||
final DomElement element6 = lastChild.isGenericValue();
|
||||
putExpected(new DomEvent(element6, true));
|
||||
assertResultsAndClear();
|
||||
|
||||
assertCached(firstChild, firstChildTag);
|
||||
assertCached(newChild, newChildTag);
|
||||
assertCached(child, childTag);
|
||||
assertCached(lastChild, lastChildTag);
|
||||
|
||||
assertSame(firstChildTag, element.getXmlTag().findSubTags("child-element")[0]);
|
||||
assertSame(newChildTag, element.getXmlTag().findSubTags("child-element")[1]);
|
||||
assertSame(childTag, element.getXmlTag().findSubTags("child-element")[2]);
|
||||
assertSame(lastChildTag, element.getXmlTag().findSubTags("child-element")[3]);
|
||||
}
|
||||
|
||||
public void testUndefineCollectionChild() throws Throwable {
|
||||
final MyElement element = createElement("<a><child-element/><child-element/><child-element/></a>");
|
||||
final MyElement child1 = element.getChildElements().get(0);
|
||||
final MyElement child2 = element.getChildElements().get(1);
|
||||
final MyElement child3 = element.getChildElements().get(2);
|
||||
|
||||
final List<XmlTag> oldChildren = new ArrayList<XmlTag>(Arrays.asList(element.getXmlTag().getSubTags()));
|
||||
|
||||
assertTrue(child2.isValid());
|
||||
assertEquals(element, child2.getParent());
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
child2.undefine();
|
||||
assertFalse(child2.isValid());
|
||||
|
||||
oldChildren.remove(1);
|
||||
assertEquals(oldChildren, Arrays.asList(element.getXmlTag().getSubTags()));
|
||||
|
||||
assertEquals(Arrays.asList(child1, child3), element.getChildElements());
|
||||
assertCached(child1, element.getXmlTag().findSubTags("child-element")[0]);
|
||||
assertCached(child3, element.getXmlTag().findSubTags("child-element")[1]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
myCallRegistry.putExpected(new DomEvent(element, false));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testUndefineFixedChild() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final MyElement child = createElement("<a><child/></a>").getChild();
|
||||
|
||||
incModCount();
|
||||
child.ensureTagExists();
|
||||
assertTrue(child.isValid());
|
||||
assertNotNull(child.getXmlElement());
|
||||
|
||||
incModCount();
|
||||
child.undefine();
|
||||
assertTrue(child.isValid());
|
||||
assertNull(child.getXmlElement());
|
||||
|
||||
child.ensureTagExists();
|
||||
incModCount();
|
||||
assertTrue(child.isValid());
|
||||
assertNotNull(child.getXmlElement());
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testAttributes() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
final GenericAttributeValue<String> attr = element.getAttr();
|
||||
assertSame(element.getXmlTag(), attr.getXmlTag());
|
||||
assertNull(attr.getValue());
|
||||
assertNull(attr.getXmlAttribute());
|
||||
|
||||
assertEquals(attr, element.getAttr());
|
||||
attr.setValue("239");
|
||||
assertEquals("239", attr.getValue());
|
||||
final XmlAttribute attribute = element.getXmlTag().getAttribute("attr", null);
|
||||
assertSame(attribute, attr.getXmlAttribute());
|
||||
assertSame(attribute, attr.getXmlElement());
|
||||
assertSame(attribute, attr.ensureXmlElementExists());
|
||||
assertSame(attribute.getValueElement(), attr.getXmlAttributeValue());
|
||||
|
||||
attr.setValue(null);
|
||||
assertFalse(attribute.isValid());
|
||||
assertNull(element.getXmlTag().getAttributeValue("attr"));
|
||||
assertNull(attr.getValue());
|
||||
assertNull(attr.getXmlAttribute());
|
||||
}
|
||||
|
||||
public void testUndefineLastFixedChildWithNotEmptyCollection() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final MyElement element = createElement("<a>" + "<child>1</child>" + "<child attr=\"\">2</child>" + "<child/></a>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
|
||||
assertEquals("", child2.getAttr().getValue());
|
||||
assertTrue(child.isValid());
|
||||
assertTrue(child2.isValid());
|
||||
child.undefine();
|
||||
|
||||
assertTrue(child.isValid());
|
||||
assertTrue(child2.isValid());
|
||||
assertTrue(child2.equals(element.getChild2()));
|
||||
assertNotNull(child.getXmlTag());
|
||||
|
||||
child2.undefine();
|
||||
|
||||
assertTrue(child.isValid());
|
||||
assertTrue(child2.isValid());
|
||||
assertTrue(child2.equals(element.getChild2()));
|
||||
assertEquals(child, element.getChild());
|
||||
assertEquals("", child.getValue());
|
||||
assertNull(element.getChild2().getValue());
|
||||
|
||||
myCallRegistry.putExpected(new DomEvent(child, false));
|
||||
myCallRegistry.putExpected(new DomEvent(child2, false));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testUndefineNotLastFixedChild() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final MyElement element = createElement("<a>" + "<child>1</child>" + "<child attr=\"\">2</child>" + "</a>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
|
||||
assertTrue(child.isValid());
|
||||
assertTrue(child2.isValid());
|
||||
child.undefine();
|
||||
assertTrue(child.isValid());
|
||||
assertTrue(child2.isValid());
|
||||
assertEquals(element, child.getParent());
|
||||
assertEquals(element, child2.getParent());
|
||||
assertEquals(child, element.getChild());
|
||||
assertEquals(child2, element.getChild2());
|
||||
|
||||
myCallRegistry.putExpected(new DomEvent(child, false));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
|
||||
XmlTag[] subTags = element.getXmlTag().getSubTags();
|
||||
assertEquals(2, subTags.length);
|
||||
assertCached(child, subTags[0]);
|
||||
assertCached(child2, subTags[1]);
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testUndefineLastFixedChild() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final MyElement element =
|
||||
createElement("<a>" + "<child>1</child>" + "<child attr=\"\">2</child>" + "<child attr=\"\">2</child>" + "</a>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
child2.undefine();
|
||||
|
||||
myCallRegistry.putExpected(new DomEvent(child2, false));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
|
||||
XmlTag[] subTags = element.getXmlTag().getSubTags();
|
||||
assertTrue(child.isValid());
|
||||
assertTrue(child2.isValid());
|
||||
assertEquals(1, subTags.length);
|
||||
assertNull(child2.getXmlTag());
|
||||
|
||||
assertEquals(element, child.getParent());
|
||||
assertEquals(element, child2.getParent());
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testUndefineFixedChildWithNoTag() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
final MyElement child = element.getChild();
|
||||
child.undefine();
|
||||
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
assertTrue(child.isValid());
|
||||
assertEquals(0, element.getXmlTag().getSubTags().length);
|
||||
|
||||
assertSame(element, child.getParent());
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testGenericValuesCollection() throws Throwable {
|
||||
final MyElement element = createElement("<a><generic-child>239</generic-child></a>");
|
||||
assertEquals(239, (int)element.getGenericChildren().get(0).getValue());
|
||||
}
|
||||
|
||||
public void testIsBooleanGenericValueMethod() throws Throwable {
|
||||
assertNull(createElement("").isGenericValue().getValue());
|
||||
}
|
||||
|
||||
public void testGetParentOfType() throws Throwable {
|
||||
getTypeChooserManager().registerTypeChooser(MyAbstractElement.class, new MyTypeChooser());
|
||||
try {
|
||||
final MyElement element = createElement("");
|
||||
final MyAbstractElement abstractChild = element.getAbstractChild();
|
||||
final MyElement child239 = abstractChild.getChild239();
|
||||
|
||||
assertSame(child239, child239.getParentOfType(MyElement.class, false));
|
||||
assertSame(abstractChild, child239.getParentOfType(MyElement.class, true));
|
||||
assertSame(abstractChild, child239.getParentOfType(MyAbstractElement.class, true));
|
||||
assertSame(DomUtil.getFileElement(element), child239.getParentOfType(DomFileElement.class, false));
|
||||
assertSame(DomUtil.getFileElement(element), DomUtil.getFileElement(element).getParentOfType(DomFileElement.class, false));
|
||||
assertNull(DomUtil.getFileElement(element).getParentOfType(DomFileElement.class, true));
|
||||
}
|
||||
finally {
|
||||
getTypeChooserManager().unregisterTypeChooser(MyAbstractElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
public void testChildrenValidAfterUndefine() throws Throwable {
|
||||
final MyElement element = createElement("<a><child/></a>");
|
||||
final MyElement child = element.getChild();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
element.undefine();
|
||||
}
|
||||
});
|
||||
|
||||
assertTrue(element.isValid());
|
||||
assertFalse(child.isValid());
|
||||
}
|
||||
|
||||
public void testGetCompositeCollection() throws Throwable {
|
||||
final MyElement element = createElement("");
|
||||
final MyFooConcreteElement foo = element.addFooChild();
|
||||
final MyElement child = element.addChildElement();
|
||||
final MyBarConcreteElement bar = element.addBarChild();
|
||||
assertEquals(Arrays.asList(foo, bar, child), element.getCompositeList());
|
||||
}
|
||||
|
||||
public void testAddToCompositeCollection() throws Throwable {
|
||||
final MyElement element = createElement("");
|
||||
final MyBarConcreteElement bar = element.addBarComposite();
|
||||
final MyElement child = element.addChildComposite();
|
||||
final MyElement child2 = element.addChildElement();
|
||||
final MyFooConcreteElement foo1 = element.addFooComposite(2);
|
||||
final MyFooConcreteElement foo2 = element.addFooComposite(0);
|
||||
assertEquals(Arrays.asList(foo2, bar, child, foo1, child2), element.getCompositeList());
|
||||
}
|
||||
|
||||
public void testCreateElementWithRequiredChild() throws Throwable {
|
||||
final MyElement element = createElement("").addChildElement();
|
||||
assertNotNull(element.getAttr().getXmlAttribute());
|
||||
assertNotNull(element.isGenericValue().getXmlTag());
|
||||
assertTrue(element.getMyChildren2().isEmpty());
|
||||
}
|
||||
|
||||
public void testSetRequiredChildValue() throws Throwable {
|
||||
final MyElement element = createElement("<a/>").getChild();
|
||||
element.isGenericValue().setStringValue("true");
|
||||
assertEquals(1, element.getXmlTag().findSubTags("generic-value").length);
|
||||
assertTrue(element.isGenericValue().getValue());
|
||||
}
|
||||
|
||||
public void testGetFixedPath() throws Throwable {
|
||||
final MyElement element = createElement("");
|
||||
final MyElement child2 = element.getChild2();
|
||||
assertEquals(Arrays.asList("getChild2", "getChild2", "getChild239", "getAbstractChild", "getChild2"),
|
||||
getFixedPath(child2.getChild2().getChild239().getAbstractChild().getChild2()));
|
||||
assertEquals(Arrays.asList("getChild2"), getFixedPath(child2));
|
||||
assertEquals(Arrays.asList(), getFixedPath(element));
|
||||
assertEquals(Arrays.asList("getAttr"), getFixedPath(element.getAttr()));
|
||||
assertNull(DomUtil.getFixedPath(element.addChildElement().getChild()));
|
||||
}
|
||||
|
||||
public void testGetDomElementCustomChild() throws Throwable {
|
||||
final MyElement myElement = createElement("<a><abstract-child/><generic-value/><bar/></a>", MyElement.class);
|
||||
final XmlTag tag = myElement.getXmlTag();
|
||||
assertEquals(1, myElement.getCustomChildren().size());
|
||||
assertInstanceOf(getDomManager().getDomElement(tag.getSubTags()[0]), MyAbstractElement.class);
|
||||
assertInstanceOf(getDomManager().getDomElement(tag.getSubTags()[1]), GenericDomValue.class);
|
||||
assertInstanceOf(getDomManager().getDomElement(tag.getSubTags()[2]), MyElement.class);
|
||||
}
|
||||
|
||||
public void testNoChildrenForMalformedTags() throws Throwable {
|
||||
final MyElement myElement = createElement("<a><</a>", MyElement.class);
|
||||
final XmlTag tag = myElement.getXmlTag();
|
||||
assertEquals(0, myElement.getCustomChildren().size());
|
||||
}
|
||||
|
||||
public void testCustomNameChildren() throws Throwable {
|
||||
final MyElement myElement = createElement("<a><foo/><bar/><foo xmlns=\"z\"/></a>", MyElement.class);
|
||||
final XmlTag tag = myElement.getXmlTag();
|
||||
final List<MyElement> customChildren = myElement.getCustomChildren();
|
||||
assertOrderedEquals(customChildren, myElement.getGenericInfo().getCustomNameChildrenDescription().getValues(myElement));
|
||||
assertOrderedCollection(customChildren, new Consumer<MyElement>() {
|
||||
@Override
|
||||
public void consume(final MyElement element) {
|
||||
assertInstanceOf(element, MyElement.class);
|
||||
assertEquals(tag.getSubTags()[0], element.getXmlTag());
|
||||
}
|
||||
}, new Consumer<MyElement>() {
|
||||
@Override
|
||||
public void consume(final MyElement element) {
|
||||
assertInstanceOf(element, MyElement.class);
|
||||
assertEquals(tag.getSubTags()[1], element.getXmlTag());
|
||||
}
|
||||
}, new Consumer<MyElement>() {
|
||||
@Override
|
||||
public void consume(final MyElement element) {
|
||||
assertInstanceOf(element, MyElement.class);
|
||||
assertEquals(tag.getSubTags()[2], element.getXmlTag());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<String> getFixedPath(final DomElement element) {
|
||||
return ContainerUtil.map2List(DomUtil.getFixedPath(element), new Function<JavaMethod, String>() {
|
||||
@Override
|
||||
public String fun(final JavaMethod s) {
|
||||
return s.getName();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testElementsWithoutXmlGetItLater() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
final PsiElement tag = element.getXmlTag().add(createTag("<child/>"));
|
||||
incModCount();
|
||||
|
||||
assertTrue(child.isValid());
|
||||
assertEquals(tag, child.getXmlTag());
|
||||
|
||||
assertTrue(child2.isValid());
|
||||
assertNull(child2.getXmlTag());
|
||||
}
|
||||
|
||||
public void testHigherOrderFixedsAreNotCustom() {
|
||||
final MyElement element = createElement("<a><child/><child/><child/></a>");
|
||||
XmlTag third = element.getXmlTag().getSubTags()[2];
|
||||
assertNull(getDomManager().getDomElement(third));
|
||||
assertEmpty(element.getCustomChildren());
|
||||
}
|
||||
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
@Attribute
|
||||
@Required
|
||||
GenericAttributeValue<String> getAttr();
|
||||
|
||||
String getValue();
|
||||
|
||||
@SubTag("child")
|
||||
MyElement getMyChild();
|
||||
|
||||
MyElement getChild();
|
||||
|
||||
@SubTag(value = "child", index = 1)
|
||||
MyElement getChild2();
|
||||
|
||||
MyElement getChild239();
|
||||
|
||||
@SubTagList("child-element")
|
||||
List<? extends MyElement> getMyChildren();
|
||||
|
||||
@CustomChildren
|
||||
List<MyElement> getCustomChildren();
|
||||
|
||||
@SubTagList("child-element")
|
||||
@Required
|
||||
List<MyElement> getMyChildren2();
|
||||
|
||||
List<MyElement> getChildElements();
|
||||
|
||||
MyElement addChildElement();
|
||||
|
||||
MyElement addChildElement(int index);
|
||||
|
||||
MyAbstractElement getAbstractChild();
|
||||
|
||||
List<MyAbstractElement> getAbstractElements();
|
||||
|
||||
@SubTagList("abstract-element")
|
||||
MyBarConcreteElement addBarChild();
|
||||
|
||||
@SubTagList("abstract-element")
|
||||
MyFooConcreteElement addFooChild();
|
||||
|
||||
<T extends MyAbstractElement> T addAbstractElement(Class<T> aClass);
|
||||
|
||||
<T extends MyAbstractElement> T addAbstractElement(Class<T> aClass, int index);
|
||||
|
||||
<T extends MyAbstractElement> T addAbstractElement(int index, Class<T> aClass);
|
||||
|
||||
List<GenericDomValue<Integer>> getGenericChildren();
|
||||
|
||||
@Required
|
||||
GenericDomValue<Boolean> isGenericValue();
|
||||
|
||||
@SubTagsList({"child-element", "abstract-element"})
|
||||
List<MyElement> getCompositeList();
|
||||
|
||||
@SubTagsList(value = {"child-element", "abstract-element"}, tagName = "abstract-element")
|
||||
MyBarConcreteElement addBarComposite();
|
||||
|
||||
@SubTagsList(value = {"child-element", "abstract-element"}, tagName = "child-element")
|
||||
MyElement addChildComposite();
|
||||
|
||||
@SubTagsList(value = {"child-element", "abstract-element"}, tagName = "abstract-element")
|
||||
MyFooConcreteElement addFooComposite(int index);
|
||||
|
||||
}
|
||||
|
||||
public interface MyAbstractElement extends MyElement {
|
||||
}
|
||||
|
||||
public interface MyFooConcreteElement extends MyAbstractElement {
|
||||
MyFooConcreteElement getFoo();
|
||||
}
|
||||
|
||||
public interface MyBarConcreteElement extends MyAbstractElement {
|
||||
}
|
||||
|
||||
private static class MyTypeChooser extends TypeChooser {
|
||||
@Override
|
||||
public Type chooseType(final XmlTag tag) {
|
||||
return tag != null && tag.getText().contains("Foo") ? MyFooConcreteElement.class : MyBarConcreteElement.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void distinguishTag(final XmlTag tag, final Type aClass) throws IncorrectOperationException {
|
||||
tag.setAttribute("foo", ((Class)aClass).getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getChooserTypes() {
|
||||
return ArrayUtil.EMPTY_CLASS_ARRAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2007 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.semantic.SemService;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.testFramework.Timings;
|
||||
import com.intellij.util.xml.impl.DomFileElementImpl;
|
||||
import com.intellij.util.xml.reflect.DomExtender;
|
||||
import com.intellij.util.xml.reflect.DomExtenderEP;
|
||||
import com.intellij.util.xml.reflect.DomExtensionsRegistrar;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomConcurrencyStressTest extends DomTestCase {
|
||||
private static final int ITERATIONS = Timings.adjustAccordingToMySpeed(239, true);
|
||||
|
||||
public void testInternalDomLocksReadConsistency() throws Throwable {
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyElement.class, "a"), myTestRootDisposable);
|
||||
|
||||
registerExtender(MyElement.class, MyExtender.class);
|
||||
|
||||
|
||||
final XmlFile file = createXmlFile("<a attr=\"1\" attr2=\"2\">" +
|
||||
"<foo-child><foo-child/><custom-foo/></foo-child>" +
|
||||
"<bar-child><foo-child/></bar-child>" +
|
||||
"<foo-element>" +
|
||||
" <foo-child/>" +
|
||||
" <foo-child><foo-child attr=\"\"/></foo-child>" +
|
||||
" <custom-foo/>" +
|
||||
" <custom-bar/>" +
|
||||
"</foo-element>" +
|
||||
"<custom-bar/>" +
|
||||
"<custom-bar>" +
|
||||
" <foo-child/>" +
|
||||
" <foo-element/>" +
|
||||
" <foo-element/>" +
|
||||
" <custom-bar/>" +
|
||||
"</custom-bar>" +
|
||||
"<custom-bar attr=\"\">" +
|
||||
" <foo-child/>" +
|
||||
" <some-child/>" +
|
||||
" <custom-bar/>" +
|
||||
"</custom-bar>" +
|
||||
"<child/>" +
|
||||
"<child/>" +
|
||||
"<bool/>" +
|
||||
"</a>");
|
||||
|
||||
System.out.println("ITERATIONS =" + ITERATIONS);
|
||||
runThreads(42, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final DomFileElementImpl<DomElement> element = getDomManager().getFileElement(file);
|
||||
assertNotNull(element);
|
||||
element.getRootElement().accept(new DomElementVisitor() {
|
||||
@Override
|
||||
public void visitDomElement(final DomElement element) {
|
||||
if (DomUtil.hasXml(element)) {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
SemService.getSemService(getProject()).clearCache();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void registerExtender(final Class elementClass, final Class extenderClass) {
|
||||
final DomExtenderEP extenderEP = new DomExtenderEP();
|
||||
extenderEP.domClassName = elementClass.getName();
|
||||
extenderEP.extenderClassName = extenderClass.getName();
|
||||
PlatformTestUtil.registerExtension(Extensions.getRootArea(), DomExtenderEP.EP_NAME, extenderEP, myTestRootDisposable);
|
||||
}
|
||||
|
||||
private static void runThreads(int threadCount, final Runnable runnable) throws Throwable {
|
||||
final Ref<Throwable> exc = Ref.create(null);
|
||||
|
||||
final CountDownLatch reads = new CountDownLatch(threadCount);
|
||||
for (int j = 0; j < threadCount; j++) {
|
||||
new Thread(){
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
runnable.run();
|
||||
}
|
||||
catch (Throwable e) {
|
||||
exc.set(e);
|
||||
} finally {
|
||||
reads.countDown();
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
reads.await();
|
||||
if (!exc.isNull()) {
|
||||
throw exc.get();
|
||||
}
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
MyElement getFooChild();
|
||||
MyElement getBarChild();
|
||||
|
||||
MyElement getSomeChild();
|
||||
|
||||
List<MyElement> getFooElements();
|
||||
MyElement addFooElement();
|
||||
|
||||
List<MyElement> getChildren();
|
||||
MyElement addChild();
|
||||
|
||||
GenericAttributeValue<String> getAttr();
|
||||
GenericAttributeValue<String> getAttr2();
|
||||
|
||||
@SubTag(indicator = true)
|
||||
GenericDomValue<Boolean> getBool();
|
||||
|
||||
}
|
||||
|
||||
public static class MyExtender extends DomExtender<MyElement> {
|
||||
private final Random myRandom = new Random();
|
||||
|
||||
@Override
|
||||
public void registerExtensions(@NotNull MyElement myElement, @NotNull DomExtensionsRegistrar registrar) {
|
||||
for (MyElement element : myElement.getFooElements()) {
|
||||
element.getFooElements();
|
||||
}
|
||||
if (myRandom.nextInt(20) < 2) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
registrar.registerFixedNumberChildExtension(new XmlName("custom-foo", null), MyElement.class);
|
||||
myElement.getSomeChild().getFooElements();
|
||||
myElement.getFooChild().getFooChild().getAttr();
|
||||
myElement.getAttr();
|
||||
registrar.registerCollectionChildrenExtension(new XmlName("custom-bar", null), MyElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
public void testBigCustomFile() throws Throwable {
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyAllCustomElement.class, "component"), myTestRootDisposable);
|
||||
|
||||
registerExtender(MyAllCustomElement.class, MyAllCustomExtender.class);
|
||||
|
||||
VirtualFile bigXml = LocalFileSystem.getInstance().findFileByPath(PathManagerEx.getTestDataPath() + "/psi/formatter/xml/performance.xml");
|
||||
assert bigXml != null;
|
||||
final XmlFile file = (XmlFile)PsiManager.getInstance(ourProject).findFile(bigXml);
|
||||
|
||||
runThreads(42, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final Random random = new Random();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
int offset = random.nextInt(file.getTextLength() - 10);
|
||||
XmlTag tag = PsiTreeUtil.findElementOfClassAtOffset(file, offset, XmlTag.class, false);
|
||||
assert tag != null : offset;
|
||||
DomElement element = DomUtil.getDomElement(tag);
|
||||
assert element instanceof MyAllCustomElement : element;
|
||||
}
|
||||
});
|
||||
|
||||
if (random.nextInt(50) == 0) {
|
||||
SemService.getSemService(getProject()).clearCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public interface MyAllCustomElement extends DomElement {}
|
||||
|
||||
public static class MyAllCustomExtender extends DomExtender<MyAllCustomElement> {
|
||||
@Override
|
||||
public void registerExtensions(@NotNull MyAllCustomElement element, @NotNull DomExtensionsRegistrar registrar) {
|
||||
try {
|
||||
DomElement parent = element;
|
||||
while (parent != null) {
|
||||
for (DomElement child : DomUtil.getDefinedChildren(parent, true, true)) {
|
||||
DomElement childParent = child.getParent();
|
||||
if (!parent.equals(childParent)) {
|
||||
String parentText = parent.getXmlTag().getText();
|
||||
String childText = child.getXmlElement().getText();
|
||||
child.getParent();
|
||||
parent.equals(childParent);
|
||||
throw new AssertionError(parent.getXmlElement() + "; " + childParent + "; " + child.getXmlElement().getText());
|
||||
}
|
||||
}
|
||||
|
||||
parent = parent.getParent();
|
||||
}
|
||||
}
|
||||
catch (StackOverflowError e) {
|
||||
System.out.println(Thread.currentThread() + ": " + element.getXmlTag().getName() + element.getXmlTag().hashCode());
|
||||
throw e;
|
||||
}
|
||||
registrar.registerCustomChildrenExtension(MyAllCustomElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,310 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2007 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.ParameterizedTypeImpl;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import com.intellij.util.xml.reflect.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomExtensionsTest extends DomTestCase {
|
||||
private static final Key<Boolean> BOOL_KEY = Key.create("aaa");
|
||||
|
||||
public void testExtendAttributes() throws Throwable {
|
||||
registerDomExtender(AttrDomExtender.class);
|
||||
assertEmpty(getCustomChildren(createElement("<a foo=\"xxx\"/>", MyElement.class)));
|
||||
|
||||
MyElement element = createElement("<a attr=\"foo\" foo=\"true\"/>", MyElement.class);
|
||||
final GenericAttributeValue child = assertInstanceOf(assertOneElement(getCustomChildren(element)), GenericAttributeValue.class);
|
||||
assertEquals("true", child.getStringValue());
|
||||
assertEquals(Boolean.TRUE, child.getValue());
|
||||
assertEquals(Boolean.class, DomUtil.getGenericValueParameter(child.getDomElementType()));
|
||||
assertSame(element.getXmlTag().getAttribute("foo"), child.getXmlElement());
|
||||
|
||||
child.setStringValue("xxx");
|
||||
assertEquals("xxx", child.getStringValue());
|
||||
assertEquals("xxx", element.getXmlTag().getAttributeValue("foo"));
|
||||
|
||||
element = createElement("<a attr=\"foo\" foo=\"true\"/>", MyElement.class);
|
||||
final GenericAttributeValue value = getDomManager().getDomElement(element.getXmlTag().getAttribute("foo"));
|
||||
assertNotNull(value);
|
||||
assertEquals(value, assertOneElement(getCustomChildren(element)));
|
||||
assertNotNull(element.getGenericInfo().getAttributeChildDescription("foo"));
|
||||
}
|
||||
|
||||
public void testCustomAttributeChildClass() throws Throwable {
|
||||
registerDomExtender(AttrDomExtender3.class);
|
||||
final MyElement element = createElement("<a attr=\"xxx\"/>", MyElement.class);
|
||||
assertEquals("xxx", assertInstanceOf(assertOneElement(getCustomChildren(element)), MyAttribute.class).getXmlElementName());
|
||||
}
|
||||
|
||||
public void testUserData() throws Throwable {
|
||||
registerDomExtender(AttrDomExtender3.class);
|
||||
final MyElement element = createElement("<a attr=\"xxx\"/>", MyElement.class);
|
||||
final DomAttributeChildDescription description = element.getGenericInfo().getAttributeChildDescription("xxx");
|
||||
assertNotNull(description);
|
||||
assertSame(Boolean.TRUE, description.getUserData(BOOL_KEY));
|
||||
}
|
||||
|
||||
public void testUseCustomConverter() throws Throwable {
|
||||
registerDomExtender(AttrDomExtender2.class);
|
||||
final MyElement myElement = createElement("<a attr=\"xxx\" xxx=\"zzz\" yyy=\"zzz\"/>", MyElement.class);
|
||||
assertUnorderedCollection(getCustomChildren(myElement), new Consumer<DomElement>() {
|
||||
@Override
|
||||
public void consume(final DomElement element) {
|
||||
final StringBuffer stringBuffer = ((GenericAttributeValue<StringBuffer>)element).getValue();
|
||||
assertEquals("zzz", stringBuffer.toString());
|
||||
assertInstanceOf(((GenericAttributeValue<StringBuffer>)element).getConverter(), StringBufferConverter.class);
|
||||
assertNotNull(myElement.getGenericInfo().getAttributeChildDescription("xxx"));
|
||||
|
||||
Convert convert = element.getAnnotation(Convert.class);
|
||||
assertNotNull(convert);
|
||||
assertEquals(StringBufferConverter.class, convert.value());
|
||||
assertTrue(convert.soft());
|
||||
}
|
||||
}, new Consumer<DomElement>() {
|
||||
@Override
|
||||
public void consume(final DomElement element) {
|
||||
final StringBuffer stringBuffer = ((GenericAttributeValue<StringBuffer>)element).getValue();
|
||||
assertEquals("zzz", stringBuffer.toString());
|
||||
assertInstanceOf(((GenericAttributeValue<StringBuffer>)element).getConverter(), StringBufferConverter.class);
|
||||
assertNotNull(myElement.getGenericInfo().getAttributeChildDescription("yyy"));
|
||||
|
||||
Convert convert = element.getAnnotation(Convert.class);
|
||||
assertNotNull(convert);
|
||||
assertEquals(StringBufferConverter.class, convert.value());
|
||||
assertFalse(convert.soft());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testFixedChildren() throws Throwable {
|
||||
registerDomExtender(FixedDomExtender.class);
|
||||
final MyElement myElement = createElement("<a attr=\"xxx\"><xxx>zzz</xxx><yyy attr=\"foo\"/><yyy attr=\"bar\"/></a>", MyElement.class);
|
||||
assertUnorderedCollection(getCustomChildren(myElement), new Consumer<DomElement>() {
|
||||
@Override
|
||||
public void consume(final DomElement element) {
|
||||
assertEquals(GenericDomValue.class, ReflectionUtil.getRawType(element.getDomElementType()));
|
||||
final StringBuffer stringBuffer = ((GenericDomValue<StringBuffer>)element).getValue();
|
||||
assertEquals("zzz", stringBuffer.toString());
|
||||
assertInstanceOf(((GenericDomValue<StringBuffer>)element).getConverter(), MyStringBufferConverter.class);
|
||||
assertNotNull(myElement.getGenericInfo().getFixedChildDescription("xxx"));
|
||||
|
||||
Convert convert = element.getAnnotation(Convert.class);
|
||||
assertNotNull(convert);
|
||||
assertEquals(MyStringBufferConverter.class, convert.value());
|
||||
assertTrue(convert.soft());
|
||||
|
||||
assertNotNull(element.getGenericInfo().getAttributeChildDescription("aaa"));
|
||||
}
|
||||
}, new Consumer<DomElement>() {
|
||||
@Override
|
||||
public void consume(final DomElement element) {
|
||||
assertEquals("foo", ((MyElement) element).getAttr().getValue());
|
||||
assertNull(element.getAnnotation(Convert.class));
|
||||
}
|
||||
}, new Consumer<DomElement>() {
|
||||
@Override
|
||||
public void consume(final DomElement element) {
|
||||
assertEquals("bar", ((MyElement) element).getAttr().getValue());
|
||||
assertNull(element.getAnnotation(Convert.class));
|
||||
}
|
||||
});
|
||||
final DomFixedChildDescription description = myElement.getGenericInfo().getFixedChildDescription("yyy");
|
||||
assertNotNull(description);
|
||||
assertEquals(2, description.getCount());
|
||||
}
|
||||
|
||||
public void testCollectionChildren() throws Throwable {
|
||||
registerDomExtender(CollectionDomExtender.class);
|
||||
final MyElement myElement = createElement("<a attr=\"xxx\"><xxx>zzz</xxx><xxx attr=\"foo\"/></a>", MyElement.class);
|
||||
assertUnorderedCollection(getCustomChildren(myElement), new Consumer<DomElement>() {
|
||||
@Override
|
||||
public void consume(final DomElement element) {
|
||||
assertEquals("foo", ((MyElement) element).getAttr().getValue());
|
||||
assertNull(element.getAnnotation(Convert.class));
|
||||
}
|
||||
}, new Consumer<DomElement>() {
|
||||
@Override
|
||||
public void consume(final DomElement element) {
|
||||
assertNull(((MyElement) element).getAttr().getValue());
|
||||
assertNull(element.getAnnotation(Convert.class));
|
||||
}
|
||||
});
|
||||
assertNotNull(myElement.getGenericInfo().getCollectionChildDescription("xxx"));
|
||||
}
|
||||
|
||||
public void testCollectionAdders() throws Throwable {
|
||||
registerDomExtender(CollectionDomExtender.class);
|
||||
final MyElement myElement = createElement("<a attr=\"xxx\"></a>", MyElement.class);
|
||||
final DomCollectionChildDescription description = myElement.getGenericInfo().getCollectionChildDescription("xxx");
|
||||
final DomElement element2 = description.addValue(myElement);
|
||||
final DomElement element0 = description.addValue(myElement, 0);
|
||||
final DomElement element3 = description.addValue(myElement, MyConcreteElement.class);
|
||||
final DomElement element1 = description.addValue(myElement, MyConcreteElement.class, 1);
|
||||
assertSameElements(getCustomChildren(myElement), element0, element1, element2, element3);
|
||||
}
|
||||
|
||||
public void testCustomChildrenAccessFromExtender() throws Throwable {
|
||||
registerDomExtender(MyCustomChildrenElement.class, CustomDomExtender.class);
|
||||
final MyCustomChildrenElement myElement = createElement("<a><xx/><yy/><concrete-child/><some-concrete-child/></a>", MyCustomChildrenElement.class);
|
||||
final DomCollectionChildDescription description = myElement.getGenericInfo().getCollectionChildDescription("xx");
|
||||
assertNotNull(description);
|
||||
assertInstanceOf(assertOneElement(description.getValues(myElement)), MyDynamicElement.class);
|
||||
assertInstanceOf(assertOneElement(myElement.getCustomChidren()), MyCustomElement.class);
|
||||
assertInstanceOf(assertOneElement(myElement.getConcreteChildren()), MyConcreteElement.class);
|
||||
assertNotNull(assertInstanceOf(myElement.getSomeConcreteChild(), MyConcreteElement.class).getXmlTag());
|
||||
}
|
||||
|
||||
public void testFirstChildRedefinitionOnExtending() throws Exception {
|
||||
registerDomExtender(MyCustomChildrenElement.class, ModestDomExtender.class);
|
||||
|
||||
final MyCustomChildrenElement myElement = createElement("<a><concrete-child/><concrete-child/></a>", MyCustomChildrenElement.class);
|
||||
final List<MyConcreteElement> list = myElement.getConcreteChildren();
|
||||
final List<MyConcreteElement> list2 = myElement.getConcreteChildren();
|
||||
assertSame(list.get(0), list2.get(0));
|
||||
assertSame(list.get(1), list2.get(1));
|
||||
}
|
||||
|
||||
public static List<DomElement> getCustomChildren(final DomElement element) {
|
||||
final List<DomElement> children = new ArrayList<DomElement>();
|
||||
element.acceptChildren(new DomElementVisitor() {
|
||||
@Override
|
||||
public void visitDomElement(final DomElement element) {
|
||||
if (!"attr".equals(element.getXmlElementName())) {
|
||||
children.add(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
return children;
|
||||
}
|
||||
|
||||
public void registerDomExtender(Class<? extends DomExtender<MyElement>> extender) {
|
||||
registerDomExtender(MyElement.class, extender);
|
||||
}
|
||||
|
||||
public <T extends DomElement> void registerDomExtender(final Class<T> domClass, final Class<? extends DomExtender<T>> extenderClass) {
|
||||
final DomExtenderEP extenderEP = new DomExtenderEP();
|
||||
extenderEP.domClassName = domClass.getName();
|
||||
extenderEP.extenderClassName = extenderClass.getName();
|
||||
IdeaTestUtil.registerExtension(Extensions.getRootArea(), DomExtenderEP.EP_NAME, extenderEP, myTestRootDisposable);
|
||||
}
|
||||
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
GenericAttributeValue<String> getAttr();
|
||||
}
|
||||
|
||||
public interface MyCustomChildrenElement extends DomElement {
|
||||
@CustomChildren List<MyCustomElement> getCustomChidren();
|
||||
|
||||
List<MyConcreteElement> getConcreteChildren();
|
||||
|
||||
MyConcreteElement getSomeConcreteChild();
|
||||
}
|
||||
|
||||
public interface MyConcreteElement extends MyElement {
|
||||
}
|
||||
public interface MyCustomElement extends MyElement {
|
||||
}
|
||||
public interface MyDynamicElement extends MyElement {
|
||||
}
|
||||
|
||||
public static class AttrDomExtender extends DomExtender<MyElement> {
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final MyElement element, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
final String value = element.getAttr().getValue();
|
||||
if (value != null) {
|
||||
registrar.registerGenericAttributeValueChildExtension(new XmlName(value), Boolean.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class AttrDomExtender2 extends DomExtender<MyElement> {
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final MyElement element, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
final String value = element.getAttr().getValue();
|
||||
if (value != null) {
|
||||
registrar.registerGenericAttributeValueChildExtension(new XmlName(value), StringBuffer.class).setConverter(new StringBufferConverter(), true);
|
||||
registrar.registerGenericAttributeValueChildExtension(new XmlName("yyy"), StringBuffer.class).setConverter(new StringBufferConverter(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class AttrDomExtender3 extends DomExtender<MyElement> {
|
||||
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final MyElement element, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
final String value = element.getAttr().getValue();
|
||||
if (value != null) {
|
||||
registrar.registerAttributeChildExtension(new XmlName(value), MyAttribute.class).putUserData(BOOL_KEY, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FixedDomExtender extends DomExtender<MyElement> {
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final MyElement element, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
final String value = element.getAttr().getValue();
|
||||
if (value != null) {
|
||||
final ParameterizedType type = new ParameterizedTypeImpl(GenericDomValue.class, StringBuffer.class);
|
||||
final DomExtension extension =
|
||||
registrar.registerFixedNumberChildExtension(new XmlName(value), type).setConverter(new MyStringBufferConverter(true), true);
|
||||
extension.addExtender(new DomExtender<GenericDomValue<StringBuffer>>(){
|
||||
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final GenericDomValue<StringBuffer> stringBufferGenericDomValue, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
registrar.registerGenericAttributeValueChildExtension(new XmlName("aaa"), String.class);
|
||||
}
|
||||
});
|
||||
((DomExtensionsRegistrarImpl)registrar).registerFixedNumberChildrenExtension(new XmlName("yyy"), MyElement.class, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static class CollectionDomExtender extends DomExtender<MyElement> {
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final MyElement element, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
final String value = element.getAttr().getValue();
|
||||
if (value != null) {
|
||||
registrar.registerCollectionChildrenExtension(new XmlName(value), MyElement.class).setConverter(new MyStringBufferConverter(true), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomDomExtender extends DomExtender<MyCustomChildrenElement> {
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final MyCustomChildrenElement element, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
assertEmpty(element.getCustomChidren());
|
||||
registrar.registerCollectionChildrenExtension(new XmlName("xx"), MyDynamicElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModestDomExtender extends DomExtender<MyCustomChildrenElement> {
|
||||
@Override
|
||||
public void registerExtensions(@NotNull final MyCustomChildrenElement element, @NotNull final DomExtensionsRegistrar registrar) {
|
||||
registrar.registerCollectionChildrenExtension(new XmlName("xx"), MyDynamicElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyStringBufferConverter extends StringBufferConverter {
|
||||
public MyStringBufferConverter(boolean b) {
|
||||
}
|
||||
}
|
||||
public static interface MyAttribute extends GenericAttributeValue<Boolean> {}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.util.xml.impl.DomFileElementImpl;
|
||||
import com.intellij.util.xml.impl.MockDomFileDescription;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomFileDescriptionTest extends DomHardCoreTestCase {
|
||||
private XmlFile myFooElementFile;
|
||||
private XmlFile myBarElementFile;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
myFooElementFile = new WriteCommandAction<XmlFile>(getProject()) {
|
||||
@Override
|
||||
protected void run(Result<XmlFile> result) throws Throwable {
|
||||
result.setResult((XmlFile)createFile("a.xml", "<a/>"));
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
|
||||
getDomManager().registerFileDescription(new MockDomFileDescription<FooElement>(FooElement.class, "a", myFooElementFile), getTestRootDisposable());
|
||||
|
||||
myBarElementFile = new WriteCommandAction<XmlFile>(getProject()) {
|
||||
@Override
|
||||
protected void run(Result<XmlFile> result) throws Throwable {
|
||||
result.setResult((XmlFile)createFile("b.xml", "<b/>"));
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
|
||||
getDomManager().registerFileDescription(new DomFileDescription<BarElement>(BarElement.class, "b") {
|
||||
|
||||
@Override
|
||||
public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
|
||||
return myFooElementFile.getText().contains("239");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutomaticHighlightingEnabled() {
|
||||
return false;
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testNoInitialDomnessInB() throws Throwable {
|
||||
assertFalse(getDomManager().isDomFile(myBarElementFile));
|
||||
assertNull(getDomManager().getFileElement(myBarElementFile));
|
||||
}
|
||||
|
||||
public void testIsDomValue() throws Throwable {
|
||||
final XmlFile file = (XmlFile)createFile("a.xml", "<b>42</b>");
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyElement.class, "b") {
|
||||
|
||||
@Override
|
||||
public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
|
||||
return /*super.isMyFile(file, module) && */file.getText().contains("239");
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
|
||||
|
||||
assertFalse(getDomManager().isDomFile(file));
|
||||
assertNull(getDomManager().getFileElement(file));
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
file.getDocument().getRootTag().getValue().setText("239");
|
||||
}
|
||||
}.execute();
|
||||
assertTrue(getDomManager().isDomFile(file));
|
||||
final DomFileElementImpl<MyElement> root = getDomManager().getFileElement(file);
|
||||
assertNotNull(root);
|
||||
final MyElement child = root.getRootElement().getChild();
|
||||
assertTrue(root.isValid());
|
||||
assertTrue(child.isValid());
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
file.getDocument().getRootTag().getValue().setText("57121");
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(getDomManager().isDomFile(file));
|
||||
assertNull(getDomManager().getFileElement(file));
|
||||
assertFalse(root.isValid());
|
||||
assertFalse(child.isValid());
|
||||
}
|
||||
|
||||
public void testCopyFileDescriptionFromOriginalFile() throws Throwable {
|
||||
final XmlFile file = (XmlFile)createFile("a.xml", "<b>42</b>");
|
||||
|
||||
getDomManager().registerFileDescription(new MockDomFileDescription(MyElement.class, "b", file), getTestRootDisposable());
|
||||
file.setName("b.xml");
|
||||
assertTrue(getDomManager().isDomFile(file));
|
||||
final XmlFile copy = (XmlFile)file.copy();
|
||||
assertTrue(getDomManager().isDomFile(copy));
|
||||
assertFalse(getDomManager().getFileElement(file).equals(getDomManager().getFileElement(copy)));
|
||||
}
|
||||
|
||||
public void testDependantFileDescriptionCauseStackOverflow() throws Throwable {
|
||||
final XmlFile interestingFile = (XmlFile)createFile("a.xml", "<b>42</b>");
|
||||
|
||||
getDomManager().registerFileDescription(new MockDomFileDescription(MyElement.class, "b", (XmlFile)null), getTestRootDisposable());
|
||||
for (int i = 0; i < 239; i++) {
|
||||
getDomManager().registerFileDescription(new MockDomFileDescription(AbstractElement.class, "b", (XmlFile)null) {
|
||||
@Override
|
||||
@NotNull
|
||||
public Set getDependencyItems(final XmlFile file) {
|
||||
getDomManager().isDomFile(interestingFile);
|
||||
return super.getDependencyItems(file);
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
}
|
||||
|
||||
getDomManager().isDomFile(interestingFile);
|
||||
}
|
||||
|
||||
public void testCheckNamespace() throws Throwable {
|
||||
getDomManager().registerFileDescription(new DomFileDescription(NamespacedElement.class, "xxx", "bar"){
|
||||
|
||||
@Override
|
||||
protected void initializeFileDescription() {
|
||||
registerNamespacePolicy("foo", "bar");
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
|
||||
final PsiFile file = createFile("xxx.xml", "<xxx/>");
|
||||
assertFalse(getDomManager().isDomFile(file));
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
((XmlFile)file).getDocument().getRootTag().setAttribute("xmlns", "bar");
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertTrue(getDomManager().isDomFile(file));
|
||||
|
||||
}
|
||||
|
||||
public void testCheckDtdPublicId() throws Throwable {
|
||||
getDomManager().registerFileDescription(new DomFileDescription(NamespacedElement.class, "xxx", "bar"){
|
||||
|
||||
@Override
|
||||
protected void initializeFileDescription() {
|
||||
registerNamespacePolicy("foo", "bar");
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
|
||||
final PsiFile file = createFile("xxx.xml", "<xxx/>");
|
||||
assertFalse(getDomManager().isDomFile(file));
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = getDocument(file);
|
||||
document.insertString(0, "<!DOCTYPE xxx PUBLIC \"bar\" \"http://java.sun.com/dtd/ejb-jar_2_0.dtd\">\n");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertTrue(getDomManager().isDomFile(file));
|
||||
}
|
||||
|
||||
public void testChangeCustomDomness() throws Throwable {
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyElement.class, "xxx"){
|
||||
@Override
|
||||
public boolean isMyFile(@NotNull final XmlFile file, @Nullable final Module module) {
|
||||
return file.getText().contains("foo");
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
final XmlFile file = (XmlFile)createFile("xxx.xml", "<xxx zzz=\"foo\"><boy/><boy/><xxx/>");
|
||||
final MyElement boy = getDomManager().getFileElement(file, MyElement.class).getRootElement().getBoys().get(0);
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
file.getDocument().getRootTag().setAttribute("zzz", "bar");
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(getDomManager().isDomFile(file));
|
||||
assertFalse(boy.isValid());
|
||||
}
|
||||
|
||||
public interface AbstractElement extends GenericDomValue<String> {
|
||||
GenericAttributeValue<String> getAttr();
|
||||
}
|
||||
|
||||
public interface FooElement extends AbstractElement {
|
||||
}
|
||||
|
||||
public interface BarElement extends AbstractElement {
|
||||
}
|
||||
|
||||
public interface ZipElement extends AbstractElement {
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
|
||||
MyElement getChild();
|
||||
|
||||
List<MyElement> getBoys();
|
||||
|
||||
}
|
||||
|
||||
@Namespace("foo")
|
||||
public interface NamespacedElement extends DomElement {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightTestCase;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.PresentableLookupValue;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlTagValue;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
import com.intellij.util.xml.impl.DomManagerImpl;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class DomHardCoreTestCase extends CodeInsightTestCase {
|
||||
private CallRegistry<DomEvent> myCallRegistry;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myCallRegistry = new CallRegistry<DomEvent>();
|
||||
getDomManager().addDomEventListener(new DomEventListener() {
|
||||
@Override
|
||||
public void eventOccured(DomEvent event) {
|
||||
myCallRegistry.putActual(event);
|
||||
}
|
||||
}, myProject);
|
||||
}
|
||||
|
||||
protected DomManagerImpl getDomManager() {
|
||||
return DomManagerImpl.getDomManager(getProject());
|
||||
}
|
||||
|
||||
protected <T extends DomElement> T createElement(final String xml, final Class<T> aClass) throws IncorrectOperationException {
|
||||
return DomTestCase.createElement(getDomManager(), xml, aClass);
|
||||
}
|
||||
|
||||
protected void assertEventCount(final int size) {
|
||||
assertEquals(myCallRegistry.toString(), size, myCallRegistry.getSize());
|
||||
}
|
||||
|
||||
protected void putExpected(final DomEvent event) {
|
||||
myCallRegistry.putExpected(event);
|
||||
}
|
||||
|
||||
protected void assertResultsAndClear() {
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
}
|
||||
|
||||
protected PsiReference assertReference(final GenericDomValue value) {
|
||||
return assertReference(value, value.getXmlTag());
|
||||
}
|
||||
|
||||
protected PsiReference assertReference(final GenericDomValue value, PsiElement resolveTo) {
|
||||
final XmlTagValue tagValue = value.getXmlTag().getValue();
|
||||
final TextRange textRange = tagValue.getTextRange();
|
||||
final String s = value.getStringValue();
|
||||
final int i = tagValue.getText().indexOf(s);
|
||||
return assertReference(value, resolveTo, textRange.getStartOffset() + i + s.length());
|
||||
}
|
||||
|
||||
protected PsiReference assertReference(final GenericDomValue value, PsiElement resolveTo, int offset) {
|
||||
final XmlTag tag = value.getXmlTag();
|
||||
final PsiReference reference = tag.getContainingFile().findReferenceAt(offset);
|
||||
assertNotNull(reference);
|
||||
assertEquals(resolveTo, reference.resolve());
|
||||
return reference;
|
||||
}
|
||||
|
||||
protected PsiReference getReference(final GenericAttributeValue value) {
|
||||
final XmlAttributeValue attributeValue = value.getXmlAttributeValue();
|
||||
final PsiReference reference = attributeValue.getContainingFile().findReferenceAt(attributeValue.getTextRange().getStartOffset() + 1);
|
||||
assertNotNull(reference);
|
||||
assertEquals(attributeValue, reference.resolve());
|
||||
return reference;
|
||||
}
|
||||
|
||||
protected void assertVariants(PsiReference reference, String... variants) {
|
||||
Object[] refVariants = reference.getVariants();
|
||||
assertNotNull(refVariants);
|
||||
assertEquals(refVariants.length, variants.length);
|
||||
int i = 0;
|
||||
for (String variant : variants) {
|
||||
Object refVariant = refVariants[i++];
|
||||
if (refVariant instanceof LookupElement) {
|
||||
assertEquals(variant, ((LookupElement)refVariant).getLookupString());
|
||||
}
|
||||
else if (refVariant instanceof PresentableLookupValue) {
|
||||
assertEquals(variant, ((PresentableLookupValue)refVariant).getPresentation());
|
||||
}
|
||||
else {
|
||||
assertEquals(variant, refVariant.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DomReferencesTest.MyElement createElement(final String xml) throws IncorrectOperationException {
|
||||
return createElement(xml, DomReferencesTest.MyElement.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey;
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.InspectionProfile;
|
||||
import com.intellij.codeInspection.InspectionToolProvider;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ex.InspectionToolRegistrar;
|
||||
import com.intellij.ide.ui.search.SearchableOptionsRegistrar;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.mock.MockInspectionProfile;
|
||||
import com.intellij.profile.codeInspection.InspectionProfileManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.testFramework.MockSchemesManagerFactory;
|
||||
import com.intellij.util.xml.highlighting.*;
|
||||
import com.intellij.util.xml.impl.DefaultDomAnnotator;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomHighlightingLiteTest extends DomTestCase {
|
||||
private DomElementAnnotationsManagerImpl myAnnotationsManager;
|
||||
private MockDomFileElement myElement;
|
||||
private MockInspectionProfile myInspectionProfile;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
final InspectionToolRegistrar registrar = new InspectionToolRegistrar(SearchableOptionsRegistrar.getInstance());
|
||||
registrar.registerTools(new InspectionToolProvider[0]);
|
||||
final InspectionProfileManager inspectionProfileManager = new InspectionProfileManager(registrar, new MockSchemesManagerFactory());
|
||||
myInspectionProfile = new MockInspectionProfile();
|
||||
myAnnotationsManager = new DomElementAnnotationsManagerImpl(getProject()) {
|
||||
|
||||
@Override
|
||||
protected InspectionProfile getInspectionProfile(final DomFileElement fileElement) {
|
||||
|
||||
return myInspectionProfile;
|
||||
}
|
||||
};
|
||||
|
||||
final XmlFile file = createXmlFile("<a/>");
|
||||
final MockDomElement rootElement = new MockDomElement() {
|
||||
@Override
|
||||
@Nullable
|
||||
public XmlElement getXmlElement() {
|
||||
return getXmlTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlTag getXmlTag() {
|
||||
return file.getDocument().getRootTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getDomElementType() {
|
||||
return DomElement.class;
|
||||
}
|
||||
};
|
||||
|
||||
myElement = new MockDomFileElement() {
|
||||
@Override
|
||||
@Nullable
|
||||
public XmlElement getXmlElement() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public XmlFile getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomElement getParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DomElement getRootElement() {
|
||||
return rootElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getRootElementClass() {
|
||||
return DomElement.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void testEmptyProblemDescriptorInTheBeginning() throws Throwable {
|
||||
assertEmptyHolder(myAnnotationsManager.getProblemHolder(myElement));
|
||||
}
|
||||
|
||||
private static void assertEmptyHolder(final DomElementsProblemsHolder holder) {
|
||||
assertFalse(holder instanceof DomElementsProblemsHolderImpl);
|
||||
assertEmpty(holder.getAllProblems());
|
||||
}
|
||||
|
||||
public void testProblemDescriptorIsCreated() throws Throwable {
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MyDomElementsInspection.class);
|
||||
final DomElementsProblemsHolderImpl holder = assertNotEmptyHolder(myAnnotationsManager.getProblemHolder(myElement));
|
||||
assertEmpty(holder.getAllProblems());
|
||||
assertEmpty(holder.getAllProblems(new MyDomElementsInspection()));
|
||||
}
|
||||
|
||||
private static DomElementsProblemsHolderImpl assertNotEmptyHolder(final DomElementsProblemsHolder holder1) {
|
||||
return assertInstanceOf(holder1, DomElementsProblemsHolderImpl.class);
|
||||
}
|
||||
|
||||
public void testInspectionMarkedAsPassedAfterAppend() throws Throwable {
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MyDomElementsInspection.class);
|
||||
final DomElementsProblemsHolderImpl holder = (DomElementsProblemsHolderImpl)myAnnotationsManager.getProblemHolder(myElement);
|
||||
assertTrue(holder.isInspectionCompleted(MyDomElementsInspection.class));
|
||||
assertFalse(holder.isInspectionCompleted(DomElementsInspection.class));
|
||||
}
|
||||
|
||||
public void testHolderRecreationAfterChange() throws Throwable {
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MyDomElementsInspection.class);
|
||||
assertTrue(DomElementAnnotationsManagerImpl.isHolderUpToDate(myElement));
|
||||
final DomElementsProblemsHolder holder = myAnnotationsManager.getProblemHolder(myElement);
|
||||
|
||||
myElement.incModificationCount();
|
||||
assertFalse(DomElementAnnotationsManagerImpl.isHolderUpToDate(myElement));
|
||||
assertSame(holder, myAnnotationsManager.getProblemHolder(myElement));
|
||||
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MyDomElementsInspection.class);
|
||||
assertNotSame(holder, assertNotEmptyHolder(myAnnotationsManager.getProblemHolder(myElement)));
|
||||
}
|
||||
|
||||
public void testMockDomInspection() throws Throwable {
|
||||
myElement.setFileDescription(new MyNonHighlightingDomFileDescription());
|
||||
assertInstanceOf(myAnnotationsManager.getMockInspection(myElement), MockDomInspection.class);
|
||||
}
|
||||
|
||||
public void testMockAnnotatingDomInspection() throws Throwable {
|
||||
myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
|
||||
assertInstanceOf(myAnnotationsManager.getMockInspection(myElement), MockAnnotatingDomInspection.class);
|
||||
}
|
||||
|
||||
public void testNoMockInspection() throws Throwable {
|
||||
myElement.setFileDescription(new MyNonHighlightingDomFileDescription());
|
||||
myInspectionProfile.setInspectionTools(new MyDomElementsInspection());
|
||||
assertNull(myAnnotationsManager.getMockInspection(myElement));
|
||||
}
|
||||
|
||||
public void testDefaultAnnotator() throws Throwable {
|
||||
final DefaultDomAnnotator annotator = new DefaultDomAnnotator() {
|
||||
@Override
|
||||
protected DomElementAnnotationsManagerImpl getAnnotationsManager(final DomElement element) {
|
||||
return myAnnotationsManager;
|
||||
}
|
||||
};
|
||||
final StringBuilder s = new StringBuilder();
|
||||
final ArrayList<Annotation> toFill = new ArrayList<Annotation>();
|
||||
final MyDomElementsInspection inspection = new MyDomElementsInspection() {
|
||||
|
||||
@Override
|
||||
public void checkFileElement(final DomFileElement fileElement, final DomElementAnnotationHolder holder) {
|
||||
s.append("visited");
|
||||
}
|
||||
};
|
||||
annotator.runInspection(inspection, myElement, toFill);
|
||||
assertEquals("visited", s.toString());
|
||||
final DomElementsProblemsHolderImpl holder = assertNotEmptyHolder(myAnnotationsManager.getProblemHolder(myElement));
|
||||
assertEmpty(toFill);
|
||||
|
||||
annotator.runInspection(inspection, myElement, toFill);
|
||||
assertEquals("visited", s.toString());
|
||||
assertSame(holder, assertNotEmptyHolder(myAnnotationsManager.getProblemHolder(myElement)));
|
||||
assertEmpty(toFill);
|
||||
}
|
||||
|
||||
public void testHighlightStatus_MockDomInspection() throws Throwable {
|
||||
myElement.setFileDescription(new MyNonHighlightingDomFileDescription());
|
||||
assertEquals(DomHighlightStatus.NONE, myAnnotationsManager.getHighlightStatus(myElement));
|
||||
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MockDomInspection.class);
|
||||
assertEquals(DomHighlightStatus.INSPECTIONS_FINISHED, myAnnotationsManager.getHighlightStatus(myElement));
|
||||
}
|
||||
public void testHighlightStatus_MockAnnotatingDomInspection() throws Throwable {
|
||||
myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
|
||||
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MockAnnotatingDomInspection.class);
|
||||
assertEquals(DomHighlightStatus.INSPECTIONS_FINISHED, myAnnotationsManager.getHighlightStatus(myElement));
|
||||
}
|
||||
|
||||
public void testHighlightStatus_OtherInspections() throws Throwable {
|
||||
myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
|
||||
final MyDomElementsInspection inspection = new MyDomElementsInspection() {
|
||||
|
||||
@Override
|
||||
public ProblemDescriptor[] checkFile(@NotNull final PsiFile file, @NotNull final InspectionManager manager,
|
||||
final boolean isOnTheFly) {
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), this.getClass());
|
||||
return new ProblemDescriptor[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkFileElement(final DomFileElement fileElement, final DomElementAnnotationHolder holder) {
|
||||
}
|
||||
};
|
||||
HighlightDisplayKey.register(inspection.getShortName());
|
||||
myInspectionProfile.setInspectionTools(inspection);
|
||||
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MockAnnotatingDomInspection.class);
|
||||
assertEquals(DomHighlightStatus.ANNOTATORS_FINISHED, myAnnotationsManager.getHighlightStatus(myElement));
|
||||
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), inspection.getClass());
|
||||
assertEquals(DomHighlightStatus.INSPECTIONS_FINISHED, myAnnotationsManager.getHighlightStatus(myElement));
|
||||
}
|
||||
|
||||
public void testHighlightStatus_OtherInspections2() throws Throwable {
|
||||
myElement.setFileDescription(new DomFileDescription(DomElement.class, "a"));
|
||||
final MyDomElementsInspection inspection = new MyDomElementsInspection() {
|
||||
|
||||
@Override
|
||||
public ProblemDescriptor[] checkFile(@NotNull final PsiFile file, @NotNull final InspectionManager manager,
|
||||
final boolean isOnTheFly) {
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), this.getClass());
|
||||
return new ProblemDescriptor[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkFileElement(final DomFileElement fileElement, final DomElementAnnotationHolder holder) {
|
||||
}
|
||||
};
|
||||
HighlightDisplayKey.register(inspection.getShortName());
|
||||
myInspectionProfile.setInspectionTools(inspection);
|
||||
myInspectionProfile.setEnabled(inspection, false);
|
||||
|
||||
myAnnotationsManager.appendProblems(myElement, new DomElementAnnotationHolderImpl(), MockAnnotatingDomInspection.class);
|
||||
assertEquals(DomHighlightStatus.INSPECTIONS_FINISHED, myAnnotationsManager.getHighlightStatus(myElement));
|
||||
}
|
||||
|
||||
public void testRequiredAttributeWithoutAttributeValue() throws Throwable {
|
||||
final MyElement element = createElement("<a id />", MyElement.class);
|
||||
new MyBasicDomElementsInspection().checkDomElement(element.getId(), new DomElementAnnotationHolderImpl(), DomHighlightingHelperImpl.INSTANCE);
|
||||
}
|
||||
|
||||
private class MyDomElementsInspection extends DomElementsInspection {
|
||||
public MyDomElementsInspection() {
|
||||
super(DomElement.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
throw new UnsupportedOperationException("Method getGroupDisplayName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
throw new UnsupportedOperationException("Method getDisplayName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "xxx";
|
||||
}
|
||||
}
|
||||
|
||||
private class MyBasicDomElementsInspection extends BasicDomElementsInspection {
|
||||
public MyBasicDomElementsInspection() {
|
||||
super(DomElement.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
throw new UnsupportedOperationException("Method getGroupDisplayName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
throw new UnsupportedOperationException("Method getDisplayName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkDomElement(final DomElement element, final DomElementAnnotationHolder holder, final DomHighlightingHelper helper) {
|
||||
super.checkDomElement(element, holder, helper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "xxx";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class MyNonHighlightingDomFileDescription extends DomFileDescription {
|
||||
public MyNonHighlightingDomFileDescription() {
|
||||
super(DomElement.class, "a");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAutomaticHighlightingEnabled() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
@Convert(soft=true, value=JvmPsiTypeConverter.class)
|
||||
@Required GenericAttributeValue<PsiType> getId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.codeInsight.navigation.actions.GotoDeclarationAction;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.PomTargetPsiElement;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.testFramework.Timings;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.xml.impl.DomFileElementImpl;
|
||||
import com.intellij.util.xml.impl.DomManagerImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomIncludesTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
public void testGetChildrenHonorsIncludes() throws Throwable {
|
||||
final MyElement rootElement = createDomFile("a.xml", "<root xmlns:xi=\"http://www.w3.org/2001/XInclude\">" +
|
||||
"<xi:include href=\"b.xml\" xpointer=\"xpointer(/xxx/*)\"/>" +
|
||||
"<child xxx=\"a\"/>" +
|
||||
"</root>");
|
||||
createFile("b.xml", "<xxx><child xxx=\"b\"/></xxx>");
|
||||
final List<DomIncludesTest.Child> children = rootElement.getChildren();
|
||||
Consumer<MyElement> consumer1 = new Consumer<MyElement>() {
|
||||
@Override
|
||||
public void consume(final MyElement element) {
|
||||
assertFalse(element.getXmlElement().isPhysical());
|
||||
assertEquals(rootElement, element.getParent());
|
||||
assertEquals(DomUtil.getFileElement(rootElement), DomUtil.getFileElement(element));
|
||||
assertEquals("b", element.getXxx().getValue());
|
||||
}
|
||||
};
|
||||
Consumer<MyElement> consumer2 = new Consumer<MyElement>() {
|
||||
@Override
|
||||
public void consume(final MyElement element) {
|
||||
assertTrue(element.getXmlElement().isPhysical());
|
||||
assertEquals(rootElement, element.getParent());
|
||||
assertEquals(DomUtil.getFileElement(rootElement), DomUtil.getFileElement(element));
|
||||
assertEquals("a", element.getXxx().getValue());
|
||||
}
|
||||
};
|
||||
assertOrderedCollection(children, new Consumer[] { consumer1, consumer2 });
|
||||
}
|
||||
|
||||
public void testNamespaces() throws Throwable {
|
||||
final MyElement rootElement = createDomFile("a.xml", "<root xmlns:xi=\"http://www.w3.org/2001/XInclude\" xmlns:foo=\"foo\">" +
|
||||
"<xi:include href=\"b.xml\" xpointer=\"xpointer(/xxx/*)\"/>" +
|
||||
"<foo:boy xxx=\"a\"/>" +
|
||||
"</root>");
|
||||
DomUtil.getFileElement(rootElement).getFileDescription().registerNamespacePolicy("foo", "foo");
|
||||
|
||||
createFile("b.xml", "<xxx xmlns:foo=\"foo\"><foo:boy xxx=\"b\"/></xxx>");
|
||||
final List<Boy> children = rootElement.getBoys();
|
||||
assertOrderedCollection(children, new Consumer<Boy>() {
|
||||
@Override
|
||||
public void consume(final Boy element) {
|
||||
assertFalse(element.getXmlElement().isPhysical());
|
||||
assertEquals(rootElement, element.getParent());
|
||||
assertEquals(DomUtil.getFileElement(rootElement), DomUtil.getFileElement(element));
|
||||
assertEquals("b", element.getXxx().getValue());
|
||||
}
|
||||
}, new Consumer<Boy>() {
|
||||
@Override
|
||||
public void consume(final Boy element) {
|
||||
assertTrue(element.getXmlElement().isPhysical());
|
||||
assertEquals(rootElement, element.getParent());
|
||||
assertEquals(DomUtil.getFileElement(rootElement), DomUtil.getFileElement(element));
|
||||
assertEquals("a", element.getXxx().getValue());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testEqualsWithMultiThreadedIncludes() throws Throwable {
|
||||
final MyElement rootElement = createDomFile("a.xml", "<root xmlns:xi=\"http://www.w3.org/2001/XInclude\">" +
|
||||
"<xi:include href=\"b.xml\" xpointer=\"xpointer(/xxx/*)\"/>" +
|
||||
"</root>");
|
||||
|
||||
final PsiFile fileB = createFile("b.xml",
|
||||
"<xxx><boy/><xi:include href=\"c.xml\" xpointer=\"xpointer(/xxx/*)\"/><child/><xi:include href=\"c.xml\" xpointer=\"xpointer(/xxx/*)\"/></xxx>");
|
||||
final PsiFile fileC = createFile("c.xml",
|
||||
"<xxx><child/><xi:include href=\"d.xml\" xpointer=\"xpointer(/xxx/*)\"/><boy/><xi:include href=\"d.xml\" xpointer=\"xpointer(/xxx/*)\"/></xxx>");
|
||||
final PsiFile fileD = createFile("d.xml",
|
||||
"<xxx><boy/><xi:include href=\"e.xml\" xpointer=\"xpointer(/xxx/*)\"/><child/><xi:include href=\"e.xml\" xpointer=\"xpointer(/xxx/*)\"/></xxx>");
|
||||
final PsiFile fileE = createFile("e.xml",
|
||||
"<xxx><boy/><child/><boy/><child/><boy/><child/><boy/><child/><boy/><child/><boy/><child/></xxx>");
|
||||
final int threadCount = 100;
|
||||
final int iterationCount = Timings.adjustAccordingToMySpeed(800, true);
|
||||
System.out.println("iterationCount = " + iterationCount);
|
||||
|
||||
final CountDownLatch finished = new CountDownLatch(threadCount);
|
||||
final AtomicReference<Exception> ex = new AtomicReference<Exception>();
|
||||
|
||||
Thread[] threads = new Thread[threadCount];
|
||||
for (int j = 0; j < threadCount; j++) {
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int k = 0; k < iterationCount; k++) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
final List<Boy> boys = rootElement.getBoys();
|
||||
Thread.yield();
|
||||
final List<Child> children = rootElement.getChildren();
|
||||
Thread.yield();
|
||||
assertEquals(boys, rootElement.getBoys());
|
||||
assertEquals(children, rootElement.getChildren());
|
||||
}
|
||||
catch (Exception e) {
|
||||
ex.set(e);
|
||||
}
|
||||
finally {
|
||||
finished.countDown();
|
||||
}
|
||||
}
|
||||
});
|
||||
Thread.yield();
|
||||
}
|
||||
}
|
||||
};
|
||||
threads[j] = thread;
|
||||
thread.start();
|
||||
}
|
||||
|
||||
for (int i = 0; i < iterationCount; i++) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
fileB.getViewProvider().getDocument().insertString(0, " ");
|
||||
fileD.getViewProvider().getDocument().insertString(0, " ");
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); //clear xinclude caches
|
||||
}
|
||||
});
|
||||
Thread.sleep(10);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
fileC.getViewProvider().getDocument().insertString(0, " ");
|
||||
fileE.getViewProvider().getDocument().insertString(0, " ");
|
||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); //clear xinclude caches
|
||||
}
|
||||
});
|
||||
Thread.sleep(10);
|
||||
}
|
||||
|
||||
finished.await();
|
||||
for (Thread thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
final Exception exception = ex.get();
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
|
||||
public void testNavigationToIncluded() throws Throwable {
|
||||
final MyElement rootElement = createDomFile("a.xml", "<root xmlns:xi=\"http://www.w3.org/2001/XInclude\">" +
|
||||
"<xi:include href=\"b.xml\" xpointer=\"xpointer(/xxx/*)\"/>" +
|
||||
"<child ref=\"b\"/>" +
|
||||
"</root>");
|
||||
final XmlFile includedFile = (XmlFile) createFile("b.xml", "<xxx><child xxx=\"b\"/></xxx>");
|
||||
final List<Child> children = rootElement.getChildren();
|
||||
final MyElement domTarget = children.get(0);
|
||||
final GenericAttributeValue<Child> ref = children.get(1).getRef();
|
||||
final MyElement value = ref.getValue();
|
||||
assertEquals(domTarget, value);
|
||||
|
||||
myFixture.configureFromTempProjectFile("a.xml");
|
||||
|
||||
final int offset = ref.getXmlAttributeValue().getTextRange().getStartOffset() + 1;
|
||||
myFixture.getEditor().getCaretModel().moveToOffset(offset);
|
||||
final PsiElement target = GotoDeclarationAction.findTargetElement(getProject(), myFixture.getEditor(), offset);
|
||||
PsiElement element = ((DomTarget)((PomTargetPsiElement)target).getTarget()).getNavigationElement();
|
||||
// assertSame(PomService.convertToPsi(DomTarget.getTarget(domTarget)), target);
|
||||
assertSame(includedFile.getDocument().getRootTag().getSubTags()[0].getAttributes()[0].getValueElement(), element);
|
||||
}
|
||||
|
||||
private MyElement createDomFile(final String fileName, final String fileText) throws IOException {
|
||||
final XmlFile xmlFile = (XmlFile) createFile(fileName, fileText);
|
||||
final DomFileElementImpl<MyElement> element = getDomManager().getFileElement(xmlFile, MyElement.class, xmlFile.getDocument().getRootTag().getName());
|
||||
return element.getRootElement();
|
||||
}
|
||||
|
||||
private PsiFile createFile(final String fileName, final String fileText) throws IOException {
|
||||
final VirtualFile file = myFixture.getTempDirFixture().createFile(fileName);
|
||||
VfsUtil.saveText(file, fileText);
|
||||
return getPsiManager().findFile(file);
|
||||
}
|
||||
|
||||
private DomManagerImpl getDomManager() {
|
||||
return DomManagerImpl.getDomManager(getProject());
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
|
||||
List<Child> getChildren();
|
||||
|
||||
List<Boy> getBoys();
|
||||
|
||||
@NameValue
|
||||
GenericAttributeValue<String> getXxx();
|
||||
|
||||
GenericAttributeValue<Child> getRef();
|
||||
|
||||
}
|
||||
|
||||
@Namespace("foo")
|
||||
public interface Boy extends MyElement {
|
||||
|
||||
}
|
||||
|
||||
public interface Child extends MyElement {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomModelMergingTest extends DomTestCase{
|
||||
private ModelMerger myMerger;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myMerger = new ModelMergerImpl();
|
||||
}
|
||||
|
||||
public void testVisitor() throws Throwable {
|
||||
final MyElement element1 = createElement("", MyElement.class);
|
||||
final MyElement foo1 = element1.getFoo();
|
||||
final MyElement bar1 = element1.addBar();
|
||||
final MyElement bar2 = element1.addBar();
|
||||
|
||||
final MyElement element2 = createElement("", MyElement.class);
|
||||
final MyElement foo2 = element2.getFoo();
|
||||
final MyElement bar3 = element2.addBar();
|
||||
|
||||
final MyElement element = myMerger.mergeModels(MyElement.class, element1, element2);
|
||||
final MyElement foo = element.getFoo();
|
||||
assertEquals(foo, myMerger.mergeModels(MyElement.class, foo1, foo2));
|
||||
|
||||
final int[] count = new int[]{0};
|
||||
element.accept(new DomElementVisitor() {
|
||||
@Override
|
||||
public void visitDomElement(DomElement _element) {
|
||||
count[0]++;
|
||||
assertEquals(_element, element);
|
||||
}
|
||||
});
|
||||
assertEquals(1, count[0]);
|
||||
|
||||
count[0] = 0;
|
||||
final Set<DomElement> result = new HashSet<DomElement>();
|
||||
element.acceptChildren(new DomElementVisitor() {
|
||||
@Override
|
||||
public void visitDomElement(DomElement element) {
|
||||
count[0]++;
|
||||
result.add(element);
|
||||
}
|
||||
});
|
||||
assertEquals(new HashSet(Arrays.asList(foo, bar1, bar2, bar3)).toString().replace(",", "\n"), result.toString().replace(",", "\n"));
|
||||
assertEquals(new HashSet(Arrays.asList(foo, bar1, bar2, bar3)), result);
|
||||
assertEquals(4, count[0]);
|
||||
}
|
||||
|
||||
public void testValidity() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final MyElement element = createElement("", MyElement.class);
|
||||
final MyElement bar1 = element.addBar();
|
||||
final MyElement bar2 = element.addBar();
|
||||
final MyElement merged = myMerger.mergeModels(MyElement.class, bar1, bar2);
|
||||
assertTrue(merged.isValid());
|
||||
bar2.undefine();
|
||||
assertFalse(merged.isValid());
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
MyElement getFoo();
|
||||
List<MyElement> getBars();
|
||||
MyElement addBar();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
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.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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.impl.PsiManagerImpl;
|
||||
import com.intellij.psi.impl.meta.MetaRegistry;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.PlatformTestUtil;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import com.intellij.xml.impl.dtd.XmlNSDescriptorImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomPerformanceTest extends DomHardCoreTestCase{
|
||||
|
||||
public void testVisitorPerformance() throws Throwable {
|
||||
final MyElement element = createElement("<!DOCTYPE faces-config PUBLIC\n" +
|
||||
" \"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN\"\n" +
|
||||
" \"http://java.sun.com/dtd/web-facesconfig_1_1.dtd\">", MyElement.class);
|
||||
|
||||
MetaRegistry.bindDataToElement(DomUtil.getFile(element).getDocument(), new XmlNSDescriptorImpl());
|
||||
|
||||
final MyElement child = element.addChildElement();
|
||||
child.getAttr().setValue("239");
|
||||
child.getChild239().getAttr().setValue("42");
|
||||
child.getChild().getAttr().setValue("42xx");
|
||||
child.getChild2().getAttr().setValue("42yy");
|
||||
child.addChildElement().getChild().addFooChild().getAttr().setValue("xxx");
|
||||
child.addChildElement().addFooChild().getAttr().setValue("yyy");
|
||||
child.addChildElement().addFooChild().addBarChild().addBarChild().addChildElement().getChild().getAttr().setValue("xxx");
|
||||
child.addChildElement().addBarComposite().setValue("ssss");
|
||||
child.addBarChild().getChild2().getAttr().setValue("234178956023");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < 239; i++) {
|
||||
element.addChildElement().copyFrom(child);
|
||||
}
|
||||
IdeaTestUtil.assertTiming("", 30000, System.currentTimeMillis() - start);
|
||||
|
||||
final MyElement newElement = createElement(DomUtil.getFile(element).getText(), MyElement.class);
|
||||
|
||||
//ProfilingUtil.startCPUProfiling();
|
||||
PlatformTestUtil.startPerformanceTest(getTestName(false), 200, new ThrowableRunnable() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
newElement.acceptChildren(new DomElementVisitor() {
|
||||
@Override
|
||||
public void visitDomElement(DomElement element) {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
});
|
||||
/*
|
||||
try {
|
||||
ProfilingUtil.captureCPUSnapshot("aaa");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}).cpuBound().assertTiming();
|
||||
}
|
||||
|
||||
public void testShouldntParseNonDomFiles() throws Throwable {
|
||||
for (int i = 0; i < 420; i++) {
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyChildElement.class, "foo") {
|
||||
|
||||
@Override
|
||||
public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
|
||||
fail();
|
||||
return super.isMyFile(file, module);
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyChildElement.class, "bar") {
|
||||
|
||||
@Override
|
||||
public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
|
||||
fail();
|
||||
return super.isMyFile(file, module);
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
}
|
||||
|
||||
getDomManager().createMockElement(MyChildElement.class, null, true);
|
||||
|
||||
@NotNull final VirtualFile virtualFile = createFile("a.xml", "").getVirtualFile();
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
|
||||
final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(virtualFile.getOutputStream(this)));
|
||||
writer.write("<root>\n");
|
||||
for (int i = 0; i < 23942; i++) {
|
||||
writer.write("<bar/>\n");
|
||||
}
|
||||
writer.write("</root>");
|
||||
writer.close();
|
||||
virtualFile.refresh(false, false);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
((PsiManagerImpl)getPsiManager()).getFileManager().cleanupForNextTest();
|
||||
final XmlFile file = (XmlFile)getPsiManager().findFile(virtualFile);
|
||||
assertFalse(file.getNode().isParsed());
|
||||
assertTrue(StringUtil.isNotEmpty(file.getText()));
|
||||
PlatformTestUtil.startPerformanceTest("", 100, new ThrowableRunnable() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
assertNull(getDomManager().getFileElement(file));
|
||||
}
|
||||
}).cpuBound().assertTiming();
|
||||
assertFalse(file.getNode().isParsed());
|
||||
}
|
||||
|
||||
public void testDontParseNamespacedDomFiles() throws Exception {
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyNamespacedElement.class, "foo") {
|
||||
@Override
|
||||
protected void initializeFileDescription() {
|
||||
registerNamespacePolicy("project", "project");
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
|
||||
XmlFile file = (XmlFile)createFile("a.xml", "<foo xmlns=\"project\"/>");
|
||||
assertFalse(file.getNode().isParsed());
|
||||
assertNotNull(DomManager.getDomManager(getProject()).getFileElement(file, MyNamespacedElement.class));
|
||||
assertFalse(file.getNode().isParsed());
|
||||
|
||||
file = (XmlFile)createFile("a.xml", "<foo xmlns=\"project2\"/>");
|
||||
assertFalse(file.getNode().isParsed());
|
||||
assertNull(DomManager.getDomManager(getProject()).getFileElement(file, MyNamespacedElement.class));
|
||||
assertFalse(file.getNode().isParsed());
|
||||
}
|
||||
|
||||
@Namespace("project")
|
||||
public interface MyNamespacedElement extends DomElement {
|
||||
|
||||
}
|
||||
public interface MyChildElement extends DomElement {
|
||||
@Attribute
|
||||
@Required
|
||||
GenericAttributeValue<String> getAttr();
|
||||
|
||||
List<MyFooConcreteElement> getFooChildren();
|
||||
|
||||
MyFooConcreteElement addFooChild();
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
@Attribute
|
||||
@Required
|
||||
GenericAttributeValue<String> getAttr();
|
||||
|
||||
String getValue();
|
||||
|
||||
void setValue(String s);
|
||||
|
||||
MyChildElement getChild();
|
||||
|
||||
@SubTag(value = "child", index = 1)
|
||||
MyChildElement getChild2();
|
||||
|
||||
MyChildElement getChild239();
|
||||
|
||||
List<MyElement> getChildElements();
|
||||
|
||||
MyElement addChildElement();
|
||||
|
||||
List<MyAbstractElement> getAbstractElements();
|
||||
|
||||
@SubTagList("abstract-element")
|
||||
MyBarConcreteElement addBarChild();
|
||||
|
||||
@SubTagList("abstract-element")
|
||||
MyFooConcreteElement addFooChild();
|
||||
|
||||
@SubTagsList({"child-element", "abstract-element"})
|
||||
List<MyElement> getCompositeList();
|
||||
|
||||
@SubTagsList(value = {"child-element", "abstract-element"}, tagName = "abstract-element")
|
||||
MyBarConcreteElement addBarComposite();
|
||||
|
||||
}
|
||||
|
||||
public interface MyAbstractElement extends MyElement {
|
||||
}
|
||||
|
||||
public interface MyFooConcreteElement extends MyAbstractElement {
|
||||
}
|
||||
|
||||
public interface MyBarConcreteElement extends MyAbstractElement {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class DomReferenceInjectorTest extends DomHardCoreTestCase {
|
||||
public void testBasic() throws Exception {
|
||||
MyElement element = createElement("<a><value>abc${prop}def</value></a>", MyElement.class);
|
||||
assertEquals("abc${prop}def", element.getValue().getStringValue());
|
||||
assertEquals("abc${prop}def", element.getValue().getValue());
|
||||
}
|
||||
|
||||
public void testWithInjector() throws Exception {
|
||||
MyElement element = createElement("<a><value>abc${prop}def</value></a>", MyElement.class);
|
||||
|
||||
registerInjectorFor(element, null);
|
||||
|
||||
assertEquals("abcFOOdef", element.getValue().getStringValue());
|
||||
assertEquals("abcFOOdef", element.getValue().getValue());
|
||||
}
|
||||
|
||||
public void testCorrectlyCalculateOffsetWithInjector() throws Exception {
|
||||
MyElement element = createElement("<a><value> abc${prop}def </value></a>", MyElement.class);
|
||||
|
||||
registerInjectorFor(element, null);
|
||||
|
||||
assertEquals("abcFOOdef", element.getValue().getStringValue());
|
||||
assertEquals("abcFOOdef", element.getValue().getValue());
|
||||
}
|
||||
|
||||
public void testWithInjectorAndConverter() throws Exception {
|
||||
MyElement element = createElement("<a><converted-value>abc${prop}def</converted-value></a>", MyElement.class);
|
||||
|
||||
registerInjectorFor(element, null);
|
||||
|
||||
assertEquals("abcFOOdef", element.getConvertedValue().getStringValue());
|
||||
assertEquals("abcBARdef", element.getConvertedValue().getValue());
|
||||
}
|
||||
|
||||
public void testReference() throws Exception {
|
||||
String text = "<a><value>abc${prop}def</value></a>";
|
||||
MyElement element = createElement(text, MyElement.class);
|
||||
|
||||
MyPsiElement targetElement = new MyPsiElement();
|
||||
registerInjectorFor(element, targetElement);
|
||||
|
||||
assertEquals("abcFOOdef", element.getValue().getStringValue());
|
||||
assertEquals("abcFOOdef", element.getValue().getValue());
|
||||
|
||||
assertReference(element.getValue(), targetElement, text.indexOf("${prop}") + 1);
|
||||
}
|
||||
|
||||
public void testAttribute() throws Exception {
|
||||
String text = "<a attr=\"abc${prop}def\"/>";
|
||||
MyElement element = createElement(text, MyElement.class);
|
||||
|
||||
MyPsiElement targetElement = new MyPsiElement();
|
||||
registerInjectorFor(element, targetElement);
|
||||
|
||||
assertEquals("abcFOOdef", element.getAttr().getStringValue());
|
||||
assertEquals("abcFOOdef", element.getAttr().getValue());
|
||||
|
||||
assertReference(element.getAttr(), targetElement, text.indexOf("${prop}") + 1);
|
||||
}
|
||||
|
||||
private void registerInjectorFor(DomElement element, PsiElement targetElement) {
|
||||
DomUtil.getFileElement(element).getFileDescription().registerReferenceInjector(new MyInjector(targetElement));
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
GenericDomValue<String> getValue();
|
||||
|
||||
@Convert(MyConverter.class)
|
||||
GenericDomValue<String> getConvertedValue();
|
||||
|
||||
GenericAttributeValue<String> getAttr();
|
||||
}
|
||||
|
||||
public static class MyConverter extends Converter<String> {
|
||||
@Override
|
||||
public String fromString(@Nullable @NonNls String s, ConvertContext context) {
|
||||
return s == null ? null : s.replaceAll("FOO", "BAR");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(@Nullable String s, ConvertContext context) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyPsiElement implements PsiElement {
|
||||
@Override
|
||||
@NotNull
|
||||
public Project getProject() throws PsiInvalidElementAccessException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Language getLanguage() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiManager getManager() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiElement[] getChildren() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getFirstChild() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getLastChild() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getNextSibling() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getPrevSibling() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getContainingFile() throws PsiInvalidElementAccessException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getTextRange() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartOffsetInParent() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextLength() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement findElementAt(int offset) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference findReferenceAt(int offset) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextOffset() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public char[] textToCharArray() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getNavigationElement() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getOriginalElement() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean textMatches(@NotNull @NonNls CharSequence text) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean textMatches(@NotNull PsiElement element) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean textContains(char c) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptChildren(@NotNull PsiElementVisitor visitor) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement copy() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement add(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addBefore(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addAfter(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAdd(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addRange(PsiElement first, PsiElement last) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addRangeBefore(@NotNull PsiElement first, @NotNull PsiElement last, PsiElement anchor)
|
||||
throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addRangeAfter(PsiElement first, PsiElement last, PsiElement anchor) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkDelete() throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteChildRange(PsiElement first, PsiElement last) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement replace(@NotNull PsiElement newElement) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWritable() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiReference[] getReferences() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getCopyableUserData(Key<T> key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void putCopyableUserData(Key<T> key, T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@Nullable PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getContext() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPhysical() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public GlobalSearchScope getResolveScope() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public SearchScope getUseScope() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ASTNode getNode() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEquivalentTo(PsiElement another) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getUserData(@NotNull Key<T> key) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon(int flags) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyInjector implements DomReferenceInjector {
|
||||
private final PsiElement myMyTargetElement;
|
||||
|
||||
public MyInjector(PsiElement myTargetElement) {
|
||||
myMyTargetElement = myTargetElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolveString(@Nullable String unresolvedText, @NotNull ConvertContext context) {
|
||||
return unresolvedText == null ? null : unresolvedText.replaceAll("\\$\\{prop\\}", "FOO");
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiReference[] inject(@Nullable String unresolvedText, @NotNull final PsiElement element, @NotNull ConvertContext context) {
|
||||
final String prop = "${prop}";
|
||||
int index = unresolvedText == null ? -1 : unresolvedText.indexOf(prop);
|
||||
if (index == -1) return PsiReference.EMPTY_ARRAY;
|
||||
|
||||
TextRange textRange = ElementManipulators.getValueTextRange(element);
|
||||
final TextRange refRange = TextRange.from(textRange.getStartOffset() + index, prop.length());
|
||||
|
||||
return new PsiReference[] {
|
||||
new PsiReference() {
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement() {
|
||||
return refRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement resolve() {
|
||||
return myMyTargetElement;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getCanonicalText() {
|
||||
return prop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSoft() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.XmlTagValue;
|
||||
import com.intellij.util.xml.impl.GenericDomValueReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomReferencesTest extends DomHardCoreTestCase {
|
||||
|
||||
public void testMetaData() throws Throwable {
|
||||
final MyElement element = createElement("");
|
||||
element.getName().setValue("A");
|
||||
final XmlTag tag = element.getXmlTag();
|
||||
final DomMetaData metaData = assertInstanceOf(tag.getMetaData(), DomMetaData.class);
|
||||
assertEquals(tag, metaData.getDeclaration());
|
||||
assertOrderedEquals(metaData.getDependences(), DomUtil.getFileElement(element), tag);
|
||||
assertEquals("A", metaData.getName());
|
||||
assertEquals("A", metaData.getName(null));
|
||||
|
||||
metaData.setName("B");
|
||||
assertEquals("B", element.getName().getValue());
|
||||
}
|
||||
|
||||
public void testNameReference() throws Throwable {
|
||||
final MyElement element = createElement("<a><name>abc</name></a>");
|
||||
final DomTarget target = DomTarget.getTarget(element);
|
||||
assertNotNull(target);
|
||||
final XmlTag tag = element.getName().getXmlTag();
|
||||
assertNull(tag.getContainingFile().findReferenceAt(tag.getValue().getTextRange().getStartOffset()));
|
||||
}
|
||||
|
||||
public void testProcessingInstruction() throws Throwable {
|
||||
createElement("<a><?xml version=\"1.0\"?></a>").getXmlTag().accept(new PsiRecursiveElementVisitor() {
|
||||
@Override public void visitElement(PsiElement element) {
|
||||
super.visitElement(element);
|
||||
for (final PsiReference reference : element.getReferences()) {
|
||||
assertFalse(reference instanceof GenericDomValueReference);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testBooleanReference() throws Throwable {
|
||||
final MyElement element = createElement("<a><boolean>true</boolean></a>");
|
||||
assertVariants(assertReference(element.getBoolean()), "false", "true");
|
||||
}
|
||||
|
||||
public void testBooleanAttributeReference() throws Throwable {
|
||||
final MyElement element = createElement("<a boolean-attribute=\"true\"/>");
|
||||
final PsiReference reference = getReference(element.getBooleanAttribute());
|
||||
assertVariants(reference, "false", "true");
|
||||
|
||||
final XmlAttributeValue xmlAttributeValue = element.getBooleanAttribute().getXmlAttributeValue();
|
||||
final PsiElement psiElement = reference.getElement();
|
||||
assertEquals(xmlAttributeValue, psiElement);
|
||||
|
||||
assertEquals(new TextRange(0, "true".length()).shiftRight(1), reference.getRangeInElement());
|
||||
}
|
||||
|
||||
public void testEnumReference() throws Throwable {
|
||||
assertVariants(assertReference(createElement("<a><enum>239</enum></a>").getEnum(), null), "A", "B", "C");
|
||||
assertVariants(assertReference(createElement("<a><enum>A</enum></a>").getEnum()), "A", "B", "C");
|
||||
}
|
||||
|
||||
public void testPsiClass() throws Throwable {
|
||||
final MyElement element = createElement("<a><psi-class>java.lang.String</psi-class></a>");
|
||||
assertReference(element.getPsiClass(), PsiType.getJavaLangString(getPsiManager(), GlobalSearchScope.allScope(getProject())).resolve(),
|
||||
element.getPsiClass().getXmlTag().getValue().getTextRange().getEndOffset() - 1);
|
||||
}
|
||||
|
||||
public void testPsiType() throws Throwable {
|
||||
final MyElement element = createElement("<a><psi-type>java.lang.String</psi-type></a>");
|
||||
assertReference(element.getPsiType(), PsiType.getJavaLangString(getPsiManager(), GlobalSearchScope.allScope(getProject())).resolve());
|
||||
}
|
||||
|
||||
public void testIndentedPsiType() throws Throwable {
|
||||
final MyElement element = createElement("<a><psi-type> java.lang.Strin </psi-type></a>");
|
||||
final PsiReference psiReference = assertReference(element.getPsiType(), null);
|
||||
assertEquals(new TextRange(22, 22 + "Strin".length()), psiReference.getRangeInElement());
|
||||
}
|
||||
|
||||
public void testPsiPrimitiveType() throws Throwable {
|
||||
final MyElement element = createElement("<a><psi-type>int</psi-type></a>");
|
||||
assertReference(element.getPsiType());
|
||||
}
|
||||
|
||||
public void testPsiPrimitiveTypeArray() throws Throwable {
|
||||
final MyElement element = createElement("<a><psi-type>int[]</psi-type></a>");
|
||||
final GenericDomValue value = element.getPsiType();
|
||||
final XmlTagValue tagValue = value.getXmlTag().getValue();
|
||||
final int i = tagValue.getText().indexOf(value.getStringValue());
|
||||
assertReference(value, value.getXmlTag(), tagValue.getTextRange().getStartOffset() + i + "int".length());
|
||||
}
|
||||
|
||||
public void testPsiUnknownType() throws Throwable {
|
||||
final MyElement element = createElement("<a><psi-type>#$^%*$</psi-type></a>");
|
||||
assertReference(element.getPsiType(), null);
|
||||
}
|
||||
|
||||
public void testPsiArrayType() throws Throwable {
|
||||
final MyElement element = createElement("<a><psi-type>java.lang.String[]</psi-type></a>");
|
||||
final XmlTag tag = element.getPsiType().getXmlTag();
|
||||
final TextRange valueRange = tag.getValue().getTextRange();
|
||||
final PsiReference reference = tag.getContainingFile().findReferenceAt(valueRange.getStartOffset() + "java.lang.".length());
|
||||
assertNotNull(reference);
|
||||
assertEquals(PsiType.getJavaLangString(getPsiManager(), GlobalSearchScope.allScope(getProject())).resolve(), reference.resolve());
|
||||
assertEquals("<psi-type>java.lang.".length(), reference.getRangeInElement().getStartOffset());
|
||||
assertEquals("String".length(), reference.getRangeInElement().getLength());
|
||||
}
|
||||
|
||||
public void testJvmArrayType() throws Throwable {
|
||||
final MyElement element = createElement("<a><jvm-psi-type>[Ljava.lang.String;</jvm-psi-type></a>");
|
||||
final XmlTag tag = element.getJvmPsiType().getXmlTag();
|
||||
final TextRange valueRange = tag.getValue().getTextRange();
|
||||
final PsiReference reference = tag.getContainingFile().findReferenceAt(valueRange.getEndOffset() - 1);
|
||||
assertNotNull(reference);
|
||||
assertEquals(PsiType.getJavaLangString(getPsiManager(), GlobalSearchScope.allScope(getProject())).resolve(), reference.resolve());
|
||||
assertEquals("<jvm-psi-type>[Ljava.lang.".length(), reference.getRangeInElement().getStartOffset());
|
||||
assertEquals("String".length(), reference.getRangeInElement().getLength());
|
||||
}
|
||||
|
||||
public void testCustomResolving() throws Throwable {
|
||||
final MyElement element = createElement("<a><string-buffer>239</string-buffer></a>");
|
||||
assertVariants(assertReference(element.getStringBuffer()), "239", "42", "foo", "zzz");
|
||||
}
|
||||
|
||||
public void testAdditionalValues() throws Throwable {
|
||||
final MyElement element = createElement("<a><string-buffer>zzz</string-buffer></a>");
|
||||
final XmlTag tag = element.getStringBuffer().getXmlTag();
|
||||
assertTrue(tag.getContainingFile().findReferenceAt(tag.getValue().getTextRange().getStartOffset()).isSoft());
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
GenericDomValue<Boolean> getBoolean();
|
||||
|
||||
GenericAttributeValue<Boolean> getBooleanAttribute();
|
||||
|
||||
@Convert(MyStringConverter.class)
|
||||
GenericDomValue<String> getConvertedString();
|
||||
|
||||
GenericDomValue<MyEnum> getEnum();
|
||||
|
||||
@NameValue GenericDomValue<String> getName();
|
||||
|
||||
GenericDomValue<PsiClass> getPsiClass();
|
||||
|
||||
GenericDomValue<PsiType> getPsiType();
|
||||
|
||||
@Convert(JvmPsiTypeConverter.class)
|
||||
GenericDomValue<PsiType> getJvmPsiType();
|
||||
|
||||
List<GenericDomValue<MyEnum>> getEnumChildren();
|
||||
|
||||
@Convert(MyStringBufferConverter.class)
|
||||
GenericDomValue<StringBuffer> getStringBuffer();
|
||||
|
||||
MyAbstractElement getChild();
|
||||
|
||||
MyElement getRecursiveChild();
|
||||
|
||||
List<MyGenericValue> getMyGenericValues();
|
||||
|
||||
MyGenericValue getMyAnotherGenericValue();
|
||||
}
|
||||
|
||||
@Convert(MyStringConverter.class)
|
||||
public interface MyGenericValue extends GenericDomValue<String> {
|
||||
|
||||
}
|
||||
|
||||
public interface MySomeInterface {
|
||||
GenericValue<PsiType> getFoo();
|
||||
}
|
||||
|
||||
public interface MyAbstractElement extends DomElement {
|
||||
GenericAttributeValue<String> getFubar239();
|
||||
GenericAttributeValue<Runnable> getFubar();
|
||||
}
|
||||
|
||||
public interface MyFooElement extends MyAbstractElement, MySomeInterface {
|
||||
@Override
|
||||
GenericDomValue<PsiType> getFoo();
|
||||
|
||||
GenericAttributeValue<Set> getFubar2();
|
||||
}
|
||||
|
||||
public interface MyBarElement extends MyAbstractElement {
|
||||
GenericDomValue<StringBuffer> getBar();
|
||||
}
|
||||
|
||||
|
||||
public enum MyEnum {
|
||||
A,B,C
|
||||
}
|
||||
|
||||
public static class MyStringConverter extends ResolvingConverter<String> {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<? extends String> getVariants(final ConvertContext context) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fromString(final String s, final ConvertContext context) {
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(final String s, final ConvertContext context) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyStringBufferConverter extends ResolvingConverter<StringBuffer> {
|
||||
|
||||
@Override
|
||||
public StringBuffer fromString(final String s, final ConvertContext context) {
|
||||
return s == null ? null : new StringBuffer(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(final StringBuffer t, final ConvertContext context) {
|
||||
return t == null ? null : t.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends StringBuffer> getVariants(final ConvertContext context) {
|
||||
return Arrays.asList(new StringBuffer("239"), new StringBuffer("42"), new StringBuffer("foo"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAdditionalVariants() {
|
||||
return Collections.singleton("zzz");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
|
||||
* Use is subject to license terms.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.lang.xml.XMLLanguage;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomSaxParserTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
public void testGetRootTagNameWithoutNamespace() throws Throwable {
|
||||
assertData("<root>", "root", null, null, null);
|
||||
}
|
||||
|
||||
public void testGetRootTagNameWithNamespaceWithEmptyPrefix() throws Throwable {
|
||||
assertData("<root xmlns=\"foo\">", "root", "foo", null, null);
|
||||
}
|
||||
|
||||
public void testGetRootTagNameWithUnfinishedAttribute() throws Throwable {
|
||||
XmlFile file = createXmlFile("<root xmlns=\"foo\" aaa>");
|
||||
ensureParsed(file);
|
||||
final XmlFileHeader header = DomService.getInstance().getXmlFileHeader(file);
|
||||
assertEquals(new XmlFileHeader("root", "foo", null, null), header);
|
||||
}
|
||||
|
||||
public void testGetRootTagNameWithNamespaceWithNonEmptyPrefix() throws Throwable {
|
||||
assertData("<bar:root xmlns=\"foo\" xmlns:bar=\"b\">", "root", "b", null, null);
|
||||
}
|
||||
|
||||
public void testGetRootTagNameWithDtdNamespace() throws Throwable {
|
||||
assertData("<!DOCTYPE ejb-jar PUBLIC\n" +
|
||||
"\"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN\"\n" +
|
||||
"\"http://java.sun.com/dtd/ejb-jar_2_0.dtd\"><root>", "root", null, "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN", "http://java.sun.com/dtd/ejb-jar_2_0.dtd");
|
||||
}
|
||||
|
||||
public void testGetRootTagNameWithDtdNamespace2() throws Throwable {
|
||||
assertData("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!DOCTYPE ejb-jar PUBLIC\n" +
|
||||
"\"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN\"\n" +
|
||||
"\"http://java.sun.com/dtd/ejb-jar_2_0.dtd\"><root>", "root", null, "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN", "http://java.sun.com/dtd/ejb-jar_2_0.dtd");
|
||||
}
|
||||
|
||||
public void testNoTag() throws Throwable {
|
||||
assertData("aaaaaaaaaaaaaaaaaaaaa", null, null, null, null);
|
||||
}
|
||||
|
||||
public void testEmptyFile() throws Throwable {
|
||||
assertData("", null, null, null, null);
|
||||
}
|
||||
|
||||
public void testInvalidContent() throws Throwable {
|
||||
assertData("<?xmlmas8v6708986><OKHD POH:&*$%*&*I8yo9", null, null, null, null);
|
||||
}
|
||||
|
||||
public void testInvalidContent2() throws Throwable {
|
||||
assertData("?xmlmas8v6708986><OKHD POH:&*$%*&*I8yo9", null, null, null, null);
|
||||
}
|
||||
|
||||
private static PsiElement ensureParsed(PsiFile file) {
|
||||
return file.findElementAt(2);
|
||||
}
|
||||
|
||||
public void testInvalidContent3() throws Throwable {
|
||||
assertData("<?xmlmas8v67089", null, null, null, null);
|
||||
}
|
||||
|
||||
public void testSubtag() throws Throwable {
|
||||
assertData("<root><foo/>", "root", null, null, null);
|
||||
}
|
||||
|
||||
public void testSpring() throws Throwable {
|
||||
assertData("<?xml version=\"1.0\" encoding=\"gbk\"?>\n" + "\n" + "\n" +
|
||||
"<beans xmlns=\"http://www.springframework.org/schema/beans\"\n" +
|
||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
|
||||
" xmlns:aop=\"http://www.springframework.org/schema/aop\"\n" +
|
||||
" xmlns:tx=\"http://www.springframework.org/schema/tx\"\n" +
|
||||
" xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd\n" +
|
||||
" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd\n" +
|
||||
" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd\">\n" +
|
||||
"</beans>", "beans", "http://www.springframework.org/schema/beans", null, null);
|
||||
}
|
||||
|
||||
public void testInternalDtd() throws Throwable {
|
||||
assertData("<?xml version=\"1.0\"?>\n" +
|
||||
"<!DOCTYPE \n" +
|
||||
" hibernate-mapping SYSTEM\n" +
|
||||
"\t\t\t\"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd\"\n" + "[\n" +
|
||||
"<!ENTITY % globals SYSTEM \"classpath://auction/persistence/globals.dtd\">\n" + "%globals;\n" + "]><a/>", "a", null, null, "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd");
|
||||
}
|
||||
|
||||
private void assertData(final String start, @Nullable final String localName, @Nullable String namespace, @Nullable String publicId, @Nullable String systemId) throws IOException, SAXException {
|
||||
XmlFileHeader expected = new XmlFileHeader(localName, namespace, publicId, systemId);
|
||||
|
||||
XmlFile file = createXmlFile(start);
|
||||
assert !file.getNode().isParsed();
|
||||
assertEquals(expected, DomService.getInstance().getXmlFileHeader(file));
|
||||
|
||||
ensureParsed(file);
|
||||
assert file.getNode().isParsed();
|
||||
assertEquals(expected, DomService.getInstance().getXmlFileHeader(file));
|
||||
}
|
||||
|
||||
private XmlFile createXmlFile(String text) {
|
||||
return (XmlFile)PsiFileFactory.getInstance(getProject()).createFileFromText("a.xml", XMLLanguage.INSTANCE, text, false, false, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,539 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
import com.intellij.util.xml.ui.DomUIFactory;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomSimpleValuesTest extends DomTestCase {
|
||||
|
||||
private MyElement createElement(final String xml) throws IncorrectOperationException {
|
||||
return createElement(xml, MyElement.class);
|
||||
}
|
||||
|
||||
public void testGetValue() throws Throwable {
|
||||
final String text = "<a>foo</a>";
|
||||
assertEquals("foo", createElement(text).getTagValue());
|
||||
assertEquals("foo", createElement(text).getValue());
|
||||
}
|
||||
|
||||
public void testSetValue() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
assertEquals("", element.getValue());
|
||||
element.setValue(239);
|
||||
assertEquals("239", element.getValue());
|
||||
assertEquals("239", element.getXmlTag().getValue().getText());
|
||||
myCallRegistry.putExpected(new DomEvent(element, false));
|
||||
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testDefineAndSet() throws Throwable {
|
||||
final MyElement element = getDomManager().getFileElement(createXmlFile(""), MyElement.class, "root").getRootElement();
|
||||
myCallRegistry.clear();
|
||||
assertNull(element.getXmlTag());
|
||||
element.setValue(42);
|
||||
assertNotNull(element.getXmlTag());
|
||||
assertEquals("42", element.getXmlTag().getValue().getText());
|
||||
final DomElement element1 = element;
|
||||
myCallRegistry.putExpected(new DomEvent(element1, true));
|
||||
myCallRegistry.putExpected(new DomEvent(element, false));
|
||||
|
||||
element.setValue((Integer)null);
|
||||
assertNull(element.getXmlTag());
|
||||
assertEquals(null, element.getValue());
|
||||
|
||||
myCallRegistry.putExpected(new DomEvent(element, false));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
}
|
||||
|
||||
|
||||
public void testSimpleConverters() throws Throwable {
|
||||
assertEquals(239, createElement("<a>239</a>").getInt());
|
||||
assertEquals(true, createElement("<a>true</a>").getBoolean());
|
||||
assertEquals("true", createElement("<a>true</a>").getBuffer().toString());
|
||||
|
||||
try {
|
||||
createElement("<a>true</a>").getInt();
|
||||
fail();
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
}
|
||||
try {
|
||||
createElement("<a>42</a>").getBoolean();
|
||||
fail();
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testComment() throws Throwable {
|
||||
assertEquals(239, createElement("<a>" +
|
||||
" <!-- some comment-->" +
|
||||
" 239" +
|
||||
" <!-- some another comment-->" +
|
||||
"</a>").getInt());
|
||||
}
|
||||
|
||||
public void testPsiClassConverter() throws Throwable {
|
||||
final String className = Object.class.getName();
|
||||
final PsiClass objectClass = getJavaFacade().findClass(className, GlobalSearchScope.allScope(getProject()));
|
||||
assertEquals(objectClass, createElement("<a>" + className + "</a>").getPsiClass());
|
||||
|
||||
assertNull(createElement("<a>abcdef</a>").getPsiClass());
|
||||
}
|
||||
|
||||
public void testEnums() throws Throwable {
|
||||
final MyElement element = createElement("<a/>", MyElement.class);
|
||||
assertNull(element.getEnum());
|
||||
|
||||
element.setEnum(DomTestCase.MyEnum.BAR);
|
||||
assertEquals(DomTestCase.MyEnum.BAR, element.getEnum());
|
||||
assertEquals(DomTestCase.MyEnum.BAR.getValue(), element.getXmlTag().getValue().getText());
|
||||
|
||||
element.setEnum(null);
|
||||
assertNull(element.getEnum());
|
||||
assertNull(element.getXmlTag());
|
||||
|
||||
element.setValue(239);
|
||||
assertNull(element.getEnum());
|
||||
}
|
||||
|
||||
public void testAttributeValues() throws Throwable {
|
||||
final MyElement element = createElement("<a attra=\"foo\"/>");
|
||||
final GenericAttributeValue<String> attributeValue = element.getAttributeValue();
|
||||
assertEquals("attra", attributeValue.getXmlElementName());
|
||||
assertEquals("foo", attributeValue.getValue());
|
||||
|
||||
final GenericAttributeValue<Integer> attr = element.getAttr();
|
||||
attr.setValue(239);
|
||||
assertEquals(239, (int)attr.getValue());
|
||||
assertEquals("239", element.getXmlTag().getAttributeValue("attr"));
|
||||
final DomElement element1 = attr;
|
||||
myCallRegistry.putExpected(new DomEvent(element1, true));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
|
||||
attr.setValue(42);
|
||||
myCallRegistry.putExpected(new DomEvent(attr, false));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
|
||||
attr.setValue(null);
|
||||
assertNull(attr.getValue());
|
||||
assertNull(element.getXmlTag().getAttributeValue("attr"));
|
||||
assertNull(element.getXmlTag().getAttribute("attr", ""));
|
||||
myCallRegistry.putExpected(new DomEvent(attr, false));
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
|
||||
assertEquals("some-attribute", element.getSomeAttribute().getXmlElementName());
|
||||
|
||||
assertNull(createElement("<a attra\"attr\"/>").getAttributeValue().getStringValue());
|
||||
assertNull(createElement("<a attra\"\"/>").getAttributeValue().getStringValue());
|
||||
assertNull(createElement("<a attra\"/>").getAttributeValue().getStringValue());
|
||||
}
|
||||
|
||||
public void testGenericValue() throws Throwable {
|
||||
final MyElement element = createElement("<a><generic-child>239</generic-child></a>");
|
||||
final GenericDomValue<Integer> integerChild = element.getGenericChild();
|
||||
assertEquals(239, (int)integerChild.getValue());
|
||||
assertEquals("239", integerChild.getStringValue());
|
||||
integerChild.setValue(42);
|
||||
assertEquals(42, (int)integerChild.getValue());
|
||||
assertEquals("42", integerChild.getStringValue());
|
||||
}
|
||||
|
||||
public void testAnnotatedGenericValue() throws Throwable {
|
||||
final MyElement element = createElement("<a><buffer>239</buffer></a>");
|
||||
element.getGenericChild().getValue();
|
||||
final GenericDomValue<StringBuffer> genericChild2 = element.getGenericChild2();
|
||||
assertEquals("239", genericChild2.getValue().toString());
|
||||
}
|
||||
|
||||
public void testSpecialCharacters() throws Throwable {
|
||||
final MyElement element = createElement("");
|
||||
element.setValue("<");
|
||||
assertEquals("<", element.getValue());
|
||||
assertEquals("<![CDATA[<]]>", element.getXmlTag().getValue().getText());
|
||||
|
||||
element.getAttributeValue().setValue("<");
|
||||
assertEquals("<", element.getAttributeValue().getValue());
|
||||
assertEquals("\"<\"", element.getXmlTag().getAttribute("attra", null).getValueElement().getText());
|
||||
}
|
||||
|
||||
public void testIndicators() throws Throwable {
|
||||
final MyElement element = createElement("<a><indicator/></a>");
|
||||
final GenericDomValue<Boolean> indicator = element.getIndicator();
|
||||
assertTrue(indicator.getValue());
|
||||
|
||||
indicator.setValue(false);
|
||||
assertFalse(indicator.getValue());
|
||||
assertNull(indicator.getStringValue());
|
||||
assertNull(indicator.getXmlTag());
|
||||
assertEquals(0, element.getXmlTag().getSubTags().length);
|
||||
putExpected(new DomEvent(indicator, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
indicator.setValue(true);
|
||||
assertTrue(indicator.getValue());
|
||||
assertEquals("", indicator.getStringValue());
|
||||
assertSame(indicator.getXmlTag(), element.getXmlTag().getSubTags()[0]);
|
||||
final DomElement element1 = indicator;
|
||||
putExpected(new DomEvent(element1, true));
|
||||
assertResultsAndClear();
|
||||
|
||||
final XmlTag tag = element.getXmlTag();
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
tag.add(createTag("<indicator/>"));
|
||||
tag.add(createTag("<indicator/>"));
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertTrue(element.isValid());
|
||||
assertTrue(element.getIndicator().getValue());
|
||||
element.getIndicator().setValue(false);
|
||||
assertFalse(element.getIndicator().getValue());
|
||||
assertEquals(0, element.getXmlTag().findSubTags("indicator").length);
|
||||
}
|
||||
|
||||
public void testConcreteGenericValue() throws Throwable {
|
||||
final ConcreteGeneric generic = createElement("", ConcreteGeneric.class);
|
||||
generic.setValue("abc");
|
||||
assertEquals("abc", generic.getValue());
|
||||
|
||||
DomUIFactory.SET_VALUE_METHOD.invoke(generic, "def");
|
||||
assertEquals("def", DomUIFactory.GET_VALUE_METHOD.invoke(generic));
|
||||
}
|
||||
|
||||
public void testConcreteGenericValueWithMethods() throws Throwable {
|
||||
final ConcreteGenericWithMethods generic = createElement("", ConcreteGenericWithMethods.class);
|
||||
generic.setValue("abc");
|
||||
assertEquals("abc", generic.getValue());
|
||||
|
||||
DomUIFactory.SET_VALUE_METHOD.invoke(generic, "def");
|
||||
assertEquals("def", DomUIFactory.GET_VALUE_METHOD.invoke(generic));
|
||||
}
|
||||
|
||||
public void testNameValueInPresentation() throws Throwable {
|
||||
final MyElement element = createElement("");
|
||||
element.getAttr().setValue(23942);
|
||||
assertEquals("23942", element.getPresentation().getElementName());
|
||||
}
|
||||
|
||||
public void testResolveToDomElement() throws Throwable {
|
||||
final RootInterface element = createElement("", RootInterface.class);
|
||||
final MyElement child1 = element.addChild();
|
||||
child1.getAttr().setValue(555);
|
||||
final MyElement child2 = element.addChild();
|
||||
child2.getAttr().setValue(777);
|
||||
|
||||
final GenericDomValue<MyElement> resolve = child2.getResolve();
|
||||
resolve.setStringValue("777");
|
||||
assertEquals(child2, resolve.getValue());
|
||||
|
||||
resolve.setValue(child1);
|
||||
assertEquals("555", resolve.getStringValue());
|
||||
assertEquals(child1, resolve.getValue());
|
||||
|
||||
resolve.setStringValue("239");
|
||||
assertNull(resolve.getValue());
|
||||
|
||||
final GenericDomValue<MyElement> resolve2 = child2.getResolve2();
|
||||
resolve2.setStringValue("777");
|
||||
assertEquals(child2, resolve2.getValue());
|
||||
}
|
||||
|
||||
public void testPlainPsiTypeConverter() throws Throwable {
|
||||
assertNull(createElement("").getPsiType());
|
||||
assertSame(PsiType.INT, createElement("<a>int</a>").getPsiType());
|
||||
final PsiType psiType = createElement("<a>java.lang.String</a>").getPsiType();
|
||||
assertEquals(CommonClassNames.JAVA_LANG_STRING, assertInstanceOf(psiType, PsiClassType.class).getCanonicalText());
|
||||
|
||||
final PsiType arrayType = createElement("<a>int[]</a>").getPsiType();
|
||||
assertTrue(arrayType instanceof PsiArrayType);
|
||||
assertSame(PsiType.INT, ((PsiArrayType) arrayType).getComponentType());
|
||||
}
|
||||
|
||||
public void testJvmPsiTypeConverter() throws Throwable {
|
||||
assertNull(createElement("").getJvmPsiType());
|
||||
assertNotNull(createElement("<a>int</a>").getJvmPsiType());
|
||||
final PsiClassType string = PsiType.getJavaLangString(getPsiManager(), GlobalSearchScope.allScope(getProject()));
|
||||
final PsiType psiType = createElement("<a>java.lang.String</a>").getJvmPsiType();
|
||||
assertEquals(CommonClassNames.JAVA_LANG_STRING, assertInstanceOf(psiType, PsiClassType.class).getCanonicalText());
|
||||
|
||||
final PsiArrayType intArray = assertInstanceOf(createElement("<a>[I</a>").getJvmPsiType(), PsiArrayType.class);
|
||||
final PsiArrayType stringArray = assertInstanceOf(createElement("<a>[Ljava.lang.String;</a>").getJvmPsiType(), PsiArrayType.class);
|
||||
assertSame(PsiType.INT, intArray.getComponentType());
|
||||
assertEquals(CommonClassNames.JAVA_LANG_STRING, assertInstanceOf(stringArray.getComponentType(), PsiClassType.class).getCanonicalText());
|
||||
|
||||
assertJvmPsiTypeToString(intArray, "[I");
|
||||
assertJvmPsiTypeToString(stringArray, "[Ljava.lang.String;");
|
||||
assertJvmPsiTypeToString(string, "java.lang.String");
|
||||
}
|
||||
|
||||
public void testValueCaching() throws Throwable {
|
||||
final GenericDomValue<String> element = createElement("<a><cached-value/></a>", MyElement.class).getCachedValue();
|
||||
assertEquals(0, ((MyConverter) element.getConverter()).fromStringCalls);
|
||||
assertEquals("", element.getValue());
|
||||
assertEquals(1, ((MyConverter) element.getConverter()).fromStringCalls);
|
||||
assertEquals("", element.getValue());
|
||||
assertEquals(1, ((MyConverter) element.getConverter()).fromStringCalls);
|
||||
element.setValue("1");
|
||||
assertEquals(1, ((MyConverter) element.getConverter()).fromStringCalls);
|
||||
assertEquals("1", element.getValue());
|
||||
assertEquals(2, ((MyConverter) element.getConverter()).fromStringCalls);
|
||||
}
|
||||
|
||||
|
||||
private void assertJvmPsiTypeToString(final PsiType type, final String expected) throws IncorrectOperationException {
|
||||
final MyElement element = createElement("");
|
||||
element.setJvmPsiType(type);
|
||||
assertEquals(expected, element.getValue());
|
||||
}
|
||||
|
||||
public void testJavaStyledElement() throws IncorrectOperationException {
|
||||
JavaStyledElement element = createElement("<tag javaStyledAttribute=\"666\"></tag>", JavaStyledElement.class);
|
||||
assertEquals(element.getJavaStyledAttribute().getXmlElementName(), "javaStyledAttribute");
|
||||
}
|
||||
|
||||
public void testGenericValueListConverter() throws Throwable {
|
||||
final MyElement element = createElement("<a><string-buffer>abc</string-buffer></a>");
|
||||
assertEquals("abc", element.getStringBuffers().get(0).getValue().toString());
|
||||
}
|
||||
|
||||
public void testConvertAnnotationOnType() throws Throwable {
|
||||
final MyElement element =
|
||||
createElement("<a>" + "<my-generic-value>abc</my-generic-value>" + "<my-foo-generic-value>abc</my-foo-generic-value>" + "");
|
||||
assertEquals("bar", element.getMyGenericValue().getValue());
|
||||
assertEquals("foo", element.getMyFooGenericValue().getValue());
|
||||
}
|
||||
|
||||
public void testEntities() throws Throwable {
|
||||
final MyElement element = createElement("<!DOCTYPE a SYSTEM \"aaa\"\n" +
|
||||
"[<!ENTITY idgenerator \"identity\">]>\n" +
|
||||
"<a attra=\"a<b\" some-attribute=\"&idgenerator;\">&xxx;+&idgenerator;+&</a>");
|
||||
assertEquals("a<b", element.getAttributeValue().getValue());
|
||||
assertEquals("identity", element.getSomeAttribute().getValue());
|
||||
// assertEquals("&xxx;+identity+&", element.getValue());
|
||||
}
|
||||
|
||||
public interface RootInterface extends DomElement {
|
||||
List<MyElement> getChildren();
|
||||
MyElement addChild();
|
||||
}
|
||||
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
@Attribute("attra")
|
||||
GenericAttributeValue<String> getAttributeValue();
|
||||
|
||||
@NameValue
|
||||
GenericAttributeValue<Integer> getAttr();
|
||||
|
||||
GenericAttributeValue<String> getSomeAttribute();
|
||||
|
||||
String getValue();
|
||||
|
||||
void setValue(Integer value);
|
||||
|
||||
@TagValue()
|
||||
int getInt();
|
||||
|
||||
void setValue(String value);
|
||||
|
||||
@TagValue()
|
||||
boolean getBoolean();
|
||||
|
||||
@TagValue()
|
||||
PsiType getPsiType();
|
||||
|
||||
@Convert(JvmPsiTypeConverter.class)
|
||||
@TagValue()
|
||||
PsiType getJvmPsiType();
|
||||
|
||||
@TagValue()
|
||||
@Convert(JvmPsiTypeConverter.class)
|
||||
void setJvmPsiType(PsiType psiType);
|
||||
|
||||
@TagValue()
|
||||
DomTestCase.MyEnum getEnum();
|
||||
|
||||
@TagValue
|
||||
void setEnum(DomTestCase.MyEnum value);
|
||||
|
||||
@TagValue()
|
||||
@Convert(StringBufferConverter.class)
|
||||
StringBuffer getBuffer();
|
||||
|
||||
@TagValue()
|
||||
PsiClass getPsiClass();
|
||||
|
||||
@TagValue()
|
||||
String getTagValue();
|
||||
|
||||
GenericDomValue<Integer> getGenericChild();
|
||||
|
||||
@SubTag("buffer")
|
||||
@Convert(StringBufferConverter.class)
|
||||
GenericDomValue<StringBuffer> getGenericChild2();
|
||||
|
||||
@SubTag(indicator = true)
|
||||
GenericDomValue<Boolean> getIndicator();
|
||||
|
||||
@Resolve(MyElement.class)
|
||||
GenericDomValue<MyElement> getResolve();
|
||||
|
||||
GenericDomValue<MyElement> getResolve2();
|
||||
|
||||
@Convert(StringBufferConverter.class)
|
||||
List<GenericDomValue<StringBuffer>> getStringBuffers();
|
||||
|
||||
@Convert(MyConverter.class) GenericDomValue<String> getCachedValue();
|
||||
|
||||
MyGenericValue getMyGenericValue();
|
||||
|
||||
@Convert(FooConverter.class)
|
||||
MyGenericValue getMyFooGenericValue();
|
||||
|
||||
}
|
||||
|
||||
@Convert(BarConverter.class)
|
||||
public interface MyGenericValue extends GenericDomValue<String> {
|
||||
}
|
||||
|
||||
@NameStrategyForAttributes(JavaNameStrategy.class)
|
||||
public interface JavaStyledElement extends DomElement {
|
||||
GenericAttributeValue<String> getJavaStyledAttribute();
|
||||
}
|
||||
|
||||
public interface ConcreteGeneric extends GenericDomValue<String> {
|
||||
}
|
||||
|
||||
public interface ConcreteGenericWithMethods extends GenericDomValue<String> {
|
||||
@Override
|
||||
String getValue();
|
||||
|
||||
@Override
|
||||
void setValue(String s);
|
||||
}
|
||||
|
||||
public void testFuhrer() throws Throwable {
|
||||
final FieldGroup group = createElement("<field-group>\n" +
|
||||
"<group-name>myGroup</load-group-name>\n" +
|
||||
"<field-name>myField1</field-name>\n" +
|
||||
"<field-name>myField2</field-name>\n" +
|
||||
"</field-group>",
|
||||
FieldGroup.class);
|
||||
assertEquals(2, group.getFieldNames().size());
|
||||
assertEquals("myField1", group.getFieldNames().get(0).getValue().getName().getValue());
|
||||
assertEquals(null, group.getFieldNames().get(1).getValue());
|
||||
}
|
||||
|
||||
public interface JavaeeModelElement {
|
||||
}
|
||||
|
||||
public interface JavaeeDomModelElement extends JavaeeModelElement, DomElement {
|
||||
}
|
||||
|
||||
public interface FieldGroup extends JavaeeDomModelElement {
|
||||
|
||||
GenericDomValue<String> getGroupName();
|
||||
|
||||
List<GroupField> getFieldNames();
|
||||
|
||||
GroupField addFieldName();
|
||||
}
|
||||
|
||||
public interface GroupField extends JavaeeDomModelElement {
|
||||
|
||||
@Convert(value = CmpFieldConverter.class)
|
||||
CmpField getValue();
|
||||
|
||||
@Convert(value = CmpFieldConverter.class)
|
||||
void setValue(CmpField value);
|
||||
}
|
||||
|
||||
public static class CmpFieldConverter extends ResolvingConverter<CmpField> {
|
||||
|
||||
@Override
|
||||
public CmpField fromString(String s, ConvertContext context) {
|
||||
return ElementPresentationManager.findByName(getVariants(context), s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(CmpField t, ConvertContext context) {
|
||||
return t == null ? null : t.getName().getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Collection<CmpField> getVariants(ConvertContext context) {
|
||||
final DomElement element = context.getInvocationElement();
|
||||
return Arrays.asList(createCmpField(null, element), createCmpField("myField1", element), createCmpField("def", element));
|
||||
}
|
||||
|
||||
private CmpField createCmpField(String name, DomElement element) {
|
||||
final CmpField mockElement = element.getManager().createMockElement(CmpField.class, element.getModule(), false);
|
||||
mockElement.getName().setValue(name);
|
||||
return mockElement;
|
||||
}
|
||||
}
|
||||
|
||||
public interface CmpField extends JavaeeDomModelElement {
|
||||
@NameValue
|
||||
public GenericDomValue<String> getName();
|
||||
}
|
||||
|
||||
public static class MyConverter extends Converter<String> {
|
||||
public int fromStringCalls = 0;
|
||||
|
||||
@Override
|
||||
public String fromString(@Nullable @NonNls String s, final ConvertContext context) {
|
||||
fromStringCalls++;
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(@Nullable String s, final ConvertContext context) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FooConverter extends Converter<String> {
|
||||
@Override
|
||||
public String fromString(@Nullable @NonNls final String s, final ConvertContext context) {
|
||||
return s == null ? null : "foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(@Nullable final String s, final ConvertContext context) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
public static class BarConverter extends Converter<String> {
|
||||
@Override
|
||||
public String fromString(@Nullable @NonNls final String s, final ConvertContext context) {
|
||||
return s == null ? null : "bar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(@Nullable final String s, final ConvertContext context) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.XmlElementFactory;
|
||||
import com.intellij.psi.impl.PsiModificationTrackerImpl;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.testFramework.LightIdeaTestCase;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
import com.intellij.util.xml.impl.DomApplicationComponent;
|
||||
import com.intellij.util.xml.impl.DomFileElementImpl;
|
||||
import com.intellij.util.xml.impl.DomInvocationHandler;
|
||||
import com.intellij.util.xml.impl.DomManagerImpl;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class DomTestCase extends LightIdeaTestCase {
|
||||
protected CallRegistry<DomEvent> myCallRegistry;
|
||||
private final DomEventListener myListener = new DomEventListener() {
|
||||
@Override
|
||||
public void eventOccured(DomEvent event) {
|
||||
myCallRegistry.putActual(event);
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myCallRegistry = new CallRegistry<DomEvent>();
|
||||
getDomManager().addDomEventListener(myListener, myTestRootDisposable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
DomApplicationComponent.getInstance().clearImplementations();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
protected void assertCached(final DomElement element, final XmlElement xmlElement) {
|
||||
assertNotNull(xmlElement);
|
||||
assertSame(element.getXmlTag(), xmlElement);
|
||||
final DomInvocationHandler cachedElement = getCachedHandler(xmlElement);
|
||||
assertNotNull(cachedElement);
|
||||
assertEquals(element, cachedElement.getProxy());
|
||||
}
|
||||
|
||||
protected void assertCached(final DomFileElementImpl element, final XmlFile file) {
|
||||
assertNotNull(file);
|
||||
assertEquals(element, getDomManager().getFileElement(file));
|
||||
}
|
||||
|
||||
protected XmlTag createTag(final String text) throws IncorrectOperationException {
|
||||
return XmlElementFactory.getInstance(getProject()).createTagFromText(text);
|
||||
}
|
||||
|
||||
protected DomManagerImpl getDomManager() {
|
||||
return (DomManagerImpl)DomManager.getDomManager(getProject());
|
||||
}
|
||||
|
||||
protected static XmlFile createXmlFile(@NonNls final String text) throws IncorrectOperationException {
|
||||
return (XmlFile)createLightFile("a.xml", text);
|
||||
}
|
||||
|
||||
|
||||
protected <T extends DomElement> T createElement(final String xml, final Class<T> aClass) throws IncorrectOperationException {
|
||||
final DomManagerImpl domManager = getDomManager();
|
||||
T element = createElement(domManager, xml, aClass);
|
||||
myCallRegistry.clear();
|
||||
return element;
|
||||
}
|
||||
|
||||
protected static <T extends DomElement> T createElement(final DomManager domManager, final String xml, final Class<T> aClass)
|
||||
throws IncorrectOperationException {
|
||||
final String name = "a.xml";
|
||||
final XmlFile file = (XmlFile)PsiFileFactory.getInstance(domManager.getProject()).createFileFromText(name, xml);
|
||||
final XmlTag tag = file.getDocument().getRootTag();
|
||||
final String rootTagName = tag != null ? tag.getName() : "root";
|
||||
final T element = domManager.getFileElement(file, aClass, rootTagName).getRootElement();
|
||||
assertNotNull(element);
|
||||
assertSame(tag, element.getXmlTag());
|
||||
return element;
|
||||
}
|
||||
|
||||
protected void putExpected(final DomEvent event) {
|
||||
myCallRegistry.putExpected(event);
|
||||
}
|
||||
|
||||
protected void assertResultsAndClear() {
|
||||
myCallRegistry.assertResultsAndClear();
|
||||
}
|
||||
|
||||
protected TypeChooserManager getTypeChooserManager() {
|
||||
return getDomManager().getTypeChooserManager();
|
||||
}
|
||||
|
||||
protected static void incModCount() {
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
((PsiModificationTrackerImpl)getPsiManager().getModificationTracker()).incCounter();
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DomInvocationHandler getCachedHandler(XmlElement element) {
|
||||
final List<DomInvocationHandler> option = getDomManager().getSemService().getCachedSemElements(DomManagerImpl.DOM_HANDLER_KEY, element);
|
||||
return option == null || option.isEmpty() ? null : option.get(0);
|
||||
}
|
||||
|
||||
public enum MyEnum implements NamedEnum {
|
||||
FOO("foo"),
|
||||
BAR("bar");
|
||||
|
||||
private final String myName;
|
||||
|
||||
MyEnum(final String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return myName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.testFramework.PsiTestUtil;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
import com.intellij.util.xml.impl.DomFileElementImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class DomVirtualFileEventsTest extends DomHardCoreTestCase{
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
getDomManager().registerFileDescription(new DomFileDescription(MyElement.class, "a") {
|
||||
|
||||
@Override
|
||||
public boolean isMyFile(@NotNull final XmlFile file, final Module module) {
|
||||
return super.isMyFile(file, module) && file.getName().contains("a");
|
||||
}
|
||||
}, getTestRootDisposable());
|
||||
}
|
||||
|
||||
public void testCreateFile() throws Throwable {
|
||||
new WriteCommandAction.Simple(myProject) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final VirtualFile dir = getVirtualFile(createTempDirectory());
|
||||
PsiTestUtil.addSourceContentToRoots(getModule(), dir);
|
||||
final VirtualFile childData = dir.createChildData(this, "abc.xml");
|
||||
System.gc();
|
||||
System.gc();
|
||||
System.gc();
|
||||
System.gc();
|
||||
assertResultsAndClear();
|
||||
VfsUtil.saveText(childData, "<a/>");
|
||||
assertEventCount(0);
|
||||
assertResultsAndClear();
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testDeleteFile() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final VirtualFile dir = getVirtualFile(createTempDirectory());
|
||||
PsiTestUtil.addSourceContentToRoots(getModule(), dir);
|
||||
final VirtualFile childData = dir.createChildData(this, "abc.xml");
|
||||
assertResultsAndClear();
|
||||
VfsUtil.saveText(childData, "<a/>");
|
||||
final DomFileElementImpl<DomElement> fileElement = getFileElement(childData);
|
||||
assertResultsAndClear();
|
||||
|
||||
childData.delete(this);
|
||||
assertEventCount(1);
|
||||
putExpected(new DomEvent(fileElement, false));
|
||||
assertResultsAndClear();
|
||||
assertFalse(fileElement.isValid());
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
public void testRenameFile() throws Throwable {
|
||||
new WriteCommandAction.Simple(getProject()) {
|
||||
@Override
|
||||
protected void run() throws Throwable {
|
||||
final VirtualFile dir = getVirtualFile(createTempDirectory());
|
||||
PsiTestUtil.addSourceContentToRoots(getModule(), dir);
|
||||
final VirtualFile data = dir.createChildData(this, "abc.xml");
|
||||
VfsUtil.saveText(data, "<a/>");
|
||||
final DomFileElementImpl<DomElement> fileElement = getFileElement(data);
|
||||
assertEventCount(0);
|
||||
assertResultsAndClear();
|
||||
|
||||
data.rename(this, "deaf.xml");
|
||||
assertEventCount(1);
|
||||
putExpected(new DomEvent(fileElement, false));
|
||||
assertResultsAndClear();
|
||||
assertEquals(fileElement, getFileElement(data));
|
||||
assertTrue(fileElement.isValid());
|
||||
|
||||
data.rename(this, "fff.xml");
|
||||
assertEventCount(1);
|
||||
putExpected(new DomEvent(fileElement, false));
|
||||
assertResultsAndClear();
|
||||
assertNull(getFileElement(data));
|
||||
assertFalse(fileElement.isValid());
|
||||
}
|
||||
}.execute().throwException();
|
||||
}
|
||||
|
||||
private DomFileElementImpl<DomElement> getFileElement(final VirtualFile file) {
|
||||
return getDomManager().getFileElement((XmlFile)getPsiManager().findFile(file));
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xml.reflect.DomGenericInfo;
|
||||
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class MockDomElement extends UserDataHolderBase implements DomElement{
|
||||
@Override
|
||||
@Nullable
|
||||
public XmlTag getXmlTag() {
|
||||
throw new UnsupportedOperationException("Method getXmlTag is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <T extends DomElement> DomFileElement<T> getRoot() {
|
||||
throw new UnsupportedOperationException("Method getRoot is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DomElement getParent() {
|
||||
throw new UnsupportedOperationException("Method getParent is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlTag ensureTagExists() {
|
||||
throw new UnsupportedOperationException("Method ensureTagExists is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public XmlElement getXmlElement() {
|
||||
throw new UnsupportedOperationException("Method getXmlElement is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlElement ensureXmlElementExists() {
|
||||
throw new UnsupportedOperationException("Method ensureXmlElementExists is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undefine() {
|
||||
throw new UnsupportedOperationException("Method undefine is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
throw new UnsupportedOperationException("Method isValid is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DomGenericInfo getGenericInfo() {
|
||||
throw new UnsupportedOperationException("Method getGenericInfo is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getXmlElementName() {
|
||||
throw new UnsupportedOperationException("Method getXmlElementName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getXmlElementNamespace() {
|
||||
throw new UnsupportedOperationException("Method getXmlElementNamespace is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@NonNls
|
||||
public String getXmlElementNamespaceKey() {
|
||||
throw new UnsupportedOperationException("Method getXmlElementNamespaceKey is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(final DomElementVisitor visitor) {
|
||||
throw new UnsupportedOperationException("Method accept is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptChildren(DomElementVisitor visitor) {
|
||||
throw new UnsupportedOperationException("Method acceptChildren is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DomManager getManager() {
|
||||
throw new UnsupportedOperationException("Method getManager is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getDomElementType() {
|
||||
throw new UnsupportedOperationException("Method getDomElementType is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AbstractDomChildrenDescription getChildDescription() {
|
||||
throw new UnsupportedOperationException("Method getChildDescription is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomNameStrategy getNameStrategy() {
|
||||
throw new UnsupportedOperationException("Method getNameStrategy is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ElementPresentation getPresentation() {
|
||||
throw new UnsupportedOperationException("Method getPresentation is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSearchScope getResolveScope() {
|
||||
throw new UnsupportedOperationException("Method getResolveScope is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends DomElement> T getParentOfType(Class<T> requiredClass, boolean strict) {
|
||||
throw new UnsupportedOperationException("Method getParentOfType is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Module getModule() {
|
||||
throw new UnsupportedOperationException("Method getModule is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(DomElement other) {
|
||||
throw new UnsupportedOperationException("Method copyFrom is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends DomElement> T createMockCopy(final boolean physical) {
|
||||
throw new UnsupportedOperationException("Method createMockCopy is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends DomElement> T createStableCopy() {
|
||||
return (T)this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
throw new UnsupportedOperationException("Method getAnnotation is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xml.reflect.DomGenericInfo;
|
||||
import com.intellij.util.xml.reflect.AbstractDomChildrenDescription;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class MockDomFileElement extends UserDataHolderBase implements DomFileElement<DomElement>{
|
||||
private long myModCount = 0;
|
||||
private DomFileDescription myFileDescription;
|
||||
|
||||
public void setFileDescription(final DomFileDescription fileDescription) {
|
||||
myFileDescription = fileDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public XmlFile getFile() {
|
||||
throw new UnsupportedOperationException("Method getFile is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public XmlFile getOriginalFile() {
|
||||
throw new UnsupportedOperationException("Method getOriginalFile is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlTag getRootTag() {
|
||||
throw new UnsupportedOperationException("Method getRootTag is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DomElement getRootElement() {
|
||||
throw new UnsupportedOperationException("Method getRootElement is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getRootElementClass() {
|
||||
throw new UnsupportedOperationException("Method getRootElementType is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DomFileDescription getFileDescription() {
|
||||
return myFileDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public XmlTag getXmlTag() {
|
||||
throw new UnsupportedOperationException("Method getXmlTag is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <T extends DomElement> DomFileElement<T> getRoot() {
|
||||
return (DomFileElement<T>)this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public DomElement getParent() {
|
||||
throw new UnsupportedOperationException("Method getParent is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlTag ensureTagExists() {
|
||||
throw new UnsupportedOperationException("Method ensureTagExists is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public XmlElement getXmlElement() {
|
||||
throw new UnsupportedOperationException("Method getXmlElement is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlElement ensureXmlElementExists() {
|
||||
throw new UnsupportedOperationException("Method ensureXmlElementExists is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undefine() {
|
||||
throw new UnsupportedOperationException("Method undefine is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
throw new UnsupportedOperationException("Method isValid is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DomGenericInfo getGenericInfo() {
|
||||
throw new UnsupportedOperationException("Method getGenericInfo is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getXmlElementName() {
|
||||
throw new UnsupportedOperationException("Method getXmlElementName is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getXmlElementNamespace() {
|
||||
throw new UnsupportedOperationException("Method getXmlElementNamespace is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@NonNls
|
||||
public String getXmlElementNamespaceKey() {
|
||||
throw new UnsupportedOperationException("Method getXmlElementNamespaceKey is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(final DomElementVisitor visitor) {
|
||||
throw new UnsupportedOperationException("Method accept is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptChildren(DomElementVisitor visitor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public DomManager getManager() {
|
||||
throw new UnsupportedOperationException("Method getManager is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getDomElementType() {
|
||||
throw new UnsupportedOperationException("Method getDomElementType is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public AbstractDomChildrenDescription getChildDescription() {
|
||||
throw new UnsupportedOperationException("Method getChildDescription is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public DomNameStrategy getNameStrategy() {
|
||||
throw new UnsupportedOperationException("Method getNameStrategy is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ElementPresentation getPresentation() {
|
||||
throw new UnsupportedOperationException("Method getPresentation is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSearchScope getResolveScope() {
|
||||
throw new UnsupportedOperationException("Method getResolveScope is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends DomElement> T getParentOfType(Class<T> requiredClass, boolean strict) {
|
||||
throw new UnsupportedOperationException("Method getParentOfType is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Module getModule() {
|
||||
throw new UnsupportedOperationException("Method getModule is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(DomElement other) {
|
||||
throw new UnsupportedOperationException("Method copyFrom is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends DomElement> T createMockCopy(final boolean physical) {
|
||||
throw new UnsupportedOperationException("Method createMockCopy is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends DomElement> T createStableCopy() {
|
||||
throw new UnsupportedOperationException("Method createStableCopy is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
throw new UnsupportedOperationException("Method getAnnotation is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getModificationCount() {
|
||||
return myModCount;
|
||||
}
|
||||
|
||||
public void incModificationCount() {
|
||||
myModCount++;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2007 JetBrains s.r.o. All Rights Reserved.
|
||||
*/
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class MockGenericAttributeValue extends MockDomElement implements GenericAttributeValue<Object> {
|
||||
@Override
|
||||
public XmlAttribute getXmlAttribute() {
|
||||
throw new UnsupportedOperationException("Method getXmlAttribute is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public XmlAttributeValue getXmlAttributeValue() {
|
||||
throw new UnsupportedOperationException("Method getXmlAttributeValue is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Converter getConverter() {
|
||||
throw new UnsupportedOperationException("Method getConverter is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStringValue(String value) {
|
||||
throw new UnsupportedOperationException("Method setStringValue is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(Object value) {
|
||||
throw new UnsupportedOperationException("Method setValue is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringValue() {
|
||||
throw new UnsupportedOperationException("Method getStringValue is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRawText() {
|
||||
throw new UnsupportedOperationException("Method getRawText is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue() {
|
||||
throw new UnsupportedOperationException("Method getValue is not yet implemented in " + getClass().getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class NameStrategyTest extends TestCase {
|
||||
|
||||
public void testHyphenStrategy() throws Throwable {
|
||||
assertEquals("aaa-bbb-ccc", DomNameStrategy.HYPHEN_STRATEGY.convertName("aaaBbbCcc"));
|
||||
assertEquals("aaa-bbb-ccc", DomNameStrategy.HYPHEN_STRATEGY.convertName("AaaBbbCcc"));
|
||||
assertEquals("aaa", DomNameStrategy.HYPHEN_STRATEGY.convertName("Aaa"));
|
||||
assertEquals("aaa", DomNameStrategy.HYPHEN_STRATEGY.convertName("aaa"));
|
||||
assertEquals("AAA-bbb", DomNameStrategy.HYPHEN_STRATEGY.convertName("AAABbb"));
|
||||
assertEquals("aaa-BBB", DomNameStrategy.HYPHEN_STRATEGY.convertName("AaaBBB"));
|
||||
}
|
||||
|
||||
public void testHyphenStrategySplit() throws Throwable {
|
||||
assertEquals("aaa bbb ccc", DomNameStrategy.HYPHEN_STRATEGY.splitIntoWords("aaa-bbb-ccc"));
|
||||
assertEquals("Aaa", DomNameStrategy.HYPHEN_STRATEGY.splitIntoWords("Aaa"));
|
||||
assertEquals("aaa", DomNameStrategy.HYPHEN_STRATEGY.splitIntoWords("aaa"));
|
||||
assertEquals("AAA bbb", DomNameStrategy.HYPHEN_STRATEGY.splitIntoWords("AAA-bbb"));
|
||||
assertEquals("aaa BBB", DomNameStrategy.HYPHEN_STRATEGY.splitIntoWords("aaa-BBB"));
|
||||
}
|
||||
|
||||
public void testJavaStrategy() throws Throwable {
|
||||
assertEquals("aaaBbbCcc", DomNameStrategy.JAVA_STRATEGY.convertName("aaaBbbCcc"));
|
||||
assertEquals("aaaBbbCcc", DomNameStrategy.JAVA_STRATEGY.convertName("AaaBbbCcc"));
|
||||
assertEquals("aaa", DomNameStrategy.JAVA_STRATEGY.convertName("Aaa"));
|
||||
assertEquals("aaa", DomNameStrategy.JAVA_STRATEGY.convertName("aaa"));
|
||||
assertEquals("AAABbb", DomNameStrategy.JAVA_STRATEGY.convertName("AAABbb"));
|
||||
assertEquals("aaaBBB", DomNameStrategy.JAVA_STRATEGY.convertName("AaaBBB"));
|
||||
}
|
||||
|
||||
public void testJavaStrategySplit() throws Throwable {
|
||||
assertEquals("aaa bbb ccc", DomNameStrategy.JAVA_STRATEGY.splitIntoWords("aaaBbbCcc"));
|
||||
assertEquals("aaa", DomNameStrategy.JAVA_STRATEGY.splitIntoWords("Aaa"));
|
||||
assertEquals("aaa", DomNameStrategy.JAVA_STRATEGY.splitIntoWords("aaa"));
|
||||
assertEquals("AAA bbb", DomNameStrategy.JAVA_STRATEGY.splitIntoWords("AAABbb"));
|
||||
assertEquals("aaa BBB", DomNameStrategy.JAVA_STRATEGY.splitIntoWords("aaaBBB"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import junit.framework.TestCase;
|
||||
import net.sf.cglib.proxy.AdvancedProxy;
|
||||
import net.sf.cglib.proxy.InvocationHandler;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class ProxyTest extends TestCase {
|
||||
|
||||
public void testExtendClass() throws Throwable {
|
||||
final List<String> invocations = new ArrayList<String>();
|
||||
Implementation implementation = AdvancedProxy.createProxy(Implementation.class, new Class[]{Interface3.class}, new InvocationHandler(){
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
invocations.add(method.getName());
|
||||
if (Object.class.equals(method.getDeclaringClass())) {
|
||||
return method.invoke(this, args);
|
||||
}
|
||||
return Implementation.class.getMethod("getField").invoke(proxy);
|
||||
}
|
||||
}, "239");
|
||||
implementation.hashCode();
|
||||
implementation.method();
|
||||
assertEquals("239", implementation.getFoo());
|
||||
implementation.setField("42");
|
||||
assertEquals("42", implementation.getBar());
|
||||
assertEquals("42", implementation.toString());
|
||||
assertEquals(Arrays.asList("hashCode", "getFoo", "getFoo", "getBar"), invocations);
|
||||
|
||||
assertEquals("42", Interface1.class.getMethod("getFoo").invoke(implementation));
|
||||
|
||||
assertEquals("42", Interface3.class.getMethod("bar").invoke(implementation));
|
||||
|
||||
assertEquals("42", Interface1.class.getMethod("foo").invoke(implementation));
|
||||
assertEquals("42", Interface2.class.getMethod("foo").invoke(implementation));
|
||||
assertEquals("42", Interface2.class.getMethod("foo").invoke(implementation));
|
||||
assertEquals("42", Implementation.class.getMethod("foo").invoke(implementation));
|
||||
}
|
||||
|
||||
public interface Interface1 {
|
||||
Object getFoo();
|
||||
Object foo();
|
||||
}
|
||||
|
||||
public interface Interface2 extends Interface1 {
|
||||
@Override
|
||||
CharSequence getFoo();
|
||||
@Override
|
||||
CharSequence foo();
|
||||
}
|
||||
|
||||
public interface Interface3 extends Interface1 {
|
||||
@Override
|
||||
String foo();
|
||||
String bar();
|
||||
}
|
||||
|
||||
private abstract static class Implementation implements Interface2 {
|
||||
private String myField;
|
||||
|
||||
protected Implementation(final String field) {
|
||||
myField = field;
|
||||
}
|
||||
|
||||
public String getField() {
|
||||
return myField;
|
||||
}
|
||||
|
||||
public void setField(final String field) {
|
||||
myField = field;
|
||||
}
|
||||
|
||||
public void method() {
|
||||
getFoo();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return myField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract String getFoo();
|
||||
|
||||
public abstract String getBar();
|
||||
|
||||
}
|
||||
|
||||
public void testAddInterfaces() throws Throwable {
|
||||
final BaseImpl proxy = AdvancedProxy.createProxy(BaseImpl.class, BaseIEx.class);
|
||||
assertEquals(proxy.sayA(), "a");
|
||||
assertEquals(((BaseI)proxy).sayA(), "a");
|
||||
assertEquals(((BaseIEx)proxy).sayA(), "a");
|
||||
}
|
||||
|
||||
public interface BaseI {
|
||||
Object sayA();
|
||||
}
|
||||
|
||||
public interface BaseIEx extends BaseI {
|
||||
@Override
|
||||
CharSequence sayA();
|
||||
}
|
||||
|
||||
public static abstract class BaseImpl implements BaseI {
|
||||
@Override
|
||||
public String sayA() {
|
||||
return "a";
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class AbstractBase implements BaseI {
|
||||
@Override
|
||||
public abstract String sayA();
|
||||
|
||||
public abstract static class AbstractBaseImpl extends AbstractBase {}
|
||||
}
|
||||
|
||||
public void testCovariantFromInterface() throws Throwable {
|
||||
final AbstractBase.AbstractBaseImpl proxy = AdvancedProxy.createProxy(AbstractBase.AbstractBaseImpl.class, ArrayUtil.EMPTY_CLASS_ARRAY,
|
||||
new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
return "a";
|
||||
}
|
||||
}, false, new Object[0]);
|
||||
assertEquals(proxy.sayA(), "a");
|
||||
assertEquals(((AbstractBase)proxy).sayA(), "a");
|
||||
assertEquals(((BaseI)proxy).sayA(), "a");
|
||||
}
|
||||
|
||||
public static class CovariantFromBaseClassTest {
|
||||
public static interface Intf {
|
||||
String sayA();
|
||||
}
|
||||
|
||||
public static class Base {
|
||||
public Object sayA() {
|
||||
return "beeee";
|
||||
}
|
||||
}
|
||||
|
||||
public abstract static class Impl extends Base implements Intf {
|
||||
@Override
|
||||
public abstract String sayA();
|
||||
}
|
||||
}
|
||||
|
||||
public void testCovariantFromBaseClass() throws Throwable {
|
||||
final CovariantFromBaseClassTest.Impl proxy = AdvancedProxy.createProxy(CovariantFromBaseClassTest.Impl.class,
|
||||
ArrayUtil.EMPTY_CLASS_ARRAY, new InvocationHandler() {
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
return "a";
|
||||
}
|
||||
}, false, new Object[0]);
|
||||
assertEquals(proxy.sayA(), "a");
|
||||
assertEquals(((CovariantFromBaseClassTest.Base)proxy).sayA(), "a");
|
||||
assertEquals(((CovariantFromBaseClassTest.Intf)proxy).sayA(), "a");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class SimpleValuesIncrementalUpdateTest extends DomTestCase{
|
||||
|
||||
public void testAttributeChange() throws Throwable {
|
||||
final MyElement element = createElement("<a/>");
|
||||
element.getXmlTag().setAttribute("attr", "foo");
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
assertTrue(element.getAttr().isValid());
|
||||
|
||||
element.getXmlTag().setAttribute("bttr", "foo");
|
||||
element.getXmlTag().setAttribute("attr", "bar");
|
||||
putExpected(new DomEvent(element, false));
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
assertTrue(element.getAttr().isValid());
|
||||
|
||||
element.getXmlTag().setAttribute("attr", null);
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
assertTrue(element.getAttr().isValid());
|
||||
}
|
||||
|
||||
public void testAttributeValueChangeAsXmlElementChange() throws Throwable {
|
||||
final MyElement element = createElement("<a attr=\"foo\"/>");
|
||||
final GenericAttributeValue<String> attr = element.getAttr();
|
||||
attr.getXmlAttributeValue().getFirstChild().replace(createTag("<a attr=\"bar\"/>").getAttribute("attr", null).getValueElement().getFirstChild());
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
assertTrue(attr.isValid());
|
||||
}
|
||||
|
||||
public void testTagValueChange() throws Throwable {
|
||||
final MyElement element = createElement("<a><child> </child></a>").getChild();
|
||||
element.getXmlTag().getValue().setText("abc");
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
element.getXmlTag().getValue().setText(null);
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAttrXmlEmptyUri() throws Throwable {
|
||||
final MyElement element = createElement("<a xmlns=\"foo\"><ns-child attr=\"239\"/></a>" , MyElement.class);
|
||||
getDomManager().getDomFileDescription(element.getXmlElement()).registerNamespacePolicy("foo", "foo");
|
||||
|
||||
final GenericAttributeValue<String> attr = element.getNsChild().getAttr();
|
||||
attr.getXmlTag().setAttribute("attr", "42");
|
||||
putExpected(new DomEvent(element.getNsChild(), false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
private MyElement createElement(final String xml) throws IncorrectOperationException {
|
||||
return createElement(xml, MyElement.class);
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement{
|
||||
GenericAttributeValue<String> getAttr();
|
||||
|
||||
Integer getValue();
|
||||
|
||||
MyElement getChild();
|
||||
|
||||
MyNsElement getNsChild();
|
||||
}
|
||||
|
||||
@Namespace("foo")
|
||||
public interface MyNsElement extends DomElement{
|
||||
GenericAttributeValue<String> getAttr();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.intellij.util.xml;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class StringBufferConverter extends Converter<StringBuffer> {
|
||||
@Override
|
||||
public StringBuffer fromString(final String s, final ConvertContext context) {
|
||||
return s==null?null:new StringBuffer(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(final StringBuffer t, final ConvertContext context) {
|
||||
return t==null?null:t.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package com.intellij.util.xml.impl;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomTestCase;
|
||||
import com.intellij.util.xml.SubTag;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class IncrementalUpdateEventsTest extends DomTestCase {
|
||||
private MyElement myElement;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myElement = createElement("<a><child/><child/><child-element/><child-element/></a>");
|
||||
}
|
||||
|
||||
public void testRemove0() throws IncorrectOperationException {
|
||||
deleteTag(0);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
deleteTag(0);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
deleteTag(0);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
deleteTag(0);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testRemove1() throws IncorrectOperationException {
|
||||
deleteTag(1);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testRemove2() throws IncorrectOperationException {
|
||||
deleteTag(2);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
deleteTag(2);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testRemove3() throws IncorrectOperationException {
|
||||
deleteTag(3);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAdd0() throws Throwable {
|
||||
addChildTag(0);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAdd1() throws Throwable {
|
||||
addChildTag(1);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAdd2() throws Throwable {
|
||||
addChildElementTag(2);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAdd3() throws Throwable {
|
||||
addChildElementTag(3);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAdd4() throws Throwable {
|
||||
final XmlTag tag = myElement.getXmlTag();
|
||||
tag.addAfter(createTag("<child-element/>"), tag.getSubTags()[3]);
|
||||
putExpected(new DomEvent(myElement, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
private MyElement getChild(final int index) {
|
||||
return myElement.getChildElements().get(index);
|
||||
}
|
||||
|
||||
private void addChildTag(int index) throws IncorrectOperationException {
|
||||
final XmlTag tag = myElement.getXmlTag();
|
||||
tag.addBefore(createTag("<child/>"), tag.getSubTags()[index]);
|
||||
}
|
||||
|
||||
private void addChildElementTag(int index) throws IncorrectOperationException {
|
||||
final XmlTag tag = myElement.getXmlTag();
|
||||
tag.addBefore(createTag("<child-element/>"), tag.getSubTags()[index]);
|
||||
}
|
||||
|
||||
|
||||
private void deleteTag(final int index) throws IncorrectOperationException {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
myElement.getXmlTag().getSubTags()[index].delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private MyElement createElement(final String xml) throws IncorrectOperationException {
|
||||
return createElement(xml, MyElement.class);
|
||||
}
|
||||
|
||||
public interface MyElement extends DomElement {
|
||||
MyElement getChild();
|
||||
|
||||
@SubTag(value = "child", index = 1)
|
||||
MyElement getChild2();
|
||||
|
||||
List<MyElement> getChildElements();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,694 @@
|
||||
package com.intellij.util.xml.impl;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.XmlElementFactory;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.*;
|
||||
import com.intellij.util.xml.events.DomEvent;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class TreeIncrementalUpdateTest extends DomTestCase {
|
||||
|
||||
public void testRenameCollectionTag() throws Throwable {
|
||||
final MyElement rootElement = createPhysicalElement(
|
||||
"<?xml version='1.0' encoding='UTF-8'?>\n" + "<a>\n" + " <boy>\n" + " </boy>\n" + " <girl/>\n" + "</a>");
|
||||
myCallRegistry.clear();
|
||||
assertEquals(1, rootElement.getBoys().size());
|
||||
assertEquals(1, rootElement.getGirls().size());
|
||||
final MyElement oldBoy = rootElement.getBoys().get(0);
|
||||
final XmlTag tag = oldBoy.getXmlTag();
|
||||
assertNotNull(tag);
|
||||
final int offset = tag.getTextOffset();
|
||||
final int endoffset = offset+tag.getTextLength();
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
rootElement.getGirls().get(0).undefine();
|
||||
final Document document = getDocument(DomUtil.getFile(rootElement));
|
||||
PsiDocumentManager.getInstance(getProject()).doPostponedOperationsAndUnblockDocument(document);
|
||||
document.replaceString(offset+1, offset+1+"boy".length(), "girl");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(oldBoy.isValid());
|
||||
assertEquals(0, rootElement.getBoys().size());
|
||||
assertEquals(1, rootElement.getGirls().size());
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = getDocument(DomUtil.getFile(rootElement));
|
||||
document.replaceString(endoffset - "boy".length(), endoffset, "girl");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
assertEquals(0, rootElement.getBoys().size());
|
||||
assertEquals(1, rootElement.getGirls().size());
|
||||
}
|
||||
|
||||
private MyElement createPhysicalElement(final String text) throws IncorrectOperationException {
|
||||
final XmlFile file = (XmlFile)createFile("file.xml", text);
|
||||
final DomFileElementImpl<MyElement> fileElement = getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
return rootElement;
|
||||
}
|
||||
|
||||
public void testRenameFixedTag() throws Throwable {
|
||||
final XmlFile file = (XmlFile)createFile("file.xml", "<?xml version='1.0' encoding='UTF-8'?>\n" +
|
||||
"<a>\n" +
|
||||
" <aboy>\n" +
|
||||
" </aboy>\n" +
|
||||
" <agirl/>\n" +
|
||||
"</a>");
|
||||
final DomFileElementImpl<MyElement> fileElement = getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
myCallRegistry.clear();
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
assertNotNull(rootElement.getAboy().getXmlElement());
|
||||
assertNotNull(rootElement.getAgirl().getXmlElement());
|
||||
final MyElement oldBoy = rootElement.getAboy();
|
||||
final XmlTag tag = oldBoy.getXmlTag();
|
||||
assertNotNull(tag);
|
||||
final int offset = tag.getTextOffset();
|
||||
final int endoffset = offset+tag.getTextLength();
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
rootElement.getAgirl().undefine();
|
||||
final Document document = getDocument(file);
|
||||
PsiDocumentManager.getInstance(getProject()).doPostponedOperationsAndUnblockDocument(document);
|
||||
document.replaceString(offset+1, offset+1+"aboy".length(), "agirl");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(oldBoy.isValid());
|
||||
assertNull(rootElement.getAboy().getXmlElement());
|
||||
assertNotNull(rootElement.getAgirl().getXmlElement());
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = getDocument(file);
|
||||
document.replaceString(endoffset - "aboy".length(), endoffset, "agirl");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
assertNull(rootElement.getAboy().getXmlElement());
|
||||
assertNotNull(rootElement.getAgirl().getXmlElement());
|
||||
}
|
||||
|
||||
public void testDocumentChange() throws Throwable {
|
||||
final XmlFile file = (XmlFile)createFile("file.xml", "<?xml version='1.0' encoding='UTF-8'?>\n" +
|
||||
"<a>\n" +
|
||||
" <child>\n" +
|
||||
" <child/>\n" +
|
||||
" </child>\n" +
|
||||
"</a>");
|
||||
final DomFileElementImpl<MyElement> fileElement =
|
||||
getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
myCallRegistry.clear();
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
final MyElement oldLeaf = rootElement.getChild().getChild();
|
||||
final XmlTag oldLeafTag = oldLeaf.getXmlTag();
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = getDocument(file);
|
||||
document.replaceString(0, document.getText().length(), "<a/>");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(oldLeafTag.isValid());
|
||||
|
||||
putExpected(new DomEvent(fileElement, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
assertEquals(fileElement.getRootElement(), rootElement);
|
||||
assertTrue(rootElement.isValid());
|
||||
|
||||
assertFalse(oldLeaf.isValid());
|
||||
|
||||
assertTrue(rootElement.getChild().isValid());
|
||||
assertNull(rootElement.getChild().getXmlTag());
|
||||
assertNull(rootElement.getChild().getChild().getXmlTag());
|
||||
}
|
||||
|
||||
public void testDocumentChange2() throws Throwable {
|
||||
final XmlFile file = (XmlFile)createFile("file.xml", "<?xml version='1.0' encoding='UTF-8'?>\n" +
|
||||
"<!DOCTYPE ejb-jar PUBLIC \"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN\" \"http://java.sun.com/dtd/ejb-jar_2_0.dtd\">\n" +
|
||||
"<a>\n" +
|
||||
" <child>\n" +
|
||||
" <child/>\n" +
|
||||
" </child>\n" +
|
||||
"</a>");
|
||||
final DomFileElementImpl<MyElement> fileElement =
|
||||
getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
myCallRegistry.clear();
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
final MyElement oldLeaf = rootElement.getChild().getChild();
|
||||
final XmlTag oldLeafTag = oldLeaf.getXmlTag();
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
file.getDocument().getProlog().delete();
|
||||
final XmlTag tag = file.getDocument().getRootTag();
|
||||
tag.setAttribute("xmlns", "something");
|
||||
tag.setAttribute("xmlns:xsi", "something");
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertTrue(oldLeafTag.isValid());
|
||||
|
||||
putExpected(new DomEvent(fileElement, false));
|
||||
putExpected(new DomEvent(rootElement, false));
|
||||
putExpected(new DomEvent(rootElement, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
assertEquals(fileElement.getRootElement(), rootElement);
|
||||
assertTrue(rootElement.isValid());
|
||||
|
||||
assertTrue(rootElement.getChild().isValid());
|
||||
assertTrue(rootElement.getChild().getXmlTag().isValid());
|
||||
assertTrue(rootElement.getChild().getChild().getXmlTag().isValid());
|
||||
}
|
||||
|
||||
public void testMoveUp() throws Throwable {
|
||||
final XmlFile file = (XmlFile)createFile("file.xml", "<?xml version='1.0' encoding='UTF-8'?>\n" +
|
||||
"<a>\n" +
|
||||
" <child>\n" +
|
||||
" <aboy />\n" +
|
||||
" <agirl/>\n" +
|
||||
" </child>\n" +
|
||||
"</a>");
|
||||
final DomFileElementImpl<MyElement> fileElement = getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
myCallRegistry.clear();
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
rootElement.getChild().getAboy();
|
||||
rootElement.getChild().getAgirl();
|
||||
|
||||
final Document document = getDocument(file);
|
||||
final int len = "<agirl/>".length();
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final int agirl = document.getText().indexOf("<agirl/>");
|
||||
final int boy = document.getText().indexOf("<aboy />");
|
||||
document.replaceString(agirl, agirl + len, "<aboy />");
|
||||
document.replaceString(boy, boy + len, "<agirl/>");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertTrue(rootElement.isValid());
|
||||
final XmlTag tag1 = rootElement.getXmlTag().getSubTags()[0];
|
||||
assertEquals(getDomManager().getDomElement(tag1.findFirstSubTag("agirl")), rootElement.getChild().getAgirl());
|
||||
assertEquals(getDomManager().getDomElement(tag1.findFirstSubTag("aboy")), rootElement.getChild().getAboy());
|
||||
}
|
||||
|
||||
public void testRemoveAttributeParent() throws Throwable {
|
||||
final XmlFile file = (XmlFile)createFile("file.xml", "<?xml version='1.0' encoding='UTF-8'?>\n" +
|
||||
"<!DOCTYPE ejb-jar PUBLIC \"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN\" \"http://java.sun.com/dtd/ejb-jar_2_0.dtd\">\n" +
|
||||
"<a>\n" +
|
||||
" <child-element xxx=\"239\"/>\n" +
|
||||
"</a>");
|
||||
final DomFileElementImpl<MyElement> fileElement =
|
||||
getDomManager().getFileElement(file, MyElement.class, "a");
|
||||
myCallRegistry.clear();
|
||||
final MyElement rootElement = fileElement.getRootElement();
|
||||
final MyElement oldLeaf = rootElement.getChildElements().get(0);
|
||||
final GenericAttributeValue<String> xxx = oldLeaf.getXxx();
|
||||
final XmlTag oldLeafTag = oldLeaf.getXmlTag();
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
oldLeafTag.delete();
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertFalse(oldLeaf.isValid());
|
||||
assertFalse(xxx.isValid());
|
||||
}
|
||||
|
||||
public void testTypeBeforeRootTag() throws Throwable {
|
||||
getDomManager().registerFileDescription(new DomFileDescription<MyElement>(MyElement.class, "a"), getTestRootDisposable());
|
||||
|
||||
final XmlFile file = (XmlFile)createFile("file.xml", "<?xml version='1.0' encoding='UTF-8'?>\n" +
|
||||
"<a/>");
|
||||
|
||||
assertTrue(getDomManager().isDomFile(file));
|
||||
final DomFileElementImpl<MyElement> fileElement = getDomManager().getFileElement(file, MyElement.class);
|
||||
assertTrue(fileElement.isValid());
|
||||
myCallRegistry.clear();
|
||||
|
||||
putExpected(new DomEvent(fileElement, false));
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = getDocument(file);
|
||||
final int i = document.getText().indexOf("<a");
|
||||
document.insertString(i, "a");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertFalse(getDomManager().isDomFile(file));
|
||||
assertFalse(fileElement.isValid());
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
private void assertNoCache(XmlTag tag) {
|
||||
assertNull(tag.getText(), getCachedHandler(tag));
|
||||
if (tag.isValid()) {
|
||||
for (XmlTag xmlTag : tag.getSubTags()) {
|
||||
assertNoCache(xmlTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private MyElement createElement(final String xml) throws IncorrectOperationException {
|
||||
return createElement(xml, MyElement.class);
|
||||
}
|
||||
|
||||
public void testAddCollectionElement() throws Throwable {
|
||||
final MyElement element = createElement("<a><child/><child/><child-element/></a>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
final MyElement firstChild = element.getChildElements().get(0);
|
||||
element.getXmlTag().add(createTag("<child-element/>"));
|
||||
final XmlTag[] subTags = element.getXmlTag().getSubTags();
|
||||
assertEquals(2, element.getChildElements().size());
|
||||
assertEquals(firstChild, element.getChildElements().get(0));
|
||||
MyElement nextChild = element.getChildElements().get(1);
|
||||
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAddFixedElement() throws Throwable {
|
||||
final MyElement element = createPhysicalElement("<a>" +
|
||||
"<child/>" +
|
||||
"<child><child/></child>" +
|
||||
"<child/></a>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
final XmlTag leafTag = child2.getChild().getXmlTag();
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
element.getXmlTag().addAfter(createTag("<child/>"), child.getXmlTag());
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertNoCache(leafTag);
|
||||
|
||||
final XmlTag[] subTags = element.getXmlTag().getSubTags();
|
||||
|
||||
assertFalse(child2.isValid());
|
||||
assertEquals(child, element.getChild());
|
||||
assertFalse(child2.equals(element.getChild2()));
|
||||
|
||||
assertCached(child, subTags[0]);
|
||||
assertNoCache(subTags[2]);
|
||||
assertNoCache(subTags[3]);
|
||||
|
||||
putExpected(new DomEvent(element, false));
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAddFixedElementCanDefineIt() throws Throwable {
|
||||
final MyElement element = createElement("<a></a>");
|
||||
final MyElement child = element.getChild();
|
||||
|
||||
element.getXmlTag().add(createTag("<child/>"));
|
||||
|
||||
final XmlTag[] subTags = element.getXmlTag().getSubTags();
|
||||
|
||||
assertTrue(child.equals(element.getChild()));
|
||||
assertTrue(element.getChild().equals(child));
|
||||
|
||||
assertCached(element.getChild(), subTags[0]);
|
||||
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testActuallyRemoveCollectionElement() throws Throwable {
|
||||
final MyElement element = createElement("<a><child-element><child/></child-element><child-element/></a>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
final MyElement firstChild = element.getChildElements().get(0);
|
||||
final MyElement lastChild = element.getChildElements().get(1);
|
||||
|
||||
final XmlTag tag = element.getXmlTag();
|
||||
final XmlTag childTag = tag.getSubTags()[0];
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
childTag.delete();
|
||||
}
|
||||
});
|
||||
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
assertEquals(child, element.getChild());
|
||||
assertEquals(child2, element.getChild2());
|
||||
assertEquals(Arrays.asList(lastChild), element.getChildElements());
|
||||
assertCached(lastChild, tag.getSubTags()[0]);
|
||||
}
|
||||
|
||||
public void testCustomChildrenEvents() throws Throwable {
|
||||
final Sepulka element = createElement("<a><foo/><bar/></a>", Sepulka.class);
|
||||
final List<MyElement> list = element.getCustomChildren();
|
||||
final XmlTag tag = element.getXmlTag();
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
tag.getSubTags()[0].delete();
|
||||
tag.getSubTags()[0].delete();
|
||||
}
|
||||
});
|
||||
|
||||
tag.add(createTag("<goo/>"));
|
||||
putExpected(new DomEvent(element, false));
|
||||
putExpected(new DomEvent(element, false));
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
assertEquals(1, element.getCustomChildren().size());
|
||||
}
|
||||
|
||||
public void testRemoveFixedElement() throws Throwable {
|
||||
final MyElement element = createElement("<a>" +
|
||||
"<child/>" +
|
||||
"<child><child/></child>" +
|
||||
"<child><child/></child>" +
|
||||
"</a>");
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement child2 = element.getChild2();
|
||||
final MyElement oldLeaf = child2.getChild();
|
||||
final XmlTag tag = element.getXmlTag();
|
||||
XmlTag leafTag = tag.getSubTags()[2].getSubTags()[0];
|
||||
assertNoCache(leafTag);
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
tag.getSubTags()[1].delete();
|
||||
|
||||
assertFalse(oldLeaf.isValid());
|
||||
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
|
||||
assertEquals(child, element.getChild());
|
||||
assertFalse(child2.isValid());
|
||||
|
||||
tag.getSubTags()[1].delete();
|
||||
}
|
||||
});
|
||||
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testRootTagAppearsLater() throws Throwable {
|
||||
final XmlFile file = createXmlFile("");
|
||||
final DomFileElementImpl<MyElement> fileElement = getDomManager().getFileElement(file, MyElement.class, "root");
|
||||
myCallRegistry.clear();
|
||||
|
||||
assertNull(fileElement.getRootElement().getXmlTag());
|
||||
|
||||
file.getDocument().replace(createXmlFile("<root/>").getDocument());
|
||||
final XmlTag rootTag = fileElement.getRootTag();
|
||||
assertEquals(rootTag, file.getDocument().getRootTag());
|
||||
putExpected(new DomEvent(fileElement.getRootElement(), false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testAnotherChildren() throws Throwable {
|
||||
final MyElement element = createElement("<a><child/></a>");
|
||||
element.getXmlTag().add(createTag("<another-child/>"));
|
||||
assertEquals(1, element.getAnotherChildren().size());
|
||||
|
||||
putExpected(new DomEvent(element, false));
|
||||
assertResultsAndClear();
|
||||
}
|
||||
|
||||
public void testInvalidateParent() throws Throwable {
|
||||
final MyElement root = getDomManager().createMockElement(MyElement.class, null, true);
|
||||
new WriteCommandAction<MyElement>(getProject()) {
|
||||
@Override
|
||||
protected void run(Result<MyElement> result) throws Throwable {
|
||||
root.getChild().ensureTagExists();
|
||||
root.getChild2().ensureTagExists();
|
||||
final MyElement element = root.addChildElement().getChild();
|
||||
result.setResult(element);
|
||||
element.ensureTagExists().getValue().setText("abc");
|
||||
root.addChildElement();
|
||||
root.addChildElement();
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
assertTrue(root.isValid());
|
||||
final MyElement element = root.getChildElements().get(0).getChild();
|
||||
assertTrue(element.isValid());
|
||||
final MyElement child = element.getChild();
|
||||
final MyElement genericValue = child.getChild();
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = getDocument(DomUtil.getFile(element));
|
||||
final TextRange range = element.getXmlTag().getTextRange();
|
||||
document.replaceString(range.getStartOffset(), range.getEndOffset(), "");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
assertFalse(genericValue.isValid());
|
||||
assertFalse(child.isValid());
|
||||
assertFalse(element.isValid());
|
||||
}
|
||||
|
||||
public void testCollectionChildValidAfterFormattingReparse() throws Throwable {
|
||||
final MyElement root = getDomManager().createMockElement(MyElement.class, null, true);
|
||||
final MyElement element = new WriteCommandAction<MyElement>(getProject()) {
|
||||
@Override
|
||||
protected void run(Result<MyElement> result) throws Throwable {
|
||||
result.setResult(root.addChildElement());
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
assertTrue(root.isValid());
|
||||
assertNotNull(element.getXmlElement());
|
||||
}
|
||||
|
||||
public void testChangeImplementationClass() throws Throwable {
|
||||
getTypeChooserManager().registerTypeChooser(MyElement.class, createClassChooser());
|
||||
try {
|
||||
final MyElement element = getDomManager().createMockElement(MyElement.class, getModule(), true);
|
||||
final DomFileElement<MyElement> root = DomUtil.getFileElement(element);
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
element.addChildElement().addChildElement();
|
||||
}
|
||||
}.execute();
|
||||
|
||||
final MyElement child = element.getChildElements().get(0);
|
||||
MyElement grandChild = child.getChildElements().get(0);
|
||||
assertTrue(child instanceof BarInterface);
|
||||
assertTrue(grandChild instanceof BarInterface);
|
||||
|
||||
grandChild = element.getChildElements().get(0).getChildElements().get(0);
|
||||
final XmlTag tag = grandChild.getXmlTag();
|
||||
assertTrue(grandChild.isValid());
|
||||
assertEquals(grandChild, root.getRootElement().getChildElements().get(0).getChildElements().get(0));
|
||||
assertNotNull(element.getXmlTag());
|
||||
assertNotNull(child.getXmlTag());
|
||||
assertNotNull(tag);
|
||||
assertTrue(tag.isValid());
|
||||
|
||||
myCallRegistry.clear();
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
tag.add(XmlElementFactory.getInstance(getProject()).createTagFromText("<foo/>"));
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertTrue(root.isValid());
|
||||
assertTrue(element.isValid());
|
||||
assertTrue(grandChild.isValid());
|
||||
final MyElement newChild = root.getRootElement().getChildElements().get(0);
|
||||
assertTrue(newChild instanceof BarInterface);
|
||||
|
||||
final MyElement newGrandChild = newChild.getChildElements().get(0);
|
||||
assertTrue(newGrandChild.isValid());
|
||||
assertTrue(newGrandChild instanceof FooInterface);
|
||||
|
||||
putExpected(new DomEvent(child, false));
|
||||
putExpected(new DomEvent(grandChild, false));
|
||||
assertResultsAndClear();
|
||||
} finally {
|
||||
getTypeChooserManager().unregisterTypeChooser(MyElement.class);
|
||||
}
|
||||
}
|
||||
|
||||
public void testChangeImplementationClass_InCollection() throws Throwable {
|
||||
getTypeChooserManager().registerTypeChooser(MyElement.class, createClassChooser());
|
||||
try {
|
||||
final MyElement element = getDomManager().createMockElement(MyElement.class, getModule(), true);
|
||||
final DomFileElement<MyElement> root = DomUtil.getFileElement(element);
|
||||
new WriteCommandAction<MyElement>(getProject()) {
|
||||
@Override
|
||||
protected void run(Result<MyElement> result) throws Throwable {
|
||||
element.addChildElement().addChildElement();
|
||||
}
|
||||
}.execute().getResultObject();
|
||||
final MyElement child = element.getChildElements().get(0);
|
||||
final MyElement grandChild = child.getChildElements().get(0);
|
||||
assertTrue(child instanceof BarInterface);
|
||||
assertTrue(grandChild instanceof BarInterface);
|
||||
|
||||
assertTrue(element.isValid());
|
||||
assertTrue(child.isValid());
|
||||
assertTrue(grandChild.isValid());
|
||||
|
||||
assertNotNull(element.getXmlTag());
|
||||
assertNotNull(child.getXmlTag());
|
||||
|
||||
final XmlTag tag = grandChild.getXmlTag();
|
||||
assertNotNull(tag);
|
||||
|
||||
myCallRegistry.clear();
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
tag.add(XmlElementFactory.getInstance(getProject()).createTagFromText("<foo/>"));
|
||||
}
|
||||
}.execute();
|
||||
|
||||
assertTrue(root.isValid());
|
||||
assertTrue(element.isValid());
|
||||
|
||||
assertTrue(child.isValid());
|
||||
final MyElement newChild = element.getChildElements().get(0);
|
||||
assertTrue(newChild.isValid());
|
||||
assertTrue(newChild.getClass().toString(), newChild instanceof BarInterface);
|
||||
|
||||
assertTrue(grandChild.isValid());
|
||||
final MyElement newGrandChild = newChild.getChildElements().get(0);
|
||||
assertTrue(newGrandChild.isValid());
|
||||
assertTrue(newGrandChild instanceof FooInterface);
|
||||
|
||||
putExpected(new DomEvent(child, false));
|
||||
putExpected(new DomEvent(grandChild, false));
|
||||
assertResultsAndClear();
|
||||
} finally {
|
||||
getTypeChooserManager().unregisterTypeChooser(MyElement.class);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
public void testCommentTag() throws Throwable {
|
||||
final String prefix = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!DOCTYPE application PUBLIC \"-//Sun Microsystems, Inc.//DTD J2EE Application 1.3//EN\" \"http://java.sun.com/dtd/application_1_3.dtd\">\n" +
|
||||
"<application>\n" + " <display-name>MyAppa</display-name>\n" + " <description>ss</description>\n" +
|
||||
" <module id=\"MyWebApp2\">\n" + " <web> a\n" + " <web-uri>MyWebApp2.war</web-uri>\n" +
|
||||
" ";
|
||||
final String infix = "<context-root>MyWebApp2</context-root>";
|
||||
String suffix = "\n" + " </web>\n" + " </module>\n" +
|
||||
" <module id=\"MyWebApp22\">\n" + " <web>\n" + " <web-uri>MyWebApp2.war</web-uri>\n" +
|
||||
" <context-root>MyWebApp2</context-root>\n" + " </web>\n" + " </module>\n" +
|
||||
" <module id=\"MyEjb32\">\n" + " <ejb>MyEjb32.jar</ejb>\n" + " </module>\n" +
|
||||
" <module id=\"MyEjb4\">\n" + " <ejb>MyEjb4.jar</ejb>\n" + " </module>\n" + " <security-role>\n" +
|
||||
" <description>asdf</description>\n" + " <role-name>nameasdf</role-name>\n" +
|
||||
" </security-role>\n" + "\n" + "</application>";
|
||||
|
||||
final XmlFile file = (XmlFile)createFile("web.xml", prefix + infix + suffix);
|
||||
final JavaeeApplication javaeeApplication = getDomManager().getFileElement(file, JavaeeApplication.class).getRootElement();
|
||||
assertEquals("MyWebApp2", javaeeApplication.getModules().get(0).getWeb().getContextRoot().getValue());
|
||||
|
||||
new WriteCommandAction(getProject()) {
|
||||
@Override
|
||||
protected void run(Result result) throws Throwable {
|
||||
final Document document = getDocument(file);
|
||||
document.insertString(prefix.length() + infix.length(), "-->");
|
||||
document.insertString(prefix.length(), "<!--");
|
||||
commitDocument(document);
|
||||
}
|
||||
}.execute();
|
||||
assertTrue(javaeeApplication.isValid());
|
||||
assertTrue(javaeeApplication.getModules().get(0).getWeb().getContextRoot().isValid());
|
||||
assertTrue(javaeeApplication.getModules().get(0).getWeb().isValid());
|
||||
assertNull(javaeeApplication.getModules().get(0).getWeb().getContextRoot().getXmlElement());
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
private static TypeChooser createClassChooser() {
|
||||
return new TypeChooser() {
|
||||
@Override
|
||||
public Type chooseType(final XmlTag tag) {
|
||||
return tag != null && tag.findFirstSubTag("foo") != null
|
||||
? FooInterface.class
|
||||
: BarInterface.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void distinguishTag(final XmlTag tag, final Type aClass)
|
||||
throws IncorrectOperationException {
|
||||
if (FooInterface.class.equals(aClass) && tag.findFirstSubTag("foo") == null) {
|
||||
tag.add(XmlElementFactory.getInstance(getProject()).createTagFromText("<foo/>"));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type[] getChooserTypes() {
|
||||
return new Class[]{FooInterface.class,
|
||||
BarInterface.class};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public interface MyElement extends DomElement{
|
||||
MyElement getChild();
|
||||
@SubTag(value="child",index=1) MyElement getChild2();
|
||||
List<MyElement> getChildElements();
|
||||
List<MyElement> getBoys();
|
||||
List<MyElement> getGirls();
|
||||
List<MyElement> getAnotherChildren();
|
||||
MyElement addChildElement();
|
||||
GenericAttributeValue<String> getXxx();
|
||||
|
||||
MyElement getAboy();
|
||||
MyElement getAgirl();
|
||||
}
|
||||
|
||||
public interface FooInterface extends MyElement {
|
||||
}
|
||||
|
||||
public interface BarInterface extends MyElement {
|
||||
}
|
||||
|
||||
public interface Sepulka extends DomElement{
|
||||
@CustomChildren
|
||||
List<MyElement> getCustomChildren();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.intellij.util.xml.stubs;
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.stubs.ObjectStubTree;
|
||||
import com.intellij.psi.stubs.StubTreeLoader;
|
||||
import com.intellij.testFramework.IdeaTestCase;
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.xml.DomFileDescription;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import com.intellij.util.xml.impl.DomManagerImpl;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
* Date: 8/3/12
|
||||
*/
|
||||
public class DomStubsTest extends LightPlatformCodeInsightFixtureTestCase {
|
||||
|
||||
public void testDomLoading() throws Exception {
|
||||
|
||||
PsiFile psiFile = myFixture.configureByFile("foo.xml");
|
||||
|
||||
StubTreeLoader loader = StubTreeLoader.getInstance();
|
||||
VirtualFile file = psiFile.getVirtualFile();
|
||||
assertTrue(loader.canHaveStub(file));
|
||||
ObjectStubTree stubTree = loader.readFromVFile(getProject(), file);
|
||||
assertNotNull(stubTree);
|
||||
}
|
||||
|
||||
@SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
|
||||
public DomStubsTest() {
|
||||
IdeaTestCase.initPlatformPrefix();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCommunity() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final DomFileDescription<Foo> DOM_FILE_DESCRIPTION = new DomFileDescription<Foo>(Foo.class, "foo") {
|
||||
@Override
|
||||
public boolean hasStubs() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
((DomManagerImpl)DomManager.getDomManager(getProject())).registerFileDescription(DOM_FILE_DESCRIPTION, getTestRootDisposable());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/xml/dom-tests/testData/stubs";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.intellij.util.xml.stubs;
|
||||
|
||||
import com.intellij.util.xml.DomElement;
|
||||
|
||||
/**
|
||||
* @author Dmitry Avdeev
|
||||
* Date: 8/3/12
|
||||
*/
|
||||
public interface Foo extends DomElement {
|
||||
}
|
||||
Reference in New Issue
Block a user