Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Weinand2003-07-07 05:50:34 -0400
committerAndre Weinand2003-07-07 05:50:34 -0400
commit01166ab2791b91aaafed57f2f5209814cc66b11d (patch)
treeef0b285e84e91fc68478b48247f8dcda5c0ddb0f /examples/org.eclipse.compare.examples.xml
parentcf164bf177e1ce5e4129aed93dcacd9fd0c37829 (diff)
downloadeclipse.platform.team-01166ab2791b91aaafed57f2f5209814cc66b11d.tar.gz
eclipse.platform.team-01166ab2791b91aaafed57f2f5209814cc66b11d.tar.xz
eclipse.platform.team-01166ab2791b91aaafed57f2f5209814cc66b11d.zip
initial checkin
Diffstat (limited to 'examples/org.eclipse.compare.examples.xml')
-rw-r--r--examples/org.eclipse.compare.examples.xml/.classpath13
-rw-r--r--examples/org.eclipse.compare.examples.xml/.cvsignore1
-rw-r--r--examples/org.eclipse.compare.examples.xml/.project25
-rw-r--r--examples/org.eclipse.compare.examples.xml/IdMaps/ant_test.xml7
-rw-r--r--examples/org.eclipse.compare.examples.xml/IdMaps/idmap.dtd8
-rw-r--r--examples/org.eclipse.compare.examples.xml/about.html30
-rw-r--r--examples/org.eclipse.compare.examples.xml/build.properties19
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/CreateNewIDMapButton.gifbin0 -> 13851 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/EditCopy.gifbin0 -> 49868 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/IDMapContextMenu.gifbin0 -> 5245 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/IDMap_GeneralMatching.gifbin0 -> 2816 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/IDMap_MyPlugin.gifbin0 -> 3525 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/IDMap_NewIDMapScheme.gifbin0 -> 5743 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_ContextMenu.gifbin0 -> 3024 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_PreferencePage.gifbin0 -> 7095 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/IDMap_SelectMyPlugin.gifbin0 -> 4043 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/Ordered_MyANT.gifbin0 -> 3184 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/Ordered_NewIDMapScheme.gifbin0 -> 5450 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_ContextMenu.gifbin0 -> 2928 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_PreferencePage.gifbin0 -> 5501 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/Ordered_UnorderedScheme.gifbin0 -> 2821 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/PreferencePage.gifbin0 -> 20791 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/addidmap.gifbin0 -> 125 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/hglegal.htm14
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/ngibmcpy.gifbin0 -> 814 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare.html84
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_idMapping.html100
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_tutorial_and_examples.html246
-rw-r--r--examples/org.eclipse.compare.examples.xml/doc/smartmode_co.gifbin0 -> 229 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/icons/full/obj16/addidmap.gifbin0 -> 125 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/icons/full/obj16/attribute_obj.gifbin0 -> 854 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_obj.gifbin0 -> 851 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_ordered_obj.gifbin0 -> 875 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/icons/full/obj16/smartmode_co.gifbin0 -> 229 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/icons/full/obj16/text_obj.gifbin0 -> 848 bytes
-rw-r--r--examples/org.eclipse.compare.examples.xml/plugin.properties17
-rw-r--r--examples/org.eclipse.compare.examples.xml/plugin.xml66
-rw-r--r--examples/org.eclipse.compare.examples.xml/schema/preferencePages.xsd77
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AbstractMatching.java315
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AttributesImpl.java331
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ChooseMatcherDropDownAction.java98
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/CreateNewIdMapAction.java63
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/GeneralMatching.java484
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/HungarianMethod.java479
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/IdMap.java142
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/Mapping.java92
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/OrderedMatching.java204
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SWTUtil.java152
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SelectMatcherAction.java34
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLChildren.java30
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareAddIdMapDialog.java140
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditCopyIdMapDialog.java115
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditMappingDialog.java213
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditOrderedDialog.java148
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareMessages.java34
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLComparePreferencePage.java837
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLNode.java165
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLPlugin.java395
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureCreator.java728
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewer.java494
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewerCreator.java31
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/MessageLine.java142
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusDialog.java164
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusInfo.java171
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusUtil.java1
-rw-r--r--examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/xmlcompare.properties109
-rw-r--r--examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/AllXMLCompareTests.java32
-rw-r--r--examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestGeneralMatching.java2378
-rw-r--r--examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestMinCostBipartiteMatching.java352
-rw-r--r--examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestXMLStructureCreator.java200
70 files changed, 9980 insertions, 0 deletions
diff --git a/examples/org.eclipse.compare.examples.xml/.classpath b/examples/org.eclipse.compare.examples.xml/.classpath
new file mode 100644
index 000000000..3d73c0f9a
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/.classpath
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="var" path="JRE_LIB" sourcepath="JRE_SRC"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="tests"/>
+ <classpathentry kind="src" path="/org.eclipse.compare"/>
+ <classpathentry kind="src" path="/org.eclipse.ui"/>
+ <classpathentry kind="src" path="/org.apache.xerces"/>
+ <classpathentry kind="src" path="/org.eclipse.jdt.ui"/>
+ <classpathentry kind="src" path="/org.eclipse.core.runtime"/>
+ <classpathentry kind="src" path="/org.junit"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/examples/org.eclipse.compare.examples.xml/.cvsignore b/examples/org.eclipse.compare.examples.xml/.cvsignore
new file mode 100644
index 000000000..ba077a403
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/.cvsignore
@@ -0,0 +1 @@
+bin
diff --git a/examples/org.eclipse.compare.examples.xml/.project b/examples/org.eclipse.compare.examples.xml/.project
new file mode 100644
index 000000000..c4b46fce7
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/.project
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.compare.examples.xml</name>
+ <comment></comment>
+ <projects>
+ <project>org.apache.xerces</project>
+ <project>org.eclipse.compare</project>
+ <project>org.eclipse.compare.xml</project>
+ <project>org.eclipse.core.runtime</project>
+ <project>org.eclipse.jdt.ui</project>
+ <project>org.eclipse.swt</project>
+ <project>org.eclipse.ui</project>
+ <project>org.junit</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/examples/org.eclipse.compare.examples.xml/IdMaps/ant_test.xml b/examples/org.eclipse.compare.examples.xml/IdMaps/ant_test.xml
new file mode 100644
index 000000000..5587170bc
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/IdMaps/ant_test.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE idmap SYSTEM "idmap.dtd">
+
+<idmap name="ANT">
+ <element signature="root.project." id="name"/>
+ <element signature="root.project.target." id="name"/>
+</idmap>
diff --git a/examples/org.eclipse.compare.examples.xml/IdMaps/idmap.dtd b/examples/org.eclipse.compare.examples.xml/IdMaps/idmap.dtd
new file mode 100644
index 000000000..b60a2faae
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/IdMaps/idmap.dtd
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!ELEMENT idmap (element)*>
+<!ATTLIST idmat
+ name CDATA #REQUIRED>
+<!ELEMENT element EMPTY>
+<!ATTLIST element
+ signature ID #REQUIRED
+ id_attr CDATA #REQUIRED>
diff --git a/examples/org.eclipse.compare.examples.xml/about.html b/examples/org.eclipse.compare.examples.xml/about.html
new file mode 100644
index 000000000..9db411aab
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/about.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+<head>
+<title>About</title>
+<meta http-equiv=Content-Type content="text/html; charset=ISO-8859-1">
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>20th June, 2002</p>
+<h3>License</h3>
+<p>Eclipse.org makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise indicated below, the Content is provided to you under the terms and conditions of the
+Common Public License Version 1.0 (&quot;CPL&quot;). A copy of the CPL is available at <a href="http://www.eclipse.org/legal/cpl-v10.html">http://www.eclipse.org/legal/cpl-v10.html</a>.
+For purposes of the CPL, &quot;Program&quot; will mean the Content.</p>
+
+<h3>Contributions</h3>
+
+<p>If this Content is licensed to you under the terms and conditions of the CPL, any Contributions, as defined in the CPL, uploaded, submitted, or otherwise
+made available to Eclipse.org, members of Eclipse.org and/or the host of Eclipse.org web site, by you that relate to such
+Content are provided under the terms and conditions of the CPL and can be made available to others under the terms of the CPL.</p>
+
+<p>If this Content is licensed to you under license terms and conditions other than the CPL (&quot;Other License&quot;), any modifications, enhancements and/or
+other code and/or documentation (&quot;Modifications&quot;) uploaded, submitted, or otherwise made available to Eclipse.org, members of Eclipse.org and/or the
+host of Eclipse.org, by you that relate to such Content are provided under terms and conditions of the Other License and can be made available
+to others under the terms of the Other License. In addition, with regard to Modifications for which you are the copyright holder, you are also
+providing the Modifications under the terms and conditions of the CPL and such Modifications can be made available to others under the terms of
+the CPL.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/build.properties b/examples/org.eclipse.compare.examples.xml/build.properties
new file mode 100644
index 000000000..b997f8c0c
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/build.properties
@@ -0,0 +1,19 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+source.xmlcompareexamples.jar = src/
+
+bin.includes = doc-html/,\
+ about.html,\
+ plugin.properties,\
+ plugin.xml,\
+ xmlcompareexamples.jar
+
+src.includes = about.html
diff --git a/examples/org.eclipse.compare.examples.xml/doc/CreateNewIDMapButton.gif b/examples/org.eclipse.compare.examples.xml/doc/CreateNewIDMapButton.gif
new file mode 100644
index 000000000..907a80bfc
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/CreateNewIDMapButton.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/EditCopy.gif b/examples/org.eclipse.compare.examples.xml/doc/EditCopy.gif
new file mode 100644
index 000000000..6e7eb1da8
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/EditCopy.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/IDMapContextMenu.gif b/examples/org.eclipse.compare.examples.xml/doc/IDMapContextMenu.gif
new file mode 100644
index 000000000..e7f2052c3
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/IDMapContextMenu.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/IDMap_GeneralMatching.gif b/examples/org.eclipse.compare.examples.xml/doc/IDMap_GeneralMatching.gif
new file mode 100644
index 000000000..9ff706298
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/IDMap_GeneralMatching.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/IDMap_MyPlugin.gif b/examples/org.eclipse.compare.examples.xml/doc/IDMap_MyPlugin.gif
new file mode 100644
index 000000000..1ddf17172
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/IDMap_MyPlugin.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewIDMapScheme.gif b/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewIDMapScheme.gif
new file mode 100644
index 000000000..7c1d274c5
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewIDMapScheme.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_ContextMenu.gif b/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_ContextMenu.gif
new file mode 100644
index 000000000..93d1dc829
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_ContextMenu.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_PreferencePage.gif b/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_PreferencePage.gif
new file mode 100644
index 000000000..6d6e02b82
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/IDMap_NewMapping_PreferencePage.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/IDMap_SelectMyPlugin.gif b/examples/org.eclipse.compare.examples.xml/doc/IDMap_SelectMyPlugin.gif
new file mode 100644
index 000000000..3b16c755d
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/IDMap_SelectMyPlugin.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/Ordered_MyANT.gif b/examples/org.eclipse.compare.examples.xml/doc/Ordered_MyANT.gif
new file mode 100644
index 000000000..d4278fec0
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/Ordered_MyANT.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewIDMapScheme.gif b/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewIDMapScheme.gif
new file mode 100644
index 000000000..b9ac0da98
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewIDMapScheme.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_ContextMenu.gif b/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_ContextMenu.gif
new file mode 100644
index 000000000..8c882981b
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_ContextMenu.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_PreferencePage.gif b/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_PreferencePage.gif
new file mode 100644
index 000000000..0485d3ca8
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/Ordered_NewOrderedEntry_PreferencePage.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/Ordered_UnorderedScheme.gif b/examples/org.eclipse.compare.examples.xml/doc/Ordered_UnorderedScheme.gif
new file mode 100644
index 000000000..c58e5671b
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/Ordered_UnorderedScheme.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/PreferencePage.gif b/examples/org.eclipse.compare.examples.xml/doc/PreferencePage.gif
new file mode 100644
index 000000000..ba7912b9d
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/PreferencePage.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/addidmap.gif b/examples/org.eclipse.compare.examples.xml/doc/addidmap.gif
new file mode 100644
index 000000000..dad726088
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/addidmap.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/hglegal.htm b/examples/org.eclipse.compare.examples.xml/doc/hglegal.htm
new file mode 100644
index 000000000..b071dbdf4
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/hglegal.htm
@@ -0,0 +1,14 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name="GENERATOR" content="Mozilla/4.73 [en] (Win98; U) [Netscape]">
+ <title>Legal Notices</title>
+</head>
+<body>
+
+<h3>
+<a NAME="Notices"></a>Notices</h3>
+(c) Copyright IBM Corp. 2000, 2001. All Rights Reserved.
+</body>
+</html>
diff --git a/examples/org.eclipse.compare.examples.xml/doc/ngibmcpy.gif b/examples/org.eclipse.compare.examples.xml/doc/ngibmcpy.gif
new file mode 100644
index 000000000..360f8e998
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/ngibmcpy.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare.html b/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare.html
new file mode 100644
index 000000000..512dae01b
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare.html
@@ -0,0 +1,84 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>XML Compare Plugin</title>
+</head>
+<body link="#0000FF" vlink="#800080">
+
+<center><h1>IBM Eclipse Platform XML Compare</h1></center>
+The XML Compare plugin allows you to perform a structural compare of two XML documents. It returns
+a difference tree which indicates which XML elements have been added or removed and &#8212; for modified XML elements &#8212;
+what differences there are with respect to attributes or body text.
+<h2>Installing the plugin</h2>
+<ul>
+<li>Copy the folder <tt>org.eclipse.compare.xml</tt> to the <tt>plugins</tt> subfolder of Eclipse.
+</ul>
+<h2>Using the plugin</h2>
+The plugin is automatically used when comparing files with the extension .xml.
+<br>
+By default, the XML compare uses the <em>Unordered</em> compare method, which ignores the order in which the XML elements appear in the document and matches them so that elements which are most similar are matched.
+There is also an <em>Ordered</em> compare method, which simply compares the XML elements exactly in the order in which they appear in the document. In most cases, this compare method will not be of much use.
+<br>
+The compare method can be changed from a drop-down list in the toolbar of the structure view.
+<br>
+<br>
+When an XML document
+contains elements that can uniquely be identified by an attribute or the text of a child element,
+it is recommended that an ID Mapping Scheme be created for this type of XML document.
+<br>
+<br>
+See <a href="org_eclipse_xmlcompare_tutorial_and_examples.html">Tutorial and Examples</a> for more information on using the plugin.
+<br>
+<h3>ID Mapping Schemes</h3>
+An ID Mapping Scheme specifies for XML elements an attribute or the text of a child element that
+uniquely identifies this element. This assures that &#8212; in the compare process &#8212; the right elements will be
+matched and therefore compared with each other. If for an XML element no ID Mapping is specified, a general matching algorithm
+is be used. However, this general matching algorithm does not always return the desired result.
+The reason for this is that the general matching algorithm looks for a matching of the nodes of the two parsed trees
+to compare that minimizes the differences. The effect is that often two XML elements are matched with are
+structurally similar but represent two completely different entities of information.
+<br>
+<h3>Ordered entries</h3>
+When using the default Unordered compare (with or without id mappings) it is sometimes desired to specify that the children of certain elements be compared in ordered fashion intead of the usual unordered method.
+For example, when comparing ANT files the order of appearance of the children of <tt>target</tt> elements is important.
+<br>In such cases one can create an <i>Ordered entry</i>. An Ordered entry specifies that the direct children of an xml element, identified by its path, will be compared in ordered fashion (attributes however are still compared in unordered way).
+The children of these children will continue to be compared in unordered way, unless otherwise specified.
+<h3>Defining ID Mapping Schemes and Ordered entries</h3>
+ID Mapping Schemes can be created in three different ways:
+<ol>
+<li>By extending the extension point <a href="org_eclipse_xmlcompare_idMapping.html"><em>idMapping</em></a></li>
+<li>Using the <a href="PreferencePage.gif">XML Compare Preference page</a>.</li>
+<li>Using the <a href="CreateNewIDMapButton.gif">Create new Id Map Scheme button</a> in the toolbar and the <a href="IDMapContextMenu.gif">context menu</a>
+</ol>
+Method 1 creates a so-called <em>internal</em> mapping scheme. An internal ID Mapping Scheme
+cannot be edited at runtime. However, using the <a href="EditCopy.gif"><em>Edit Copy</em></a> button in the Preference Page, an editable copy of the
+internal ID Mapping Scheme can be created.
+<br>
+Methods 2 and 3 create so-called <em>user</em> mapping schemes. These are created by the user at runtime and
+can be modified anytime in the Preference Page.
+<p>Internal and user mapping schemes can be associated with a file extension. As a result, when comparing two XML files with this file extension, the particular ID Mapping scheme with this extension
+is automatically used.
+<br>
+<br>
+When creating or editing the ID mapping for a particular XML element, four items must be specified (see <a href="IDMap_NewMapping_PreferencePage.gif">example</a>):
+<ol>
+<li>The element name.</li>
+<li>The element path. This is the path of the element from the root of the XML document to the element's parent.</li>
+<li>The name of the id which will identify the element</li>
+<li>Whether the id name in point 3 is the name of an attribute of the element or the name of one of its children (in which case the text of this child element
+will be used as id).</li>
+</ol>
+<br>
+<hr WIDTH="100%">
+<h1>
+Extension Points</h1>
+Only one extension point is available in the XML Compare plugin. It is used to create
+internal ID Mapping Schemes:
+<ul>
+<li>
+<a href="org_eclipse_xmlcompare_idMapping.html">org.eclipse.xmlcompare.idMapping</a></li>
+</ul>
+<a href="hglegal.htm"><img SRC="ngibmcpy.gif" ALT="Copyright IBM Corp. 2000, 2001. All Rights Reserved." BORDER=0 height=12 width=195></a>
+</body>
+</html>
diff --git a/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_idMapping.html b/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_idMapping.html
new file mode 100644
index 000000000..c50e7a2af
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_idMapping.html
@@ -0,0 +1,100 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>XML Compare Extension Points: idMapping</title>
+</head>
+<body link="#0000FF" vlink="#800080">
+
+<center>
+<h1>
+idMapping</h1></center>
+<b><i>Identifier: </i></b>org.eclipse.compare.xml.idMapping
+<p><b><i>Description: </i></b>This extension point allows to define internal XML ID Mapping
+schemes using the <i>mapping</i> element. These schemes can then be used when performing an XML compare to uniquely identify XML elements by the value of an attribute or the text in a child element.
+<br>Additionally, <i>ordered</i> elements can be used to specify that the direct children of an element should be compared in ordered fashion instead of the default unordered way.
+<p><b><i>Configuration Markup:</i></b>
+<p><tt>&nbsp;&nbsp; &lt;!ELEMENT idmap (mapping*)></tt>
+<br><tt>&nbsp;&nbsp; &lt;!ATTLIST idmap</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CDATA #REQUIRED</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; extension&nbsp;
+CDATA</tt>
+<br><tt>&nbsp;&nbsp; ></tt>
+<ul>
+<li>
+<b>name</b> - the name of the ID Mapping scheme. Should be unique.</li>
+<li>
+<b>extension</b> - (optional) a file extension associated with this ID Mapping Scheme.
+When comparing files with this extension, the current ID Mapping Scheme will automatically be used.
+<br>If an extension is specified, then the extension should also be added in the plugin.xml file of the XML Compare Plugin.
+For example, if we create an ID Mapping Scheme with extension cd, the plugin.xml of the XML Compare Plugin is updated as follows
+(update shown in bold):
+<tt>
+<p>&lt;extension
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;point="org.eclipse.compare.structureMergeViewers">
+<br>&nbsp;&nbsp;&nbsp;&lt;structureMergeViewer
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;extensions="xml,classpath,<b>cd</b>"
+<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.eclipse.compare.xml.XMLStructureViewerCreator">
+<br>&nbsp;&nbsp;&nbsp;&lt;/structureMergeViewer>
+</tt>
+<p><b>Warning: </b>If an extension is associated more than once, only the first association will be considered.
+Also, internal ID Mapping schemes have priority over user ID Mapping schemes when duplicate extensions are defined.
+<p><b>Warning: </b>When an internal ID Mapping scheme with extension association is removed (from a <tt>plugin.xml</tt>), the XML Compare plugin has to be reloaded to disassociate itself from the extension.
+If not, on the first compare of files with this extension, the XML Compare plugin will be used with the default <em>Unordered</em> algorithm.
+(However, at this point the extension will have been disassociated from the XML Plugin, as the plugin has been loaded.)
+</ul>
+<br>
+<p><tt>&nbsp;&nbsp; &lt;!ELEMENT mapping EMPTY></tt>
+<br><tt>&nbsp;&nbsp; &lt;!ATTLIST mapping</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signature&nbsp;
+CDATA #REQUIRED</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+CDATA #REQUIRED</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id-source &nbsp;CDATA</tt>
+<br><tt>&nbsp;&nbsp; ></tt>
+<ul>
+<li>
+<b>signature</b> - the XML path from the root to the current element (see examples below).</li>
+
+<li>
+<b>id</b> - the attribute that identifies this element or the name of the child element
+whose text identifies this element.</li>
+
+<li>
+<b>id-source</b> - (optional) if <em>id</em> is the name of a child element, then this attribute must have
+the value <em>body</em>. If <em>id-source</em> is left out, it is assumed that <em>id</em> is an attribute.</li>
+</ul>
+<br>
+<p><tt>&nbsp;&nbsp; &lt;!ELEMENT ordered EMPTY></tt>
+<br><tt>&nbsp;&nbsp; &lt;!ATTLIST ordered</tt>
+<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; signature&nbsp;
+CDATA #REQUIRED</tt>
+<br><tt>&nbsp;&nbsp; ></tt>
+<ul>
+<li>
+<b>signature</b> - the XML path from the root to the element whose direct children will be compared in ordered fashion instead of the default unordered way.</li>
+</li>
+</ul>
+<b><i>Examples:</i></b>
+<br>The following is an example ID Mappings Scheme for ANT files.
+<br><i>project</i> elements are identified by an attribute <i>name</i>. <i>target</i> elements (which are children of <i>project</i>) are also identified by an attribute <i>name</i>.
+Also, the children of <i>target</i> will be compared in the order in which they appear in the document.
+<tt>
+<p>&lt;idmap name="ANT">
+<br>&nbsp;&nbsp;&nbsp;&nbsp; &lt;mapping signature="project" id="name"/>
+<br>&nbsp;&nbsp;&nbsp;&nbsp; &lt;mapping signature="project>target" id="name"/>
+<br>&nbsp;&nbsp;&nbsp;&nbsp; &lt;ordered signature="project>target"/>
+<br>&lt;idmap>
+</tt>
+<p>The following example illustrates a case where the text of a child element is used as id:
+<tt>
+<p>&lt;idmap name="Book Catalog" extension="book">
+<br>&nbsp;&nbsp;&nbsp;&nbsp; &lt;mapping signature="catalog>book" id="isbn" id-source="body"/>
+<br>&lt;idmap>
+</tt>
+<p><b><i>Supplied Implementation:</i></b>
+<br>The XML Compare plugin defines an ID Mapping scheme for Eclipse <tt>plugin.xml</tt> files, one for <tt>.classpath</tt> files and one for ANT files.
+<p><a href="hglegal.htm"><img SRC="ngibmcpy.gif" ALT="Copyright IBM Corp. 2000, 2001. All Rights Reserved." BORDER=0 height=12 width=195></a>
+</body>
+</html>
diff --git a/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_tutorial_and_examples.html b/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_tutorial_and_examples.html
new file mode 100644
index 000000000..5f23982a3
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/org_eclipse_xmlcompare_tutorial_and_examples.html
@@ -0,0 +1,246 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Tutorial and Examples</title>
+</head>
+<body link="#0000FF" vlink="#800080">
+<h1>Tutorial and Examples</h1>
+<h2><a id="id_mapping" name="id_mapping">
+General Matching vs. ID Mapping Schemes:<br>How to create an ID Mapping Scheme to improve compare results
+</a></h2>
+Consider an example XML file in two slightly different versions, left and right. Assume that the element <tt>extension-point</tt> is uniquely identified by the attribute <tt>id</tt>.
+The textual differences are shown in bold.
+<table>
+<tr>
+<td><tt>
+<br>
+<p>&lt;?xml version="1.0" encoding="UTF-8"?>
+<p>&lt;plugin
+<br>
+&nbsp;&nbsp;&nbsp;name="%Plugin.name"
+<br>
+&nbsp;&nbsp;&nbsp;id="org.eclipse.ui"
+<br>
+&nbsp;&nbsp;&nbsp;version="1.0"
+<br>
+&nbsp;&nbsp;&nbsp;provider-name="Object Technology International, Inc."
+<br>
+&nbsp;&nbsp;&nbsp;class="org.eclipse.ui.internal.WorkbenchPlugin">
+<br>
+<br>&lt;extension-point name="%ExtPoint.editorMenus " id="editorActions"/>
+<br>&lt;extension-point name="%ExtPoint.popupMenus " id="popupMenus"/>
+<br>&lt;extension-point name="%ExtPoint.<b>importWizards</b>" id="<b>importWizards</b>"/>
+<br>
+<p>&lt;/plugin>
+</tt>
+</td>
+<td>
+&nbsp;&nbsp;
+</td>
+<td><tt>
+<p>&lt;?xml version="1.0" encoding="UTF-8"?>
+<p>&lt;plugin
+<br>
+&nbsp;&nbsp;&nbsp;name="%Plugin.name"
+<br>
+&nbsp;&nbsp;&nbsp;id="org.eclipse.ui"
+<br>
+&nbsp;&nbsp;&nbsp;version="1.0"
+<br>
+&nbsp;&nbsp;&nbsp;provider-name="Object Technology International, Inc."
+<br>
+&nbsp;&nbsp;&nbsp;class="org.eclipse.ui.internal.WorkbenchPlugin">
+<br>
+<br>&lt;extension-point name="%ExtPoint.editorMenus " id="editorActions"/>
+<br>&lt;extension-point name="%ExtPoint.popupMenus " id="popupMenus"/>
+<br>&lt;extension-point name="%ExtPoint.<b>exportWizards</b>" id="<b>exportWizards</b>"/>
+<br>
+<p>&lt;/plugin>
+</tt>
+</td>
+</tr>
+</table>
+<br>
+Assume that the order of the elements should be ignored. The structural difference between the two documents consists in the <tt>extension-point</tt> element on the left with <tt>id="importWizards"</tt> being replaced on the right with a new <tt>extension-point</tt> with <tt>id="exportWizards"</tt>.
+Using the general matching algorithm called <em>Unordered</em>, because it ignores the order in which the XML elements appear in the document, we obtain the following tree of differences.
+<br>
+<br>
+<img src="IDMap_GeneralMatching.gif" alt="Difference Tree using General Matching Algorithm">
+<br>
+<br>
+The first two <tt>extension-point</tt> elements are identical and are therefore matched and are not shown in the difference tree. There remains the third <tt>extension-point</tt> element on both sides which, having the same element name, are also matched.
+The difference tree then shows the differences between the third <tt>extension-point</tt> element left and the third <tt>extension-point</tt> element right.
+These differences consist in the values of the attributes <tt>id</tt> and <tt>name</tt>.
+<br>
+However, this is not what we would like to see. We would like the difference tree to show us that an <tt>extension-point</tt> element was removed from the left side and a new <tt>extension-point</tt> element was added on the right side.
+<br>
+To achieve this, we create a new ID Mapping Scheme. We can do this by using the appropriate button on toolbar.
+<br><br>
+<img src="IDMap_NewIDMapScheme.gif" alt="Creating a new ID Mapping Scheme">
+<br><br>
+Assume we call the ID Mapping Scheme <em>MyPlugin</em>. We now select the ID Mapping Scheme MyPlugin from the drop-down list in the Toolbar
+<br><br>
+<img src="IDMap_SelectMyPlugin.gif" alt="Select MyPlugin ID Map Scheme">
+<br><br>
+and add to it the following Mapping:
+<br><br>
+<table>
+<tr>
+<td>
+<img src="IDMap_NewMapping_PreferencePage.gif" alt="Creating a new mapping from the preference page">
+</td>
+<td>
+&nbsp;&nbsp;&nbsp;
+</td>
+<td>
+<img src="IDMap_NewMapping_ContextMenu.gif" alt="Creating a new mapping using the context menu">
+</td>
+</tr>
+</table>
+<br>
+This can be done from the preference page (left) or from the context menu in the structure view (right).
+<br>
+The difference tree now becomes:
+<br>
+(To refresh the structure view, click on the <img src="smartmode_co.gif" alt="Button for updating view"> button of the drop-down list in the toolbar.)
+<br><br>
+<img src="IDMap_MyPlugin.gif" alt="Difference Tree using MyPlugin ID Mapping Scheme">
+<br><br>
+This is the compare result that we wanted and that we achieved by created an ID Mapping Scheme.
+<br>
+<br>
+The XML Compare Plugin already comes with a ID Mapping Scheme for Plugin files, which can be customized for particular Plugin files.
+<br><br>
+<b>Warning:</b>
+<br>
+If an ID Mapping is created, it is assumed that the id is unique, i.e. there are no two XML elements with the same name and path that have the same id.
+Should this not be the case, the ID Mapping Scheme may not deliver a sensible difference tree.
+<br>
+When an id can appear more than once, one should rely on the general algorithm.
+<br>
+<br>
+Also, when an ID Mapping Scheme is used and there are elements with no id mapping specified, the <em>Unordered</em> compare method will be used, i.e. elements are matched by their similarity and not by the order in which they appear in the document.
+To specify that the children of an element should be compared in order of appearance. See the next section on Ordered entries.
+
+<h2>Adding Ordered entries</h2>
+Ordered entries are used to specify that the direct children (excluding attributes) of an xml element &#8212; identified by its path &#8212; should be compared in ordered way instead of the default unordered method.
+<br> As an example consider the following ANT file in two slightly different versions:
+<table>
+<tr>
+<td>
+<tt>
+<p>&lt;?xml version="1.0" encoding="UTF-8"?>
+<p>&lt;project name="org.junit.wizards" default="export" basedir="..">
+<br>
+&nbsp;&nbsp;&nbsp;&lt;target name="export" depends="build">
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mkdir dir="${destdir}" />
+<br>
+<b>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;delete dir="${dest}" />
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mkdir dir="${dest}" />
+<br>
+</b>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jar
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jarfile="${dest}/JUnitWizard.jar"
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;basedir="bin"
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/>
+<br>&lt;/project>
+</tt>
+</td>
+<td>
+&nbsp;&nbsp;
+</td>
+<td>
+<tt>
+<p>&lt;?xml version="1.0" encoding="UTF-8"?>
+<p>&lt;project name="org.junit.wizards" default="export" basedir="..">
+<br>
+&nbsp;&nbsp;&nbsp;&lt;target name="export" depends="build">
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mkdir dir="${destdir}"/>
+<br>
+<b>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mkdir dir="${dest}"/>
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;delete dir="${dest}"/>
+<br>
+</b>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;jar
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jarfile="${dest}/JUnitWizard.jar"
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;basedir="bin"
+<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/>
+<br>
+<b>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;copy file="plugin.xml" todir="${dest}"/>
+</b>
+<br>&lt;/project>
+</tt>
+</td>
+</tr>
+</table>
+<br>
+The differences between the two documents are shown in bold. Two elements have been swapped (<tt>&lt;mkdir dir="${dest}"/></tt> and <tt>&lt;delete dir="${dest}"/></tt>) and a new element (<tt>&lt;copy .../></tt>) has been appended to the target element.
+<br>
+Performing an unordered compare will result in the following tree of differences:
+<br>
+<br>
+<img src="Ordered_UnorderedScheme.gif" alt="Difference Tree using Unordered Matching">
+<br>
+<br>
+The fact that two elements have been swapped is not shown since the order of elements is ignored.
+<br>
+However, from an ANT point of view, the two documents cause very different behaviour, because the order of the elements inside a <tt>target</tt> is important.
+We therefore want to create an <i>ordered entry</i> for target to instruct the compare engine to compare the direct children of target in ordered fashion.
+<br>
+We do so by first creating a new ID Mapping Scheme. This can be done using the appropriate button in the toolbar.
+<br><br>
+<img src="Ordered_NewIDMapScheme.gif" alt="Creating a new ID Mapping Scheme">
+<br><br>
+Assume we call the ID Mapping Scheme <em>MyANT</em>.
+<br>We now select the ID Mapping Scheme MyANT from the drop-down list in the Toolbar and add to it the following Ordered Entry:
+<br><br>
+<table>
+<tr>
+<td>
+<img src="Ordered_NewOrderedEntry_PreferencePage.gif" alt="Creating a new orderered entry from the preference page">
+</td>
+<td>
+&nbsp;&nbsp;&nbsp;
+</td>
+<td>
+<img src="Ordered_NewOrderedEntry_ContextMenu.gif" alt="Creating a new ordered entry using the context menu">
+</td>
+</tr>
+</table>
+<br>
+This can be done from the preference page (left) or from the context menu in the structure view (right).
+<br>
+The difference tree now becomes:
+<br>
+(To refresh the structure view, click on the <img src="smartmode_co.gif" alt="Button for updating view"> button of the drop-down list in the toolbar.)
+<br><br>
+<img src="Ordered_MyANT.gif" alt="Difference Tree using MyANT ID Mapping Scheme">
+<br><br>
+This is the compare result that we wanted and that we achieved by creating an Ordered Entry.
+<br>
+<br>
+Additionally, Id Mappings (see <a href="#id_mapping">previous section</a>) can be used to uniquely identify ordered children. Especially when there are many changes, this will improve compare results.
+<br>
+<br>
+The XML Compare Plugin already comes with a ID Mapping Scheme for ANT files, which can be customized for particular ANT files.
+<br><br>
+
+
+<br><br>
+<a href="hglegal.htm"><img SRC="ngibmcpy.gif" ALT="Copyright IBM Corp. 2000, 2001. All Rights Reserved." BORDER=0 height=12 width=195></a>
+</body>
+</html>
diff --git a/examples/org.eclipse.compare.examples.xml/doc/smartmode_co.gif b/examples/org.eclipse.compare.examples.xml/doc/smartmode_co.gif
new file mode 100644
index 000000000..c2a47b6a2
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/doc/smartmode_co.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/icons/full/obj16/addidmap.gif b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/addidmap.gif
new file mode 100644
index 000000000..dad726088
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/addidmap.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/icons/full/obj16/attribute_obj.gif b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/attribute_obj.gif
new file mode 100644
index 000000000..d81ce489e
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/attribute_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_obj.gif b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_obj.gif
new file mode 100644
index 000000000..c663550e5
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_ordered_obj.gif b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_ordered_obj.gif
new file mode 100644
index 000000000..0b2775edf
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/element_ordered_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/icons/full/obj16/smartmode_co.gif b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/smartmode_co.gif
new file mode 100644
index 000000000..c2a47b6a2
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/smartmode_co.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/icons/full/obj16/text_obj.gif b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/text_obj.gif
new file mode 100644
index 000000000..72a802e41
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/icons/full/obj16/text_obj.gif
Binary files differ
diff --git a/examples/org.eclipse.compare.examples.xml/plugin.properties b/examples/org.eclipse.compare.examples.xml/plugin.properties
new file mode 100644
index 000000000..b5c6a6168
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/plugin.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+#
+# Resource strings for XML Compare Examples plugin.xml file
+#
+pluginName= XML Compare Support
+providerName= Eclipse.org
+pluginNamePreferencePage= XML Compare
+idMapping= ID Mapping
diff --git a/examples/org.eclipse.compare.examples.xml/plugin.xml b/examples/org.eclipse.compare.examples.xml/plugin.xml
new file mode 100644
index 000000000..ae5130985
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/plugin.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- File written by PDE 1.0 -->
+<plugin
+ id="org.eclipse.compare.examples.xml"
+ name="%pluginName"
+ version="3.0.0"
+ provider-name="%providerName"
+ class="org.eclipse.compare.examples.xml.XMLPlugin">
+
+ <!-- Required plugins -->
+ <requires>
+ <import plugin="org.eclipse.ui"/>
+ <import plugin="org.eclipse.core.resources"/>
+ <import plugin="org.eclipse.compare"/>
+ <import plugin="org.apache.xerces"/>
+ </requires>
+
+ <!-- Runtime -->
+ <runtime>
+ <library name="xmlcompareexamples.jar">
+ <export name="*"/>
+ </library>
+ </runtime>
+
+ <!-- Extensions -->
+ <extension-point id="idMapping" name="%idMapping"/>
+
+ <!-- Extension points -->
+ <extension
+ point="org.eclipse.compare.structureMergeViewers">
+ <structureMergeViewer
+ extensions="xml,classpath"
+ class="org.eclipse.compare.examples.xml.XMLStructureViewerCreator">
+ </structureMergeViewer>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page name="%pluginNamePreferencePage"
+ id="org.eclipse.compare.examples.xml.XMLComparePreferencePage"
+ class="org.eclipse.compare.examples.xml.XMLComparePreferencePage"
+ category= "org.eclipse.ui.preferencePages.Workbench">
+ </page>
+ </extension>
+
+ <extension
+ point="org.eclipse.compare.examples.xml.idMapping">
+ <idmap name="ANT">
+ <mapping signature="project" id="name"/>
+ <mapping signature="project>target" id="name"/>
+ <ordered signature="project>target"/>
+ </idmap>
+ <idmap name="Eclipse Plugin">
+ <mapping signature="plugin" id="id"/>
+ <mapping signature="plugin>requires>import" id="plugin"/>
+ <mapping signature="plugin>runtime>library" id="name"/>
+ <mapping signature="plugin>runtime>library>export" id="name"/>
+ <mapping signature="plugin>extension-point" id="id"/>
+ <mapping signature="plugin>extension" id="point"/>
+ </idmap>
+ <idmap name="Eclipse ClassPath" extension="CLASSPATH">
+ <mapping signature="classpath>classpathentry" id="path"/>
+ </idmap>
+ </extension>
+
+</plugin>
diff --git a/examples/org.eclipse.compare.examples.xml/schema/preferencePages.xsd b/examples/org.eclipse.compare.examples.xml/schema/preferencePages.xsd
new file mode 100644
index 000000000..1d63422a8
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/schema/preferencePages.xsd
@@ -0,0 +1,77 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.compare.xml">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.compare.xml" id="preferencePages" name="%ExtPoint.preferencePages"/>
+ </appInfo>
+ <documentation>
+ [Enter description of this extension point]
+ </documentation>
+</annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ [Enter extension point usage example here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ [Enter API information here.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+ [Enter information about supplied implementation of this extension point.]
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AbstractMatching.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AbstractMatching.java
new file mode 100644
index 000000000..30be2d0bd
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AbstractMatching.java
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+import org.eclipse.compare.rangedifferencer.IRangeComparator;
+import org.eclipse.compare.rangedifferencer.RangeDifference;
+import org.eclipse.compare.rangedifferencer.RangeDifferencer;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * @version 1.0
+ * @author
+ */
+public abstract class AbstractMatching {
+
+ protected static final int NO_ENTRY = -1;//value with which fDT elements are initialized
+ protected static final String SIGN_ELEMENT= XMLStructureCreator.SIGN_ELEMENT;
+ int[][] fDT;//Distance Table; 1st index from fNLeft, 2nd index from fNRight
+ ArrayList[][] fDT_Matchings;//Mathing entries of children for a match. 1st index from fNLeft, 2nd index from fNRight
+ Vector fNLeft;
+ Vector fNRight;
+ Vector fMatches;
+
+ /* methods used for match */
+
+ /* finds all the leaves of a tree and puts them in a vector */
+ protected void findLeaves(XMLNode root, ArrayList leaves) {
+ if (isLeaf(root)) {
+ leaves.add(root);
+ } else {
+ Object[] children = root.getChildren();
+ for (int i=0; i<children.length; i++)
+ findLeaves((XMLNode) children[i], leaves);
+ }
+ }
+
+ /* true if x is a leaf */
+ protected boolean isLeaf(XMLNode x) {
+ if (x == null) return true;
+ return x.getChildren() == null || x.getChildren().length <= 0;
+ }
+
+ /* Numbers all nodes of tree. The number of x is its index in the vector numbering */
+ protected void numberNodes(XMLNode root, Vector numbering) {
+ if (root != null) {
+ numbering.add(root);
+ Object[] children = root.getChildren();
+ if (children != null) {
+ for (int i=0; i<children.length; i++)
+ numberNodes((XMLNode) children[i], numbering);
+ }
+ }
+ }
+
+ /* counts # of nodes in tree including root */
+ protected int countNodes(XMLNode root) {
+ if (root == null) return 0;
+ int count = 1;
+ if (isLeaf(root)) return count;
+ Object[] children = root.getChildren();
+ for (int i=0; i<children.length; i++)
+ count+=countNodes((XMLNode) children[i]);
+ return count;
+ }
+
+ /* returns index of node x in fNLeft */
+ protected int indexOfLN (XMLNode x) {
+ int i;
+ for (i=0; (i<fNLeft.size()) && (fNLeft.elementAt(i) != x); i++);
+ return i;
+ }
+
+ /* returns index of node y in fNRight */
+ protected int indexOfRN (XMLNode y) {
+ int j;
+ for (j=0; (j<fNRight.size()) && (fNRight.elementAt(j) != y); j++);
+ return j;
+ }
+
+/* for testing */
+ public Vector getMatches() {
+ return fMatches;
+ }
+
+ protected class XMLComparator implements IRangeComparator {
+
+ private Object[] fXML_elements;
+
+ public XMLComparator(Object[] xml_elements) {
+ fXML_elements= xml_elements;
+ }
+
+ /*
+ * @see IRangeComparator#getRangeCount()
+ */
+ public int getRangeCount() {
+ return fXML_elements.length;
+ }
+
+ /*
+ * @see IRangeComparator#rangesEqual(int, IRangeComparator, int)
+ */
+ public boolean rangesEqual(
+ int thisIndex,
+ IRangeComparator other_irc,
+ int otherIndex) {
+
+ if (other_irc instanceof XMLComparator) {
+ XMLComparator other= (XMLComparator) other_irc;
+ //return ((XMLNode)fXML_elements[thisIndex]).subtreeEquals(other.getXML_elements()[otherIndex]);
+
+ //ordered compare of subtrees
+ //boolean result= ((XMLNode)fXML_elements[thisIndex]).subtreeEquals(other.getXML_elements()[otherIndex]);
+
+ //taking ids into account
+ boolean sameId= false;
+ XMLNode thisNode= (XMLNode)fXML_elements[thisIndex];
+ XMLNode otherNode= (XMLNode)other.getXML_elements()[otherIndex];
+ if ( thisNode.usesIDMAP() && otherNode.usesIDMAP() ) {
+ if ( otherNode.getOrigId().equals(thisNode.getOrigId()) ) {
+ sameId= true;
+ }
+ }
+
+ //unordered compare of subtrees
+ int distance= dist((XMLNode)other.getXML_elements()[otherIndex] , (XMLNode)fXML_elements[thisIndex]);
+ return sameId || distance == 0;
+ }
+ return false;
+ }
+
+ /*
+ * @see IRangeComparator#skipRangeComparison(int, int, IRangeComparator)
+ */
+ public boolean skipRangeComparison(
+ int length,
+ int maxLength,
+ IRangeComparator other) {
+ return false;
+ }
+
+ public Object[] getXML_elements() {
+ return fXML_elements;
+ }
+
+ }
+
+ /* represents a matching between a node in the Left tree and a node in the Right tree */
+ class Match {
+ public XMLNode fx;
+ public XMLNode fy;
+
+ Match(XMLNode x, XMLNode y) {
+ fx = x;
+ fy = y;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof Match) {
+ Match m = (Match) obj;
+ if (m != null)
+ return fx == m.fx && fy == m.fy;
+ }
+ return false;
+ }
+ }
+
+ protected int handleRangeDifferencer(Object[] xc_elements, Object[] yc_elements, ArrayList DTMatching, int distance) {
+ RangeDifference[] differences= RangeDifferencer.findDifferences(new XMLComparator(xc_elements), new XMLComparator(yc_elements));
+
+ int cur_pos_left= 0;
+ int cur_pos_right= 0;
+ for (int i= 0; i < differences.length; i++) {
+ RangeDifference rd= differences[i];
+ int equal_length= rd.leftStart();
+ //handle elements before current range which are unchanged
+ while (cur_pos_left < equal_length) {
+ //assuming XMLComparator has already filled fDT and fDT_Matchings for subtrees
+ //rooted at xc_elements[cur_pos_left] and yc_elements[cur_pos_right]
+// if ( fDT[indexOfLN( (XMLNode)xc_elements[cur_pos_left])][indexOfRN( (XMLNode)yc_elements[cur_pos_right])] != 0)
+// System.out.println("distance not 0");
+// distance += fDT[indexOfLN( (XMLNode)xc_elements[cur_pos_left])][indexOfRN( (XMLNode)yc_elements[cur_pos_right])];
+ //DTMatching.addAll(fDT_Matchings[index_left][index_right]);
+ DTMatching.add(new Match( (XMLNode)xc_elements[cur_pos_left], (XMLNode)yc_elements[cur_pos_right]));
+ cur_pos_left++;
+ cur_pos_right++;
+ }
+ //now handle RangeDifference rd[i]
+ int smaller_length, greater_length;
+ boolean leftGreater= rd.leftLength() > rd.rightLength();
+ if (leftGreater) {
+ smaller_length= rd.rightLength();
+ greater_length= rd.leftLength();
+ } else {
+ smaller_length= rd.leftLength();
+ greater_length= rd.rightLength();
+ }
+
+ //handle elements elements in range
+ for (int j=0; j < smaller_length; j++) {
+ distance += dist((XMLNode) xc_elements[cur_pos_left], (XMLNode) yc_elements[cur_pos_right]);
+ DTMatching.add(new Match( (XMLNode)xc_elements[cur_pos_left], (XMLNode)yc_elements[cur_pos_right]));
+ cur_pos_left++;
+ cur_pos_right++;
+ }
+ //int cur_pos_greater= (leftGreater)?cur_pos_left:cur_pos_right;
+ if (leftGreater) {
+ for (int j=smaller_length; j < greater_length; j++) {
+ distance += countNodes((XMLNode) xc_elements[cur_pos_left]);
+ DTMatching.add(new Match( (XMLNode)xc_elements[cur_pos_left], null));
+ cur_pos_left++;
+ }
+ } else {
+ for (int j=smaller_length; j < greater_length; j++) {
+ distance += countNodes((XMLNode) yc_elements[cur_pos_right]);
+ DTMatching.add(new Match( null, (XMLNode)yc_elements[cur_pos_right]));
+ cur_pos_right++;
+ }
+ }
+// for (int j=smaller_length; j < greater_length; j++) {
+// distance += countNodes((XMLNode) xc_elements[cur_pos_greater]);
+// cur_pos_greater++;
+// }
+// if (leftGreater)
+// cur_pos_left= cur_pos_greater;
+// else
+// cur_pos_right= cur_pos_greater;
+ }
+
+ for (int i= cur_pos_left; i < xc_elements.length; i++) {
+ //distance += fDT[indexOfLN( (XMLNode)xc_elements[cur_pos_left])][indexOfRN( (XMLNode)yc_elements[cur_pos_right])];
+ //DTMatching.addAll(fDT_Matchings[index_left][index_right]);
+ DTMatching.add(new Match( (XMLNode)xc_elements[cur_pos_left], (XMLNode)yc_elements[cur_pos_right]));
+ cur_pos_left++;
+ cur_pos_right++;
+ }
+
+ return distance;
+ }
+
+ abstract public void match(XMLNode LeftTree, XMLNode RightTree, boolean rightTreeIsAncestor, IProgressMonitor monitor) throws InterruptedException;
+
+ protected int dist(XMLNode x, XMLNode y) {
+ //System.out.println("dist( "+x.getSignature()+" , "+y.getSignature()+")");
+ int ret= NO_ENTRY;
+
+ int index_x= indexOfLN(x);
+ int index_y= indexOfRN(y);
+ if (fDT[index_x][index_y] != NO_ENTRY) return fDT[index_x][index_y];
+
+ if (isLeaf(x) && isLeaf(y)) {
+ if (x.getXMLType() == XMLStructureCreator.TYPE_ELEMENT) {
+ if ( x.getSignature().equals(y.getSignature()) ) {
+ ret= 0;
+ fDT[index_x][index_y] = ret;
+ return ret;
+ } else {
+ ret= 2;
+ fDT[index_x][index_y] = ret;
+ return ret;
+ }
+ } else if (x.getXMLType() == XMLStructureCreator.TYPE_ATTRIBUTE || x.getXMLType() == XMLStructureCreator.TYPE_TEXT) {
+ if ( x.getSignature().equals(y.getSignature()) ) {
+ if (x.getValue().equals(y.getValue())) {
+ ret= 0;
+ fDT[index_x][index_y] = ret;
+ return ret;
+ } else {
+ ret= 1;
+ fDT[index_x][index_y] = ret;
+ return ret;
+ }
+ }
+ else {
+ ret= 2;
+ fDT[index_x][index_y] = ret;
+ return ret;
+ }
+ }
+ } else {//x or y are not leaves
+ if ( !x.getSignature().equals(y.getSignature()) ) {
+ ret= countNodes(x) + countNodes(y);
+ fDT[index_x][index_y] = ret;
+ return ret;
+ } else {//x.getSignature().equals(y.getSignature())
+ if (isLeaf(x)) {
+ ret= countNodes(y)-1;
+ fDT[index_x][index_y] = ret;
+ return ret;
+ }
+ if (isLeaf(y)) {
+ ret= countNodes(x)-1;
+ fDT[index_x][index_y] = ret;
+ return ret;
+ }
+ //both x and y have children
+ return handleXandYnotLeaves(x,y);
+ }
+ }
+ return ret;
+ }
+
+ abstract int handleXandYnotLeaves(XMLNode x, XMLNode y);
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AttributesImpl.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AttributesImpl.java
new file mode 100644
index 000000000..2b4f1e444
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/AttributesImpl.java
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import org.xml.sax.Attributes;
+
+/**
+ * An Attributes implementation that can perform more operations
+ * than the attribute list helper supplied with the standard SAX2
+ * distribution.
+ */
+public class AttributesImpl implements Attributes {
+
+ /** Head node. */
+ private ListNode fHead;
+
+ /** Tail node. */
+ private ListNode fTail;
+
+ /** Length. */
+ private int fLength;
+
+
+ /** Returns the number of attributes. */
+ public int getLength() {
+ return fLength;
+ }
+
+ /** Returns the index of the specified attribute. */
+ public int getIndex(String raw) {
+ ListNode place= fHead;
+ int index= 0;
+ while (place != null) {
+ if (place.raw.equals(raw)) {
+ return index;
+ }
+ index++;
+ place= place.next;
+ }
+ return -1;
+ }
+
+ /** Returns the index of the specified attribute. */
+ public int getIndex(String uri, String local) {
+ ListNode place= fHead;
+ int index= 0;
+ while (place != null) {
+ if (place.uri.equals(uri) && place.local.equals(local)) {
+ return index;
+ }
+ index++;
+ place= place.next;
+ }
+ return -1;
+ }
+
+ /** Returns the attribute URI by index. */
+ public String getURI(int index) {
+
+ ListNode node= getListNodeAt(index);
+ return node != null ? node.uri : null;
+ }
+
+ /** Returns the attribute local name by index. */
+ public String getLocalName(int index) {
+
+ ListNode node= getListNodeAt(index);
+ return node != null ? node.local : null;
+ }
+
+ /** Returns the attribute raw name by index. */
+ public String getQName(int index) {
+
+ ListNode node= getListNodeAt(index);
+ return node != null ? node.raw : null;
+
+ }
+
+ /** Returns the attribute type by index. */
+ public String getType(int index) {
+
+ ListNode node= getListNodeAt(index);
+ return (node != null) ? node.type : null;
+ }
+
+ /** Returns the attribute type by uri and local. */
+ public String getType(String uri, String local) {
+
+ ListNode node= getListNode(uri, local);
+ return (node != null) ? node.type : null;
+
+ }
+
+ /** Returns the attribute type by raw name. */
+ public String getType(String raw) {
+
+ ListNode node= getListNode(raw);
+ return (node != null) ? node.type : null;
+ }
+
+ /** Returns the attribute value by index. */
+ public String getValue(int index) {
+
+ ListNode node= getListNodeAt(index);
+ return (node != null) ? node.value : null;
+ }
+
+ /** Returns the attribute value by uri and local. */
+ public String getValue(String uri, String local) {
+
+ ListNode node= getListNode(uri, local);
+ return (node != null) ? node.value : null;
+ }
+
+ /** Returns the attribute value by raw name. */
+ public String getValue(String raw) {
+
+ ListNode node= getListNode(raw);
+ return (node != null) ? node.value : null;
+ }
+
+ /** Adds an attribute. */
+ public void addAttribute(String raw, String type, String value) {
+ addAttribute(null, null, raw, type, value);
+ }
+
+ /** Adds an attribute. */
+ public void addAttribute(
+ String uri,
+ String local,
+ String raw,
+ String type,
+ String value) {
+
+ ListNode node= new ListNode(uri, local, raw, type, value);
+ if (fLength == 0) {
+ fHead= node;
+ } else {
+ fTail.next= node;
+ }
+ fTail= node;
+ fLength++;
+ }
+
+ /** Inserts an attribute. */
+ public void insertAttributeAt(
+ int index,
+ String raw,
+ String type,
+ String value) {
+ insertAttributeAt(index, null, null, raw, type, value);
+ }
+
+ /** Inserts an attribute. */
+ public void insertAttributeAt(
+ int index,
+ String uri,
+ String local,
+ String raw,
+ String type,
+ String value) {
+
+ // if list is empty, add attribute
+ if (fLength == 0 || index >= fLength) {
+ addAttribute(uri, local, raw, type, value);
+ return;
+ }
+
+ // insert at beginning of list
+ ListNode node= new ListNode(uri, local, raw, type, value);
+ if (index < 1) {
+ node.next= fHead;
+ fHead= node;
+ } else {
+ ListNode prev= getListNodeAt(index - 1);
+ node.next= prev.next;
+ prev.next= node;
+ }
+ fLength++;
+ }
+
+ /** Removes an attribute. */
+ public void removeAttributeAt(int index) {
+
+ if (fLength == 0)
+ return;
+
+ if (index == 0) {
+ fHead= fHead.next;
+ if (fHead == null) {
+ fTail= null;
+ }
+ fLength--;
+ } else {
+ ListNode prev= getListNodeAt(index - 1);
+ ListNode node= getListNodeAt(index);
+ if (node != null) {
+ prev.next= node.next;
+ if (node == fTail) {
+ fTail= prev;
+ }
+ fLength--;
+ }
+ }
+ }
+
+ /** Removes the specified attribute. */
+ public void removeAttribute(String raw) {
+ removeAttributeAt(getIndex(raw));
+ }
+
+ /** Removes the specified attribute. */
+ public void removeAttribute(String uri, String local) {
+ removeAttributeAt(getIndex(uri, local));
+ }
+
+ /** Returns the node at the specified index. */
+ private ListNode getListNodeAt(int i) {
+
+ for (ListNode place= fHead; place != null; place= place.next) {
+ if (--i == -1) {
+ return place;
+ }
+ }
+ return null;
+ }
+
+ /** Returns the first node with the specified uri and local. */
+ public ListNode getListNode(String uri, String local) {
+
+ if (uri != null && local != null) {
+ ListNode place= fHead;
+ while (place != null) {
+ if (place.uri != null
+ && place.local != null
+ && place.uri.equals(uri)
+ && place.local.equals(local)) {
+ return place;
+ }
+ place= place.next;
+ }
+ }
+ return null;
+ }
+
+ /** Returns the first node with the specified raw name. */
+ private ListNode getListNode(String raw) {
+
+ if (raw != null) {
+ for (ListNode place= fHead; place != null; place= place.next) {
+ if (place.raw != null && place.raw.equals(raw)) {
+ return place;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /** Returns a string representation of this object. */
+ public String toString() {
+ StringBuffer str= new StringBuffer();
+
+ str.append('[');
+ str.append("len="); //$NON-NLS-1$
+ str.append(fLength);
+ str.append(", {"); //$NON-NLS-1$
+ for (ListNode place= fHead; place != null; place= place.next) {
+ str.append(place.toString());
+ if (place.next != null) {
+ str.append(", "); //$NON-NLS-1$
+ }
+ }
+ str.append("}]"); //$NON-NLS-1$
+
+ return str.toString();
+ }
+
+ /**
+ * An attribute node.
+ */
+ static class ListNode {
+
+ /** Attribute uri. */
+ public String uri;
+
+ /** Attribute local. */
+ public String local;
+
+ /** Attribute raw. */
+ public String raw;
+
+ /** Attribute type. */
+ public String type;
+
+ /** Attribute value. */
+ public String value;
+
+ /** Next node. */
+ public ListNode next;
+
+ /** Constructs a list node. */
+ public ListNode(
+ String uri0,
+ String local0,
+ String raw0,
+ String type0,
+ String value0) {
+
+ this.uri= uri0;
+ this.local= local0;
+ this.raw= raw0;
+ this.type= type0;
+ this.value= value0;
+
+ }
+
+ /** Returns string representation of this object. */
+ public String toString() {
+ return raw != null ? raw : local;
+ }
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ChooseMatcherDropDownAction.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ChooseMatcherDropDownAction.java
new file mode 100644
index 000000000..2940c98e8
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ChooseMatcherDropDownAction.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.*;
+
+import org.eclipse.jface.action.*;
+
+
+/**
+ * Drop down menu to select a particular id mapping scheme
+ */
+class ChooseMatcherDropDownAction extends Action implements IMenuCreator {
+
+ private XMLStructureViewer fViewer;
+
+ public ChooseMatcherDropDownAction(XMLStructureViewer viewer) {
+ fViewer = viewer;
+ setText(XMLCompareMessages.getString("ChooseMatcherDropDownAction.text")); //$NON-NLS-1$
+ setImageDescriptor(XMLPlugin.getDefault().getImageDescriptor("obj16/smartmode_co.gif")); //$NON-NLS-1$
+ setToolTipText(XMLCompareMessages.getString("ChooseMatcherDropDownAction.tooltip")); //$NON-NLS-1$
+ setMenuCreator(this);
+ }
+
+ public void dispose() {
+ }
+
+ public Menu getMenu(Menu parent) {
+ return null;
+ }
+
+ public Menu getMenu(Control parent) {
+ XMLPlugin plugin= XMLPlugin.getDefault();
+ Menu menu= new Menu(parent);
+ addActionToMenu(menu, new SelectMatcherAction(XMLStructureCreator.USE_UNORDERED, fViewer));
+ addActionToMenu(menu, new SelectMatcherAction(XMLStructureCreator.USE_ORDERED, fViewer));
+ new MenuItem(menu, SWT.SEPARATOR);
+ HashMap IdMaps = plugin.getIdMaps();
+ HashMap IdMapsInternal = plugin.getIdMapsInternal();
+
+ Set keySetIdMaps = IdMaps.keySet();
+ Set keySetIdMapsInternal = IdMapsInternal.keySet();
+ ArrayList internalIdMapsAL= new ArrayList();
+ for (Iterator iter_internal = keySetIdMapsInternal.iterator(); iter_internal.hasNext(); ) {
+ String idmap_name = (String)iter_internal.next();
+ internalIdMapsAL.add(idmap_name);
+ }
+ Object[] internalIdMapsA= internalIdMapsAL.toArray();
+ Arrays.sort(internalIdMapsA);
+ for (int i= 0; i < internalIdMapsA.length; i++) {
+ addActionToMenu(menu, new SelectMatcherAction((String)internalIdMapsA[i], fViewer));
+ }
+ new MenuItem(menu, SWT.SEPARATOR);
+
+ ArrayList userIdMapsAL= new ArrayList();
+ for (Iterator iter_idmaps = keySetIdMaps.iterator(); iter_idmaps.hasNext(); ) {
+ String idmap_name = (String)iter_idmaps.next();
+ userIdMapsAL.add(idmap_name);
+ }
+
+ HashMap OrderedElements= plugin.getOrderedElements();
+ Set keySetOrdered= OrderedElements.keySet();
+ for (Iterator iter_orderedElements= keySetOrdered.iterator(); iter_orderedElements.hasNext();) {
+ String idmap_name= (String) iter_orderedElements.next();
+ if (!keySetIdMaps.contains(idmap_name)) {
+ userIdMapsAL.add(idmap_name);
+ }
+ }
+
+ Object[] userIdMapsA= userIdMapsAL.toArray();
+ Arrays.sort(userIdMapsA);
+ for (int i= 0; i < userIdMapsA.length; i++) {
+ addActionToMenu(menu, new SelectMatcherAction((String)userIdMapsA[i], fViewer));
+ }
+
+ return menu;
+ }
+
+ protected void addActionToMenu(Menu parent, Action action) {
+ ActionContributionItem item= new ActionContributionItem(action);
+ item.fill(parent, -1);
+ }
+
+ public void run() {
+ fViewer.contentChanged();
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/CreateNewIdMapAction.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/CreateNewIdMapAction.java
new file mode 100644
index 000000000..9494c8fbe
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/CreateNewIdMapAction.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.*;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.window.Window;
+
+/**
+ * Button to create a new id mapping scheme
+ */
+public class CreateNewIdMapAction extends Action {
+
+ private HashMap fIdMaps;// HashMap ( idname -> HashMap (signature -> id) )
+ private HashMap fIdMapsInternal;
+ private HashMap fIdExtensionToName;
+
+ public CreateNewIdMapAction(XMLStructureViewer viewer) {
+ setImageDescriptor(XMLPlugin.getDefault().getImageDescriptor("obj16/addidmap.gif")); //$NON-NLS-1$
+ setToolTipText(XMLCompareMessages.getString("XMLStructureViewer.newtask")); //$NON-NLS-1$
+ }
+
+ public void run() {
+ XMLPlugin plugin= XMLPlugin.getDefault();
+ fIdMapsInternal= plugin.getIdMapsInternal();//fIdMapsInternal is only read, not modified
+
+ fIdMaps = new HashMap();
+ HashMap PluginIdMaps = plugin.getIdMaps();
+ Set keySet = PluginIdMaps.keySet();
+ for (Iterator iter = keySet.iterator(); iter.hasNext(); ) {
+ String key = (String) iter.next();
+ fIdMaps.put(key, ((HashMap)PluginIdMaps.get(key)).clone());
+ }
+
+ fIdExtensionToName= new HashMap();
+ HashMap PluginIdExtensionToName= plugin.getIdExtensionToName();
+ keySet= PluginIdExtensionToName.keySet();
+ for (Iterator iter= keySet.iterator(); iter.hasNext(); ) {
+ String key= (String) iter.next();
+ fIdExtensionToName.put(key, PluginIdExtensionToName.get(key));
+ }
+
+ IdMap idmap = new IdMap(false);
+ XMLCompareAddIdMapDialog dialog= new XMLCompareAddIdMapDialog(XMLPlugin.getActiveWorkbenchShell(),idmap,fIdMaps,fIdMapsInternal,fIdExtensionToName,false);
+ if (dialog.open() == Window.OK) {
+ if (!fIdMaps.containsKey(idmap.getName())) {
+ fIdMaps.put(idmap.getName(),new HashMap());
+ if (!idmap.getExtension().equals("")) //$NON-NLS-1$
+ fIdExtensionToName.put(idmap.getExtension(),idmap.getName());
+ XMLPlugin.getDefault().setIdMaps(fIdMaps,fIdExtensionToName,null,false);
+ }
+ }
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/GeneralMatching.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/GeneralMatching.java
new file mode 100644
index 000000000..e1faaed7b
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/GeneralMatching.java
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/** This class is used to find a mapping between the nodes of two xml parse trees
+ * When an identifier for a specific node is known, it will be used.
+ * Otherwise a min-cost bipartite matching must be solved.
+ * This algorithm uses the algorithm described in the paper
+ * "X-Diff: A Fast Change Detection Algorithm for XML Documents"
+ */
+public class GeneralMatching extends AbstractMatching {
+
+ HungarianMethod fH;
+
+ boolean fUseOrdered;
+ String[] fOrdered;
+ boolean fIgnoreStartsWith;
+
+ public GeneralMatching() {
+ fOrdered= null;
+ fUseOrdered= false;
+ fIgnoreStartsWith= false;
+ }
+
+ public GeneralMatching(ArrayList ordered) {
+ if (ordered != null && !ordered.isEmpty()) {
+ fUseOrdered= true;
+ fOrdered= new String[ordered.size()];
+ int i=0;
+ for (Iterator iter= ordered.iterator(); iter.hasNext(); i++) {
+ fOrdered[i]= (String) iter.next();
+ }
+ } else {
+ fUseOrdered= false;
+ fOrdered= null;
+ }
+ //fOrderedElements= XMLPlugin.getDefault().getOrderedElements();
+ }
+
+ //x and y have children xc_orig and yc_orig, respectively
+ protected int unorderedMatch(XMLNode x, XMLNode y, Object[] xc_orig, Object[] yc_orig) {
+ ArrayList DTMatching = new ArrayList();//Mathing Entry in fDT_Matchings
+ int distance = 0;//distance
+
+ Vector xc_vect = new Vector();
+ Vector yc_vect = new Vector();
+ for (int i=0; i<xc_orig.length; i++) {
+ if ( ((XMLNode)xc_orig[i]).usesIDMAP() ) {
+ int j;
+ for (j=0; j<yc_orig.length && !((XMLNode)yc_orig[j]).getOrigId().equals(((XMLNode)xc_orig[i]).getOrigId()); j++);
+ if ( j<yc_orig.length ) {
+ /* not calculating their distance and adding it to variable "distance" to save time,
+ * as matching of subtrees is not performed.
+ * but better result might be achieved if this were done.
+ */
+ //int d= dist( (XMLNode)xc_orig[i], (XMLNode)yc_orig[j] );
+ //distance += d;
+ //fDT[indexOfLN((XMLNode)xc_orig[i])][indexOfRN((XMLNode)yc_orig[j])]= d;
+ DTMatching.add(new Match( (XMLNode)xc_orig[i], (XMLNode)yc_orig[j] ));
+ }
+ } else
+ xc_vect.add(xc_orig[i]);
+ }
+ XMLNode[] xc= (XMLNode[]) xc_vect.toArray(new XMLNode[xc_vect.size()]);
+ for (int j=0; j<yc_orig.length; j++) {
+ if ( !((XMLNode)yc_orig[j]).usesIDMAP() )
+ yc_vect.add(yc_orig[j]);
+ }
+ XMLNode[] yc= (XMLNode[]) yc_vect.toArray(new XMLNode[yc_vect.size()]);
+ if ( xc.length == 0 || yc.length == 0) {
+ if (xc.length == 0) {
+ for (int j=0; j<yc.length; j++) {
+ distance += countNodes((XMLNode)yc[j]);
+ }
+ } else {//yc.length == 0
+ for (int i=0; i<xc.length; i++) {
+ distance += countNodes((XMLNode)xc[i]);
+ }
+ }
+ } else {
+ for (int i=0; i<xc.length; i++) {
+ for (int j=0; j<yc.length; j++) {
+ if (fDT[indexOfLN( xc[i] )][indexOfRN( yc[j] )] == NO_ENTRY)
+ dist(xc[i], yc[j]);
+ }
+ }
+
+ /* look for Wmin (p.11)
+ * xc and yc are the two partitions that have to be mapped.
+ * But, they may not have same number of nodes
+ * HungarianMethod.java solves weighted matching only on complete bipatite graphs
+ * We must add nodes and edges to make graph complete
+ */
+ final int array_size = (xc.length > yc.length)?xc.length:yc.length;
+ final int array_rowsize = array_size+1;
+ final int array_colsize = array_size+2;
+ int[][] A = new int[array_rowsize][array_colsize];
+ for (int j=0; j<array_colsize; j++) {
+ A[0][j] = 0;
+ }
+ /* now: A[0] = new int[] {0,0,0, ... ,0}. This first row is not used by HungarianMethod
+ * (Fortran77 counts Array index from 1)
+ */
+ for (int i=1; i<array_rowsize; i++) {
+ A[i][0] = 0;
+ for (int j=1; j<array_colsize-1; j++) {
+ A[i][j] = -1;
+ }
+ A[i][array_colsize-1] = 0;
+ }
+ /* now A = 0, 0, 0, ... 0,0
+ * 0,-1,-1, ... -1,0
+ * 0,-1,-1, ... -1,0
+ * ...
+ * 0,-1,-1, ... -1,0
+ */
+ for (int i_xc = 0; i_xc < xc.length; i_xc++) {
+ for (int i_yc = 0; i_yc < yc.length; i_yc++) {
+ A[i_xc+1][i_yc+1] = fDT[indexOfLN( xc[i_xc] )][indexOfRN( yc[i_yc] )];
+ }
+ }
+ int dummyCost=0;
+ /* cost of dummy nodes not associated with a node in Tree, but needed
+ * to have a complete bipartite graph
+ */
+
+ //set dummyCost to larger than any cost in A
+ if (xc.length > yc.length) {
+ for (int i=1; i<array_rowsize; i++) {
+ for (int j=1; j<=yc.length; j++)
+ if (A[i][j] > dummyCost) dummyCost = A[i][j];
+ }
+ } else if (xc.length < yc.length) {
+ for (int i=1; i<=xc.length; i++) {
+ for (int j=1; j<array_colsize-1; j++)
+ if (A[i][j] > dummyCost) dummyCost = A[i][j];
+ }
+ } else {//xc.length == yc.length
+ dummyCost = Integer.MAX_VALUE-1;
+ }
+ dummyCost += 1;
+
+ if (xc.length > yc.length) {
+ for (int i=1; i<array_rowsize; i++) {
+ for (int j=yc.length+1; j<array_colsize-1; j++) {
+ A[i][j] = dummyCost;
+ }
+ }
+ } else if (xc.length < yc.length) {
+ for (int j=1; j<array_colsize-1; j++) {
+ for (int i=xc.length+1; i<array_rowsize; i++) {
+ A[i][j] = dummyCost;
+ }
+ }
+ }
+
+ //A is built. Now perform matching
+ int[] Matching = new int[array_rowsize];
+ int[][] A2 = new int[array_rowsize][array_colsize];
+ for (int i=0; i<array_rowsize; i++) {
+ for (int j=0; j<array_colsize; j++)
+ A2[i][j] = A[i][j];
+ }
+ fH.solve( A2,Matching);
+ //now Matching contains the min-cost matching of A
+
+ for (int m=1; m<Matching.length; m++) {
+ if (A[Matching[m]][m] == dummyCost) {
+ if (xc.length > yc.length) {
+ distance += countNodes( xc[Matching[m]-1] );
+ //added here
+ DTMatching.add(new Match( (XMLNode)xc[Matching[m]-1] , null));
+ } else if (xc.length < yc.length) {
+ distance += countNodes( yc[m-1] );
+ //added here
+ DTMatching.add(new Match( null , yc[m-1]));
+ }
+ } else {
+ int index_x = indexOfLN( xc[Matching[m]-1] );
+ int index_y = indexOfRN( yc[m-1]);
+ distance += fDT[ index_x ][ index_y ];
+ if ( (xc[Matching[m]-1]).getSignature().equals( (yc[m-1]).getSignature() ))
+ DTMatching.add(new Match( xc[Matching[m]-1] , yc[m-1] ));
+ else {
+ DTMatching.add(new Match( xc[Matching[m]-1] , null));
+ DTMatching.add(new Match( null , yc[m-1] ));
+ }
+ }
+ }
+ }
+ fDT[indexOfLN(x)][indexOfRN(y)] = distance;
+ fDT_Matchings[indexOfLN(x)][indexOfRN(y)] = DTMatching;
+ return distance;
+ }
+
+
+ protected int orderedMath(XMLNode x, XMLNode y) {
+ //assumes x and y have children
+
+ boolean old_isw= fIgnoreStartsWith;
+ fIgnoreStartsWith= true;
+
+ //both x and y have children
+ Object[] xc = x.getChildren();
+ Object[] yc = y.getChildren();
+
+ ArrayList xc_elementsAL= new ArrayList();
+ ArrayList xc_attrsAL= new ArrayList();
+
+ ArrayList yc_elementsAL= new ArrayList();
+ ArrayList yc_attrsAL= new ArrayList();
+
+ //find attributes and elements and put them in xc_elementsAL and xc_attrsAL, respectively
+ for (int i= 0; i < xc.length; i++) {
+ XMLNode x_i= (XMLNode) xc[i];
+ if (x_i.getXMLType().equals(XMLStructureCreator.TYPE_ELEMENT)) {
+ xc_elementsAL.add(x_i);
+ } else if (x_i.getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE)) {
+ xc_attrsAL.add(x_i);
+ }
+ }
+
+ //do the same for yc
+ for (int i= 0; i < yc.length; i++) {
+ XMLNode y_i= (XMLNode) yc[i];
+ if (y_i.getXMLType().equals(XMLStructureCreator.TYPE_ELEMENT)) {
+ yc_elementsAL.add(y_i);
+ } else if (y_i.getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE)) {
+ yc_attrsAL.add(y_i);
+ }
+ }
+
+ Object[] xc_elements= xc_elementsAL.toArray();
+ Object[] yc_elements= yc_elementsAL.toArray();
+ Object[] xc_attrs= xc_attrsAL.toArray();
+ Object[] yc_attrs= yc_attrsAL.toArray();
+
+ ArrayList DTMatching= null;//Mathing to be added to Entry in fDT_Matchings
+ int distance = 0;//distance to be added to entry in fDT
+
+ //perform unordered matching on attributes
+ //this updates fDT and fDT_Matchings
+ if (xc_attrs.length > 0 || yc_attrs.length > 0) {
+ if (xc_attrs.length == 0)
+ distance += yc_attrs.length;
+ else if (yc_attrs.length == 0)
+ distance += xc_attrs.length;
+ else {
+ unorderedMatch(x, y, xc_attrs, yc_attrs);
+ distance += fDT[indexOfLN(x)][indexOfRN(y)];
+ DTMatching= fDT_Matchings[indexOfLN(x)][indexOfRN(y)];
+ }
+ }
+ if (DTMatching == null)
+ DTMatching= new ArrayList();
+ //perform ordered matching on element children, i.e. number them in order of appearance
+
+ /* start new */
+ distance= handleRangeDifferencer(xc_elements, yc_elements, DTMatching, distance);
+ /* end new */
+
+ /* start: Naive ordered compare /*
+// int minlength= (xc_elements.length > yc_elements.length)?yc_elements.length:xc_elements.length;
+// for (int i= 0; i < minlength; i++) {
+// distance += dist((XMLNode) xc_elements[i], (XMLNode) yc_elements[i]);
+// DTMatching.add(new Match( (XMLNode)xc_elements[i], (XMLNode)yc_elements[i]));
+// }
+// if (xc_elements.length > yc_elements.length) {
+// for (int i= minlength; i < xc_elements.length; i++) {
+// distance += countNodes((XMLNode) xc_elements[i]);
+// }
+// } else if (xc_elements.length < yc_elements.length) {
+// for (int i= minlength; i < yc_elements.length; i++) {
+// distance += countNodes((XMLNode) yc_elements[i]);
+// }
+// }
+ /* end: Naive ordered compare */
+
+ fIgnoreStartsWith= old_isw;
+
+ fDT[indexOfLN(x)][indexOfRN(y)] = distance;
+ fDT_Matchings[indexOfLN(x)][indexOfRN(y)] = DTMatching;
+ return distance;
+
+ }
+
+
+
+ /* matches two trees according to paper "X-Diff", p. 16 */
+ public void match(XMLNode LeftTree, XMLNode RightTree, boolean rightTreeIsAncestor, IProgressMonitor monitor) throws InterruptedException {
+
+ //if (monitor != null) monitor.beginTask("",10);
+ fH = new HungarianMethod();
+ fNLeft = new Vector();//numbering LeftTree: Mapping nodes in LeftTree to numbers to be used as array indexes
+ fNRight = new Vector();//numbering RightTree: Mapping nodes in RightTree to numbers to be used as array indexes
+ numberNodes(LeftTree, fNLeft);
+ numberNodes(RightTree, fNRight);
+ fDT = new int[fNLeft.size()][fNRight.size()];
+ fDT_Matchings = new ArrayList[fNLeft.size()][fNRight.size()];
+ for (int i=0; i<fDT.length; i++) {
+ fDT[i] = new int[fNRight.size()];
+ for (int j=0; j<fDT[0].length; j++) {
+ fDT[i][j] = NO_ENTRY;
+ }
+ }
+
+ ArrayList NLeft = new ArrayList();
+ ArrayList NRight = new ArrayList();
+ findLeaves(LeftTree, NLeft);
+ findLeaves(RightTree, NRight);
+
+ /* Matching Algorithm */
+ /* Step 1: Compute editing distance for (LeftTree -> RightTree)*/
+ while (!NLeft.isEmpty() || !NRight.isEmpty()) {
+ for (ListIterator itNLeft=NLeft.listIterator(); itNLeft.hasNext(); ) {
+ XMLNode x = (XMLNode) itNLeft.next();
+ for (ListIterator itNRight=NRight.listIterator(); itNRight.hasNext(); ) {
+ XMLNode y = (XMLNode) itNRight.next();
+ if ( x.getSignature().equals(y.getSignature()) ) {
+// System.out.println("x: "+x.getName());
+// System.out.println("y: "+y.getName());
+ if (monitor != null && monitor.isCanceled()) {
+// throw new OperationCanceledException();
+ throw new InterruptedException();
+// return;
+ }
+
+ //if signature starts with root>project
+ //do not calculate dist
+
+ //if signature is root>project
+ //do ordered search on children
+ //do unordered search on childrenb
+
+ dist(x,y);
+ }
+ }
+ }
+ ArrayList NLeft_new = new ArrayList();
+ ArrayList NRight_new = new ArrayList();
+ for (ListIterator itNLeft=NLeft.listIterator(); itNLeft.hasNext(); ) {
+ XMLNode node = (XMLNode) itNLeft.next();
+ if ( node.getParent() != null && !NLeft_new.contains(node.getParent()) )
+ NLeft_new.add(node.getParent());
+ }
+ for (ListIterator itNRight=NRight.listIterator(); itNRight.hasNext(); ) {
+ XMLNode node = (XMLNode) itNRight.next();
+ if ( node.getParent() != null && !NRight_new.contains(node.getParent()) )
+ NRight_new.add(node.getParent());
+ }
+ NLeft = NLeft_new;
+ NRight = NRight_new;
+ }
+ //end of Step1
+ /* Step 2: mark matchings on LeftTree and RightTree */
+ fMatches = new Vector();
+ if ( !LeftTree.getSignature().equals(RightTree.getSignature()) ) {
+ //matching is empty
+ } else {
+ fMatches.add(new Match(LeftTree,RightTree));
+ for (int i_M = 0; i_M<fMatches.size(); i_M++) {
+ Match m = (Match) fMatches.elementAt(i_M);
+ if ( !isLeaf(m.fx) && !isLeaf(m.fy) ) {
+// if (fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ] == null)
+// System.out.println("Error: ID not unique for " + m.fx.getId());
+// else
+// fMatches.addAll(fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ]);
+ if (fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ] != null)
+ fMatches.addAll(fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ]);
+ }
+ }
+ }
+ //end of Step2
+ /* Renumber Id of Nodes to follow Matches. Or for ancestor, copy over Id to ancestor */
+ if (rightTreeIsAncestor) {
+ for (ListIterator it_M = fMatches.listIterator(); it_M.hasNext(); ) {
+ Match m = (Match) it_M.next();
+ if (m.fx != null && m.fy != null)
+ m.fy.setId(m.fx.getId());
+ }
+ } else {
+ int newId = 0;
+ for (ListIterator it_M = fMatches.listIterator(); it_M.hasNext(); newId++) {
+ Match m = (Match) it_M.next();
+ if (m.fx != null)
+ m.fx.setId(Integer.toString(newId));
+ if (m.fy != null)
+ m.fy.setId(Integer.toString(newId));
+// System.out.println("Matching: "+ ((m.fx != null)?m.fx.getOrigId():"null")+" -> "+((m.fx != null)?m.fx.getId():"null")+" , "+((m.fy != null)?m.fy.getOrigId():"null")+" -> "+((m.fy != null)?m.fy.getId():"null")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ }
+ //if (monitor != null) monitor.done();
+ }
+
+ protected int handleXandYnotLeaves(XMLNode x, XMLNode y) {
+ int ret= NO_ENTRY;
+ Object[] xc_orig = x.getChildren();
+ Object[] yc_orig = y.getChildren();
+
+ /* handle ordered entries */
+ if (fUseOrdered) {
+ boolean starts_with_sig= false;
+ boolean equals_sig= false;
+ String x_sig= x.getSignature();
+ String y_sig= y.getSignature();
+
+ int i_ordered;
+
+ if (!fIgnoreStartsWith) {
+ /* Normal case when algorithm runs.
+ * Algorithm runs bottom up from leaves to root.
+ * check x_sig.startsWith(fOrdered[i_ordered]) || y_sig.startsWith(fOrdered[i_ordered])
+ * because if this is the case and
+ * !(x_sig.equals(fOrdered[j_ordered]+SIGN_ELEMENT) && y_sig.equals(fOrdered[j_ordered]+SIGN_ELEMENT))
+ * i.e. the nodes are not marked for an ordered compare but x and/or y has an ancestor that is,
+ * then nodes x and/or y will be handled by that ancestor in orderedMatch(), which is a top-down algorithm.
+ * Thus, we exit the procedure dist() if this is the case.
+ */
+ for (i_ordered= 0; i_ordered < fOrdered.length; i_ordered++) {
+ if (x_sig.startsWith(fOrdered[i_ordered]) || y_sig.startsWith(fOrdered[i_ordered])) {
+ starts_with_sig= true;
+ if (x_sig.equals(y_sig)) {
+ for (int j_ordered=i_ordered ; j_ordered<fOrdered.length; j_ordered++) {
+ if (x_sig.equals(fOrdered[j_ordered]+SIGN_ELEMENT)) {
+ equals_sig= true;
+ break;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (starts_with_sig) {
+ if (equals_sig) {
+ return orderedMath(x, y);
+ } else {
+ return ret;
+ }
+ }
+
+ } else {
+ /* when inside orderedMatch(x, y), algorithm runs recursively from a node to the leaves of the
+ * subtree rooted at this node.
+ * In this case we do not check x_sig.startsWith(fOrdered[i_ordered]) || y_sig.startsWith(fOrdered[i_ordered])
+ */
+ if (x_sig.equals(y_sig)) {
+ for (i_ordered= 0; i_ordered < fOrdered.length; i_ordered++) {
+ if (x_sig.equals(fOrdered[i_ordered]+SIGN_ELEMENT)) {
+ equals_sig= true;
+ break;
+ }
+ }
+ }
+
+ if (equals_sig) {
+ return orderedMath(x, y);
+ }
+ }
+
+ }
+ /* end of handle ordered entries */
+
+
+ return unorderedMatch(x, y, xc_orig, yc_orig);
+ }
+
+}
+
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/HungarianMethod.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/HungarianMethod.java
new file mode 100644
index 000000000..dbd2cc623
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/HungarianMethod.java
@@ -0,0 +1,479 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+/** This algorithm solves the assignment problem.
+ * It was translated from Fortran to Java.
+ * The original algorithm was taken from http://www.netlib.no/netlib/toms/548
+ */
+public class HungarianMethod {
+
+ public int solve(int[][] A, int[] C) {
+
+ final int N = A.length-1;
+ final int NP1 = A[0].length-1;
+ int[] CH = new int[A.length];
+ int[] LC = new int[A.length];
+ int[] LR = new int[A.length];
+ int[] LZ = new int[A.length];
+ int[] NZ = new int[A.length];
+ int[] RH = new int[A[0].length];
+ int[] SLC = new int[A.length];
+ int[] SLR = new int[A.length];
+ int[] U = new int[A[0].length];
+ int H, Q, R, S, T;
+ boolean while100goto120 = false;
+
+// SUBROUTINE ASSCT ( N, A, C, T ) 10
+// INTEGER A(130,131), C(130), CH(130), LC(130), LR(130),
+// * LZ(130), NZ(130), RH(131), SLC(130), SLR(130),
+// * U(131)
+// INTEGER H, Q, R, S, T
+// EQUIVALENCE (LZ,RH), (NZ,CH)
+// C
+// C THIS SUBROUTINE SOLVES THE SQUARE ASSIGNMENT PROBLEM
+// C THE MEANING OF THE INPUT PARAMETERS IS
+// C N = NUMBER OF ROWS AND COLUMNS OF THE COST MATRIX, WITH
+// C THE CURRENT DIMENSIONS THE MAXIMUM VALUE OF N IS 130
+// C A(I,J) = ELEMENT IN ROW I AND COLUMN J OF THE COST MATRIX
+// C ( AT THE END OF COMPUTATION THE ELEMENTS OF A ARE CHANGED)
+// C THE MEANING OF THE OUTPUT PARAMETERS IS
+// C C(J) = ROW ASSIGNED TO COLUMN J (J=1,N)
+// C T = COST OF THE OPTIMAL ASSIGNMENT
+// C ALL PARAMETERS ARE INTEGER
+// C THE MEANING OF THE LOCAL VARIABLES IS
+// C A(I,J) = ELEMENT OF THE COST MATRIX IF A(I,J) IS POSITIVE,
+// C COLUMN OF THE UNASSIGNED ZERO FOLLOWING IN ROW I
+// C (I=1,N) THE UNASSIGNED ZERO OF COLUMN J (J=1,N)
+// C IF A(I,J) IS NOT POSITIVE
+// C A(I,N+1) = COLUMN OF THE FIRST UNASSIGNED ZERO OF ROW I
+// C (I=1,N)
+// C CH(I) = COLUMN OF THE NEXT UNEXPLORED AND UNASSIGNED ZERO
+// C OF ROW I (I=1,N)
+// C LC(J) = LABEL OF COLUMN J (J=1,N)
+// C LR(I) = LABEL OF ROW I (I=1,N)
+// C LZ(I) = COLUMN OF THE LAST UNASSIGNED ZERO OF ROW I(I=1,N)
+// C NZ(I) = COLUMN OF THE NEXT UNASSIGNED ZERO OF ROW I(I=1,N)
+// C RH(I) = UNEXPLORED ROW FOLLOWING THE UNEXPLORED ROW I
+// C (I=1,N)
+// C RH(N+1) = FIRST UNEXPLORED ROW
+// C SLC(K) = K-TH ELEMENT CONTAINED IN THE SET OF THE LABELLED
+// C COLUMNS
+// C SLR(K) = K-TH ELEMENT CONTAINED IN THE SET OF THE LABELLED
+// C ROWS
+// C U(I) = UNASSIGNED ROW FOLLOWING THE UNASSIGNED ROW I
+// C (I=1,N)
+// C U(N+1) = FIRST UNASSIGNED ROW
+// C
+// C THE VECTORS C,CH,LC,LR,LZ,NZ,SLC,SLR MUST BE DIMENSIONED
+// C AT LEAST AT (N), THE VECTORS RH,U AT LEAST AT (N+1),
+// C THE MATRIX A AT LEAST AT (N,N+1)
+// C
+// C INITIALIZATION
+
+ int KSLC = -1;
+ int L = -1;
+ int I = -1;
+ int M = -1;
+ int J = -1;
+ int K = -1;
+ int LJ = -1;
+ int LM = -1;
+ int KSLR = -1;
+ int NL = -1;
+ int NM = -1;
+
+ //N = N-1;
+ //NP1 = NP1-1;
+ // NP1 = N+1
+
+ for (J=1; J<=N; J++) {
+ // DO 10 J=1,N
+ C[J] = 0;
+ LZ[J] = 0;
+ NZ[J] = 0;
+ U[J] = 0;
+ }//for (int J=0; J<N; J++)
+ //10 CONTINUE
+ U[NP1] = 0;
+ T = 0;
+ //C REDUCTION OF THE INITIAL COST MATRIX
+
+ for (J=1; J<=N; J++) {
+ // DO 40 J=1,N
+ S = A[1][J];
+ for (L=2; L<=N; L++) {
+ //DO 20 L=2,N
+ if (A[L][J] < S) S = A[L][J];
+ //IF ( A(L,J) .LT. S ) S = A(L,J)
+ }//for (int L=1; L<N; L++)
+ //20 CONTINUE
+ T = T+S;
+ for (I=1; I<=N; I++) {
+ //DO 30 I=1,N
+ A[I][J] = A[I][J]-S;
+ }//for (int I=0; I<N; I++)
+ //30 CONTINUE
+
+ }//for (int J=0; J<N; J++)
+ // 40 CONTINUE
+ for (I=1; I<=N; I++) {
+ //DO 70 I=1,N
+ Q = A[I][1];
+ for (L=2; L<=N; L++) {
+ //DO 50 L=2,N
+ //System.out.println("I="+I+" L="+L);
+ if (A[I][L] < Q) Q = A[I][L];
+ //IF ( A(I,L) .LT. Q ) Q = A(I,L)
+ }//for (int L=1; L<N; L++)
+ //50 CONTINUE
+ T = T+Q;
+ L = NP1;
+ for (J=1; J<=N; J++) {
+ //DO 60 J=1,N
+ A[I][J] = A[I][J]-Q;
+ if (A[I][J] != 0) continue;
+ //IF ( A[I,J] .NE. 0 ) GO TO 60
+ A[I][L] = -J;
+ L = J;
+ }//for (int J=0; J<N; J++)
+ //60 CONTINUE
+ }//for (int I=0; I<N; N++)
+ //70 CONTINUE
+ //C CHOICE OF THE INITIAL SOLUTION
+
+
+ K = NP1;
+ for140:
+ for (I=1; I<=N; I++) {
+ // DO 140 I=1,N
+ LJ = NP1;
+ J = -A[I][NP1];
+
+ do {
+ if (C[J] == 0) {
+ // 80 IF ( C(J) .EQ. 0 ) { GO TO 130
+
+ C[J] = I;
+ A[I][LJ] = A[I][J];
+ NZ[I] = -A[I][J];
+ LZ[I] = LJ;
+ A[I][J] = 0;
+ continue for140; //break??
+ }
+
+ LJ = J;
+ J = -A[I][J];
+
+ } while (J != 0);
+ // IF ( J .NE. 0 ) GO TO 80
+ LJ = NP1;
+ J = -A[I][NP1];
+
+ do90:
+ do {
+ R = C[J];
+ LM = LZ[R];
+ M = NZ[R];
+
+ while100goto120 = false;
+ while100:
+ while (true) {
+ if (M == 0) break while100;
+ // 100 IF ( M .EQ. 0 ) GO TO 110
+ if (C[M] == 0){
+ while100goto120 = true;
+ break do90;
+ }
+ // IF ( C(M) .EQ. 0 ) GO TO 120// M != 0 && C[m] == 0
+ LM = M;
+ M = -A[R][M];
+ }
+ // GO TO 100
+
+ //110
+ LJ = J;
+ J = -A[I][J];
+ } while (J != 0);
+ // IF ( J .NE. 0 ) GO TO 90
+
+ if ( !while100goto120 ) {
+ U[K] = I;
+ K = I;
+ continue for140;
+ // GO TO 140
+ }
+ // 120
+ while100goto120 = false;
+ NZ[R] = -A[R][M];
+ LZ[R] = J;
+ A[R][LM] = -J;
+ A[R][J] = A[R][M];
+ A[R][M] = 0;
+ C[M] = R;
+
+ //130
+ C[J] = I;
+ A[I][LJ] = A[I][J];
+ NZ[I] = -A[I][J];
+ LZ[I] = LJ;
+ A[I][J] = 0;
+
+
+ // 140 CONTINUE
+ }
+ //C RESEARCH OF A NEW ASSIGNMENT
+ while392:
+ while (true) {
+ if (U[NP1] == 0) return T;
+ // 150 IF ( U(NP1) .EQ. 0 ) RETURN
+
+ for (I=1; I<=N; I++) {
+ // DO 160 I=1,N
+ CH[I] = 0;
+ LC[I] = 0;
+ LR[I] = 0;
+ RH[I] = 0;
+ }
+ // 160 CONTINUE
+ RH[NP1] = -1;
+ KSLC = 0;
+ KSLR = 1;
+ R = U[NP1];
+ //System.out.println("R: "+R);
+ LR[R] = -1;
+ SLR[1] = R;
+
+ boolean goto190 = false;
+ while360:
+ while(true) {
+ do350:
+ do {
+ //System.out.println("R: "+R+" NP1: "+NP1);
+ if (goto190 || A[R][NP1] != 0) {
+ // IF ( A(R,NP1) .EQ. 0 ) GO TO 220
+
+
+ do200:
+ do {
+ if (!goto190) {
+ // 170
+ L = -A[R][NP1];
+
+ if (A[R][L] != 0) {
+ // IF ( A(R,L) .EQ. 0 ) GO TO 180
+ if (RH[R] == 0) {
+ // IF ( RH(R) .NE. 0 ) GO TO 180
+ RH[R] = RH[NP1];
+ CH[R] = -A[R][L];
+ RH[NP1] = R;
+ }
+ }
+ }// if (!goto190)
+ //boolean goto210 = false;
+ while190:
+ while (true) {
+ if (!goto190) {
+ if (LC[L] ==0) break while190;
+ //180 IF ( LC(L) .EQ. 0 ) GO TO 200
+
+ if (RH[R] == 0) {
+ break do200;
+ // goto210 = true;
+ //break;
+ }
+ // IF ( RH(R) .EQ. 0 ) GO TO 210
+ }// if (!goto190)
+ goto190 = false;
+ // 190
+ L = CH[R];
+ CH[R] = -A[R][L];
+ if (A[R][L] != 0) continue while190;
+ //IF ( A(R,L) .NE. 0 ) GO TO 180
+ RH[NP1] = RH[R];
+ RH[R] = 0;
+
+ //GO TO 180
+
+ }//end while190
+
+ //if (!goto210) {
+ //200
+ LC[L] = R;
+
+ if (C[L] == 0) break while360;
+ //IF ( C(L) .EQ. 0 ) GO TO 360
+
+ KSLC = KSLC+1;
+ SLC[KSLC] = L;
+ R = C[L];
+ LR[R] = L;
+ KSLR = KSLR+1;
+ SLR[KSLR] = R;
+ //}
+ } while (A[R][NP1] != 0); //do200
+ // IF ( A(R,NP1) .NE. 0 ) GO TO 170
+ //}// if (!goto210)
+ // goto210 = false;
+ // 210 CONTINUE
+
+ if (RH[NP1] > 0) break do350;
+ //IF ( RH(NP1) .GT. 0 ) GO TO 350
+
+ }// if (A[R,L] != 0)
+ //C REDUCTION OF THE CURRENT COST MATRIX
+ // 220
+ H = Integer.MAX_VALUE;
+
+ for240:
+ for (J=1; J<=N; J++) {
+ // DO 240 J=1,N
+
+ if (LC[J] != 0) continue for240;
+ // IF ( LC(J) .NE. 0 ) GO TO 240
+
+ for (K=1; K<=KSLR; K++) {
+ // DO 230 K=1,KSLR
+ I = SLR[K];
+ if (A[I][J] < H) H = A[I][J];
+ // IF ( A(I,J) .LT. H ) H = A(I,J)
+ }// for (int K=0; K<KSLR; K++)
+ // 230 CONTINUE
+
+ }// for (int J; J<N; J++)
+ // 240 CONTINUE
+
+ T = T+H;
+
+ for290:
+ for (J=1; J<=N; J++) {
+ // DO 290 J=1,N
+
+ if (LC[J] != 0 ) continue for290;
+ // IF ( LC(J) .NE. 0 ) GO TO 290
+
+ for280:
+ for (K=1; K<=KSLR; K++) {
+ // DO 280 K=1,KSLR
+ I = SLR[K];
+ A[I][J] = A[I][J]-H;
+ if (A[I][J] != 0) continue for280;
+ // IF ( A(I,J) .NE. 0 ) GO TO 280
+
+ if (RH[I] == 0) {
+ // IF ( RH(I) .NE. 0 ) GO TO 250
+ RH[I] = RH[NP1];
+ CH[I] = J;
+ RH[NP1] = I;
+ }// if (RH[I] == 0)
+ //250
+ L = NP1;
+ //260
+ while (true) {
+ NL = -A[I][L];
+ if (NL == 0) break;
+ // IF ( NL .EQ. 0 ) GO TO 270
+ L = NL;
+ }// while (true)
+ // GO TO 260
+ //270
+ A[I][L] = -J;
+
+ }// for (int K=0; K<KSLR; K++)
+ // 280 CONTINUE
+
+ }// for (int J=0; J<N; J++)
+ // 290 CONTINUE
+
+ if (KSLC != 0) {
+ //IF ( KSLC .EQ. 0 ) GO TO 350
+
+ for340:
+ for (I=1; I<=N; I++) {
+ // DO 340 I=1,N
+
+ if (LR[I] != 0) continue for340;
+ //IF ( LR(I) .NE. 0 ) GO TO 340
+
+ for330:
+ for (K=1; K<=KSLC; K++) {
+ //DO 330 K=1,KSLC
+ J = SLC[K];
+
+ boolean enter_if = false;
+ if (A[I][J] <= 0) {
+ //IF ( A(I,J) .GT. 0 ) GO TO 320
+ L = NP1;
+ //300
+ while (true) {
+ NL = - A[I][L];
+ if (NL == J) break;
+ //IF ( NL .EQ. J ) GO TO 310
+ L = NL;
+ }//while (true)
+ //GO TO 300
+ //310
+ A[I][L] = A[I][J];
+ A[I][J] = H;
+ //GO TO 330
+ enter_if = true;
+ }//if (A[I,J] <=0)
+ if (!enter_if) {
+ //320
+ A[I][J] = A[I][J]+H;
+ }
+ }//for (int K=0; K<KSLC; K++)
+ // 330 CONTINUE
+ }//for (int I=0; I<N; I++)
+ // 340 CONTINUE
+ }// if (KSLC != 0)
+
+ } while (false);//do350
+ //350
+ R = RH[NP1];
+ //System.out.println("R: "+R+" at 350");
+ goto190 = true;
+ }//while360
+ // GO TO 190
+ //C ASSIGNMENT OF A NEW ROW
+ while389:
+ while (true) {
+ //360
+ C[L] = R;
+ M = NP1;
+ //370
+ while (true) {
+ NM = -A[R][M];
+ if (NM == L) break;
+ // IF ( NM .EQ. L ) GO TO 380
+ M = NM;
+ }//while (true)
+ // GO TO 370
+ //380
+ A[R][M] = A[R][L];
+ A[R][L] = 0;
+ if (LR[R] < 0) break while389;
+ // IF ( LR(R) .LT. 0 ) GO TO 390
+ L = LR[R];
+ A[R][L] = A[R][NP1];
+ A[R][NP1] = -L;
+ R = LC[L];
+ }//while389
+ // GO TO 360
+ //390
+ U[NP1] = U[R];
+ U[R] = 0;
+ }
+ // GO TO 150
+ //END
+ }
+
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/IdMap.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/IdMap.java
new file mode 100644
index 000000000..62bb23c62
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/IdMap.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+/** This class is used to represent a id mapping scheme in the XML Compare preference page
+ */
+public class IdMap {
+
+ private String fName;
+ private boolean fInternal;
+ private Vector fMappings;
+ private String fExtension;
+ private ArrayList fOrdered;//contains Mapping elements for list of ordered entries (the children of these elements will be compared in ordered fashion)
+
+ /**
+ * Creates an IdMap which represents an Id Mapping Scheme
+ * @param internal true if the IdMap is internal
+ */
+ public IdMap(boolean internal) {
+ this("", internal); //$NON-NLS-1$
+ }
+
+ /**
+ * Creates an IdMap which represents an Id Mapping Scheme
+ * @param name The name of the mapping, as in fIdMaps/fIdMapsInternal HashMaps and fOrderedElements/fOrderedElementsInternal HashMaps
+ * @param internal true if the IdMap is internal
+ */
+ public IdMap(String name, boolean internal) {
+ this(name, internal, new Vector());
+ }
+
+ /**
+ * Creates an IdMap which represents an Id Mapping Scheme
+ * @param name The name of the mapping, as in fIdMaps/fIdMapsInternal HashMaps and fOrderedElements/fOrderedElementsInternal HashMaps
+ * @param internal true if the IdMap is internal
+ * @param mappings Vector of Mapping elements which represent the id mappings of this id mapping scheme
+ */
+ public IdMap(String name, boolean internal, Vector mappings) {
+ this(name, internal, mappings, ""); //$NON-NLS-1$
+ }
+
+ /**
+ * Creates an IdMap which represents an Id Mapping Scheme.
+ * @param name The name of the mapping, as in fIdMaps/fIdMapsInternal HashMaps and fOrderedElements/fOrderedElementsInternal HashMaps.
+ * @param internal true if the IdMap is internal.
+ * @param mappings Vector of Mapping elements which represent the id mappings of this id mapping scheme.
+ * @param extension Optional extension to be associated with this id mapping scheme.
+ */
+ public IdMap(String name, boolean internal, Vector mappings, String extension) {
+ this(name, internal, mappings, extension, null);
+ }
+
+ /**
+ * Creates an IdMap which represents an Id Mapping Scheme.
+ * @param name The name of the mapping, as in fIdMaps/fIdMapsInternal HashMaps and fOrderedElements/fOrderedElementsInternal HashMaps.
+ * @param internal true if the IdMap is internal.
+ * @param mappings Vector of Mapping elements which represent the id mappings of this id mapping scheme.
+ * @param extension Optional extension to be associated with this id mapping scheme.
+ * @param ordered Optional ArrayList of Mapping elements representing ordered entries.
+ */
+ public IdMap(String name, boolean internal, Vector mappings, String extension, ArrayList ordered) {
+ fName = name;
+ fInternal = internal;
+ fMappings = mappings;
+ fExtension= extension.toLowerCase();
+ fOrdered= ordered;
+ }
+
+ /*
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object object) {
+ if (!(object instanceof IdMap))
+ return false;
+
+ IdMap idmap= (IdMap) object;
+
+ if (idmap == this)
+ return true;
+
+ return
+ idmap.getName().equals(fName) &&
+ idmap.getMappings().equals(fMappings);
+ }
+
+ /*
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return fName.hashCode() ^ fMappings.hashCode();
+ }
+
+ public void setName(String name) {
+ fName = name;
+ }
+
+ public String getName() {
+ return fName;
+ }
+
+ public void setMappings(Vector mappings) {
+ fMappings = mappings;
+ }
+
+ public Vector getMappings() {
+ return fMappings;
+ }
+
+ public void setInternal(boolean bool) {
+ fInternal = bool;
+ }
+
+ public boolean isInternal() {
+ return fInternal;
+ }
+
+ public void setExtension(String extension) {
+ fExtension= extension;
+ }
+
+ public String getExtension() {
+ return fExtension;
+ }
+ public void setOrdered(ArrayList ordered) {
+ fOrdered= ordered;
+ }
+ public ArrayList getOrdered() {
+ return fOrdered;
+ }
+
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/Mapping.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/Mapping.java
new file mode 100644
index 000000000..e8197ab0e
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/Mapping.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+/** This class is used to represent a particular id mapping or ordered entry in the XML Compare preference page
+ */
+public class Mapping {
+
+ private String fElement;
+ private String fSignature;
+ private String fIdAttribute;
+
+ public Mapping() {
+ this("", "", ""); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ }
+
+ public Mapping(String element, String signature) {
+ this(element, signature, ""); //$NON-NLS-1$
+ }
+
+ public Mapping(String element, String signature, String idattribute) {
+ fElement = element;
+ fSignature = signature;
+ fIdAttribute = idattribute;
+ }
+
+ /*
+ * @see Object#equals(Object)
+ */
+ public boolean equals(Object object) {
+ if (!(object instanceof Mapping))
+ return false;
+
+ Mapping mapping= (Mapping) object;
+
+ if (mapping == this)
+ return true;
+
+ return
+ mapping.fElement.equals(fElement) &&
+ mapping.fSignature.equals(fSignature) &&
+ mapping.fIdAttribute.equals(fIdAttribute);
+ }
+
+ /*
+ * @see Object#hashCode()
+ */
+ public int hashCode() {
+ return fElement.hashCode() ^ fSignature.hashCode();
+ }
+
+ public void setElement(String element) {
+ fElement = element;
+ }
+ public String getElement() {
+ return fElement;
+ }
+
+ public void setSignature(String signature) {
+ fSignature = signature;
+ }
+ public String getSignature() {
+ return fSignature;
+ }
+
+ public void setIdAttribute(String idattribute) {
+ fIdAttribute = idattribute;
+ }
+ public String getIdAttribute() {
+ return fIdAttribute;
+ }
+
+ public String getKey() {
+ return getKey(fSignature, fElement);
+ }
+
+ public static String getKey(String signature, String element) {
+ if (signature == "") //$NON-NLS-1$
+ return XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + element + XMLStructureCreator.SIGN_SEPARATOR;
+ else
+ return XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + signature + XMLStructureCreator.SIGN_SEPARATOR + element + XMLStructureCreator.SIGN_SEPARATOR;
+
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/OrderedMatching.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/OrderedMatching.java
new file mode 100644
index 000000000..8648a0d92
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/OrderedMatching.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.Vector;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+
+public class OrderedMatching extends AbstractMatching {
+
+ public OrderedMatching() {
+ super();
+ }
+
+ protected int orderedMath(XMLNode x, XMLNode y) {
+ //assumes x and y have children
+
+// boolean old_isw= fIgnoreStartsWith;
+// fIgnoreStartsWith= true;
+
+ //both x and y have children
+ Object[] xc = x.getChildren();
+ Object[] yc = y.getChildren();
+
+ ArrayList xc_elementsAL= new ArrayList();
+ ArrayList xc_attrsAL= new ArrayList();
+
+ ArrayList yc_elementsAL= new ArrayList();
+ ArrayList yc_attrsAL= new ArrayList();
+
+ //find attributes and elements and put them in xc_elementsAL and xc_attrsAL, respectively
+ for (int i= 0; i < xc.length; i++) {
+ XMLNode x_i= (XMLNode) xc[i];
+ if (x_i.getXMLType().equals(XMLStructureCreator.TYPE_ELEMENT)) {
+ xc_elementsAL.add(x_i);
+ } else if (x_i.getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE)) {
+ xc_attrsAL.add(x_i);
+ }
+ }
+
+ //do the same for yc
+ for (int i= 0; i < yc.length; i++) {
+ XMLNode y_i= (XMLNode) yc[i];
+ if (y_i.getXMLType().equals(XMLStructureCreator.TYPE_ELEMENT)) {
+ yc_elementsAL.add(y_i);
+ } else if (y_i.getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE)) {
+ yc_attrsAL.add(y_i);
+ }
+ }
+
+ Object[] xc_elements= xc_elementsAL.toArray();
+ Object[] yc_elements= yc_elementsAL.toArray();
+
+ ArrayList DTMatching= new ArrayList();//Mathing to be added to Entry in fDT_Matchings
+ int distance = 0;//distance to be added to entry in fDT
+
+ //perform unordered matching on attributes
+ //this updates fDT and fDT_Matchings
+ if (xc_attrsAL.size() > 0 || yc_attrsAL.size()> 0) {
+ if (xc_attrsAL.size() == 0)
+ distance += yc_attrsAL.size();
+ else if (yc_attrsAL.size() == 0)
+ distance += xc_attrsAL.size();
+ else {
+ //unorderedMatch(x, y, xc_attrs, yc_attrs);
+// distance += fDT[indexOfLN(x)][indexOfRN(y)];
+// DTMatching= fDT_Matchings[indexOfLN(x)][indexOfRN(y)];
+ distance= handleAttributes(xc_attrsAL, yc_attrsAL, DTMatching);
+ }
+ }
+
+ //perform ordered matching on element children, i.e. number them in order of appearance
+
+ /* start new */
+ distance= handleRangeDifferencer(xc_elements, yc_elements, DTMatching, distance);
+ /* end new */
+
+ /* start: Naive ordered compare /*
+// int minlength= (xc_elements.length > yc_elements.length)?yc_elements.length:xc_elements.length;
+// for (int i= 0; i < minlength; i++) {
+// distance += dist((XMLNode) xc_elements[i], (XMLNode) yc_elements[i]);
+// DTMatching.add(new Match( (XMLNode)xc_elements[i], (XMLNode)yc_elements[i]));
+// }
+// if (xc_elements.length > yc_elements.length) {
+// for (int i= minlength; i < xc_elements.length; i++) {
+// distance += countNodes((XMLNode) xc_elements[i]);
+// }
+// } else if (xc_elements.length < yc_elements.length) {
+// for (int i= minlength; i < yc_elements.length; i++) {
+// distance += countNodes((XMLNode) yc_elements[i]);
+// }
+// }
+ /* end: Naive ordered compare */
+
+// fIgnoreStartsWith= old_isw;
+
+ fDT[indexOfLN(x)][indexOfRN(y)] = distance;
+ fDT_Matchings[indexOfLN(x)][indexOfRN(y)] = DTMatching;
+ return distance;
+
+ }
+
+
+ /* matches two trees according to paper "X-Diff", p. 16 */
+ public void match(XMLNode LeftTree, XMLNode RightTree, boolean rightTreeIsAncestor, IProgressMonitor monitor) throws InterruptedException {
+
+ fNLeft = new Vector();//numbering LeftTree: Mapping nodes in LeftTree to numbers to be used as array indexes
+ fNRight = new Vector();//numbering RightTree: Mapping nodes in RightTree to numbers to be used as array indexes
+ numberNodes(LeftTree, fNLeft);
+ numberNodes(RightTree, fNRight);
+ fDT = new int[fNLeft.size()][fNRight.size()];
+ fDT_Matchings = new ArrayList[fNLeft.size()][fNRight.size()];
+ for (int i=0; i<fDT.length; i++) {
+ fDT[i] = new int[fNRight.size()];
+ for (int j=0; j<fDT[0].length; j++) {
+ fDT[i][j] = NO_ENTRY;
+ }
+ }
+
+ dist(LeftTree,RightTree);
+// /* mark matchings on LeftTree and RightTree */
+ fMatches = new Vector();
+ if ( !LeftTree.getSignature().equals(RightTree.getSignature()) ) {
+ //matching is empty
+ } else {
+ fMatches.add(new Match(LeftTree,RightTree));
+ for (int i_M = 0; i_M<fMatches.size(); i_M++) {
+ Match m = (Match) fMatches.elementAt(i_M);
+ if ( !isLeaf(m.fx) && !isLeaf(m.fy) ) {
+// if (fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ] == null)
+// System.out.println("Error: ID not unique for " + m.fx.getId());
+// else
+// fMatches.addAll(fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ]);
+ if (fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ] != null)
+ fMatches.addAll(fDT_Matchings[ indexOfLN(m.fx) ][ indexOfRN(m.fy) ]);
+ }
+ }
+ }
+ //end of Step2
+ /* Renumber Id of Nodes to follow Matches. Or for ancestor, copy over Id to ancestor */
+ if (rightTreeIsAncestor) {
+ for (ListIterator it_M = fMatches.listIterator(); it_M.hasNext(); ) {
+ Match m = (Match) it_M.next();
+ if (m.fx != null && m.fy != null)
+ m.fy.setId(m.fx.getId());
+ }
+ } else {
+ int newId = 0;
+ for (ListIterator it_M = fMatches.listIterator(); it_M.hasNext(); newId++) {
+ Match m = (Match) it_M.next();
+ if (m.fx != null)
+ m.fx.setId(Integer.toString(newId));
+ if (m.fy != null)
+ m.fy.setId(Integer.toString(newId));
+// System.out.println("Matching: "+ ((m.fx != null)?m.fx.getOrigId():"null")+" -> "+((m.fx != null)?m.fx.getId():"null")+" , "+((m.fy != null)?m.fy.getOrigId():"null")+" -> "+((m.fy != null)?m.fy.getId():"null")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+ }
+ //if (monitor != null) monitor.done();
+ }
+
+ public int handleAttributes(ArrayList xc_attrs, ArrayList yc_attrs, ArrayList DTMatching) {
+ int distance= 0;
+ x_for:
+ for (Iterator iter_xc= xc_attrs.iterator(); iter_xc.hasNext(); ) {
+ XMLNode x_attr= (XMLNode) iter_xc.next();
+ String x_attr_name= x_attr.getName();
+ for (Iterator iter_yc= yc_attrs.iterator(); iter_yc.hasNext(); ) {
+ XMLNode y_attr= (XMLNode) iter_yc.next();
+ if (y_attr.getName().equals(x_attr_name)) {
+ if (!y_attr.getValue().equals(x_attr.getValue()))
+ distance += 1;
+ DTMatching.add( new Match( x_attr, y_attr ) );
+ yc_attrs.remove(y_attr);
+ continue x_for;
+ }
+ }
+ DTMatching.add( new Match( x_attr, null) );
+ distance += 1;
+ }
+
+ for (Iterator iter_yc= yc_attrs.iterator(); iter_yc.hasNext(); ) {
+ DTMatching.add( new Match( null, (XMLNode) iter_yc.next()) );
+ distance += 1;
+ }
+
+ return distance;
+ }
+
+ protected int handleXandYnotLeaves(XMLNode x, XMLNode y) {
+ /* handle entries as ordered*/
+ return orderedMath(x, y);
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SWTUtil.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SWTUtil.java
new file mode 100644
index 000000000..f65bd5155
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SWTUtil.java
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DragSource;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Caret;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ScrollBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Widget;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.util.Assert;
+
+/**
+ * Utility class to simplify access to some SWT resources.
+ */
+public class SWTUtil {
+
+ /**
+ * Returns the standard display to be used. The method first checks, if
+ * the thread calling this method has an associated disaply. If so, this
+ * display is returned. Otherwise the method returns the default display.
+ */
+ public static Display getStandardDisplay() {
+ Display display;
+ display= Display.getCurrent();
+ if (display == null)
+ display= Display.getDefault();
+ return display;
+ }
+
+ /**
+ * Returns the shell for the given widget. If the widget doesn't represent
+ * a SWT object that manage a shell, <code>null</code> is returned.
+ *
+ * @return the shell for the given widget
+ */
+ public static Shell getShell(Widget widget) {
+ if (widget instanceof Control)
+ return ((Control)widget).getShell();
+ if (widget instanceof Caret)
+ return ((Caret)widget).getParent().getShell();
+ if (widget instanceof DragSource)
+ return ((DragSource)widget).getControl().getShell();
+ if (widget instanceof DropTarget)
+ return ((DropTarget)widget).getControl().getShell();
+ if (widget instanceof Menu)
+ return ((Menu)widget).getParent().getShell();
+ if (widget instanceof ScrollBar)
+ return ((ScrollBar)widget).getParent().getShell();
+
+ return null;
+ }
+
+
+ private static double getVerticalDialogUnitSize(Control control) {
+ GC gc= new GC(control);
+ try {
+ int height = gc.getFontMetrics().getHeight();
+ return height * 0.125;
+ } finally {
+ gc.dispose();
+ }
+ }
+
+ private static double getHorizontalDialogUnitSize(Control control) {
+ GC gc= new GC(control);
+ try {
+ int averageWidth= gc.getFontMetrics().getAverageCharWidth();
+ return averageWidth * 0.25;
+ } finally {
+ gc.dispose();
+ }
+ }
+
+
+ /**
+ * @see DialogPage#convertHeightInCharsToPixels
+ */
+ public static int convertHeightInCharsToPixels(int chars, Control control) {
+ return convertVerticalDLUsToPixels(chars * 8, control);
+ }
+
+ /**
+ * @see DialogPage#convertHorizontalDLUsToPixels
+ */
+ public static int convertHorizontalDLUsToPixels(int dlus, Control control) {
+ return (int)Math.round(dlus * getHorizontalDialogUnitSize(control));
+ }
+
+ /**
+ * @see DialogPage#convertVerticalDLUsToPixels
+ */
+ public static int convertVerticalDLUsToPixels(int dlus, Control control) {
+ return (int)Math.round(dlus * getVerticalDialogUnitSize(control));
+ }
+
+ /**
+ * @see DialogPage#convertWidthInCharsToPixels
+ */
+ public static int convertWidthInCharsToPixels(int chars, Control control) {
+ return convertHorizontalDLUsToPixels(chars * 4, control);
+ }
+
+ /**
+ * Returns a width hint for a button control.
+ */
+ public static int getButtonWidthHint(Button button) {
+ int widthHint= convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH, button);
+ return Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ }
+
+ /**
+ * Returns a height hint for a button control.
+ */
+ public static int getButtonHeigthHint(Button button) {
+ return convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT, button);
+ }
+
+ /**
+ * Sets width and height hint for the button control.
+ * <b>Note:</b> This is a NOP if the button's layout data is not
+ * an instance of <code>GridData</code>.
+ *
+ * @param the button for which to set the dimension hint
+ */
+ public static void setButtonDimensionHint(Button button) {
+ Assert.isNotNull(button);
+ Object gd= button.getLayoutData();
+ if (gd instanceof GridData) {
+ ((GridData)gd).heightHint= getButtonHeigthHint(button);
+ ((GridData)gd).widthHint= getButtonWidthHint(button);
+ }
+ }
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SelectMatcherAction.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SelectMatcherAction.java
new file mode 100644
index 000000000..03d122efb
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/SelectMatcherAction.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import org.eclipse.jface.action.Action;
+
+class SelectMatcherAction extends Action {
+
+ private XMLStructureViewer fViewer;
+ private String fDesc;
+
+ /**
+ * Create a new instance of this class
+ */
+ public SelectMatcherAction(String desc, XMLStructureViewer viewer) {
+ fViewer = viewer;
+ fDesc = desc;
+ setText(fDesc);
+ setToolTipText(fDesc);
+ }
+
+ public void run() {
+ ((XMLStructureCreator)fViewer.getStructureCreator()).setIdMap(fDesc);
+ fViewer.contentChanged();
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLChildren.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLChildren.java
new file mode 100644
index 000000000..172dab08a
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLChildren.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.HashMap;
+
+import org.eclipse.jface.text.IDocument;
+
+/** XMLNode that has children elements */
+public class XMLChildren extends XMLNode {
+
+ public int children;//counts the number of children
+ public HashMap childElements;//Maps the name of XML child elements to their # of occurence
+
+ public XMLChildren(String XMLType, String id, String value, String signature, IDocument doc, int start, int length) {
+ super(XMLType,id,value,signature,doc,start,length);
+ children=0;
+ childElements = new HashMap();
+ }
+
+}
+
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareAddIdMapDialog.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareAddIdMapDialog.java
new file mode 100644
index 000000000..85f899d37
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareAddIdMapDialog.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.text.MessageFormat;
+import java.util.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+
+import org.eclipse.compare.examples.xml.ui.StatusDialog;
+import org.eclipse.compare.examples.xml.ui.StatusInfo;
+
+/**
+ * This class is used to add or edit an ID Mapping Scheme
+ */
+public class XMLCompareAddIdMapDialog extends StatusDialog {
+
+ private IdMap fIdMap;
+ private HashMap fIdMaps;
+ private HashMap fIdMapsInternal;
+ private HashMap fIdExtensionToName;
+ private boolean fEdit;
+
+ private Text fIdMapText;
+ private Text fIdMapExtText;
+
+ public XMLCompareAddIdMapDialog(Shell parent, IdMap idmap, HashMap idmaps, HashMap idmapsInternal, HashMap idextensiontoname, boolean edit) {
+ super(parent);
+
+ fEdit = edit;
+ if (fEdit)
+ setTitle(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.editTitle")); //$NON-NLS-1$
+ else
+ setTitle(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.newTitle")); //$NON-NLS-1$
+
+ fIdMap = idmap;
+ fIdMaps = idmaps;
+ fIdMapsInternal= idmapsInternal;
+ fIdExtensionToName= idextensiontoname;
+ }
+/**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite ancestor) {
+ Composite composite= (Composite) super.createDialogArea(ancestor);
+
+ Composite inner= new Composite(composite, SWT.NONE);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ inner.setLayout(layout);
+ inner.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Label label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.label")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fIdMapText= new Text(inner, SWT.BORDER);
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ data.widthHint = convertWidthInCharsToPixels(30);
+ fIdMapText.setLayoutData(data);
+ fIdMapText.setText(fIdMap.getName());
+ fIdMapText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+ label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.extlabel")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fIdMapExtText= new Text(inner, SWT.BORDER);
+ data = new GridData(GridData.FILL_HORIZONTAL);
+ data.widthHint = convertWidthInCharsToPixels(30);
+ fIdMapExtText.setLayoutData(data);
+ fIdMapExtText.setText(fIdMap.getExtension());
+ fIdMapExtText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+
+ fIdMapText.setFocus();
+
+ return composite;
+ }
+
+/**
+ * Validate user input
+ */
+ private void doValidation() {
+ StatusInfo status= new StatusInfo();
+ String newText= fIdMapText.getText();
+ if (newText.length() == 0)
+ status.setError(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.error.noname")); //$NON-NLS-1$
+ else if (XMLComparePreferencePage.containsInvalidCharacters(newText))
+ status.setError(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.error.invalidname")); //$NON-NLS-1$
+ else if ( (!fEdit && (fIdMaps.containsKey(newText) || fIdMapsInternal.containsKey(newText)) )
+ || (fEdit && !newText.equals(fIdMap.getName()) && (fIdMaps.containsKey(newText) || fIdMapsInternal.containsKey(newText)) )
+ )
+ status.setError(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.error.idmapExists")); //$NON-NLS-1$
+ newText= fIdMapExtText.getText().toLowerCase();
+ if (newText.length() > 0) {
+ if (newText.indexOf(".") > -1) //$NON-NLS-1$
+ status.setError(XMLCompareMessages.getString("XMLCompareAddIdMapDialog.error.extfullstop")); //$NON-NLS-1$
+ else if (fIdExtensionToName.containsKey(newText) && !fIdExtensionToName.get(newText).equals(fIdMap.getName()))
+ status.setError(MessageFormat.format("{0} {1}",new String[] {XMLCompareMessages.getString("XMLCompareAddIdMapDialog.error.extExists"),(String)fIdExtensionToName.get(newText)})); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ updateStatus(status);
+ }
+/**
+ * Notifies that the ok button of this dialog has been pressed.
+ */
+ protected void okPressed() {
+ fIdMap.setName(fIdMapText.getText());
+ fIdMap.setExtension(fIdMapExtText.getText().toLowerCase());
+ super.okPressed();
+ }
+
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditCopyIdMapDialog.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditCopyIdMapDialog.java
new file mode 100644
index 000000000..3131061d0
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditCopyIdMapDialog.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.HashMap;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+
+import org.eclipse.compare.examples.xml.ui.StatusDialog;
+import org.eclipse.compare.examples.xml.ui.StatusInfo;
+
+/**
+ * This class is used to create an editable ID Mapping Scheme from an internal ID Mappping Scheme
+ */
+public class XMLCompareEditCopyIdMapDialog extends StatusDialog {
+
+ private HashMap fIdMaps;
+ private HashMap fIdMapsInternal;
+
+ private Text fIdMapText;
+ private String fResult;
+
+/**
+ * Constructs a new edit copy mapping dialog.
+ */
+ public XMLCompareEditCopyIdMapDialog(Shell parent, IdMap idmap, HashMap idmaps, HashMap idmapsInternal) {
+ super(parent);
+
+ setTitle(XMLCompareMessages.getString("XMLCompareEditCopyIdMapDialog.title")); //$NON-NLS-1$
+
+ fIdMaps = idmaps;
+ fIdMapsInternal= idmapsInternal;
+ }
+
+ public String getResult() {
+ return fResult;
+ }
+/**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite ancestor) {
+ Composite composite= (Composite) super.createDialogArea(ancestor);
+
+ Label comment= new Label(composite, SWT.NONE);
+ comment.setText(XMLCompareMessages.getString("XMLCompareEditCopyIdMapDialog.comment")); //$NON-NLS-1$
+ GridData data= new GridData();
+ data.horizontalAlignment= GridData.FILL;
+ data.verticalAlignment= GridData.BEGINNING;
+ comment.setLayoutData(data);
+
+ Composite inner= new Composite(composite, SWT.NONE);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ inner.setLayout(layout);
+ inner.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ Label label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareEditCopyIdMapDialog.label")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fIdMapText= new Text(inner, SWT.BORDER);
+ fIdMapText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fIdMapText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+ fIdMapText.setFocus();
+
+ return composite;
+ }
+
+/**
+ * Validate user input
+ */
+ private void doValidation() {
+ StatusInfo status= new StatusInfo();
+ String newText= fIdMapText.getText();
+ if (newText.length() == 0)
+ status.setError(XMLCompareMessages.getString("XMLCompareEditCopyIdMapDialog.error.noname")); //$NON-NLS-1$
+ else if (XMLComparePreferencePage.containsInvalidCharacters(newText))
+ status.setError(XMLCompareMessages.getString("XMLCompareEditCopyIdMapDialog.error.invalidname")); //$NON-NLS-1$
+ else if (fIdMaps.containsKey(newText) || fIdMapsInternal.containsKey(newText))
+ status.setError(XMLCompareMessages.getString("XMLCompareEditCopyIdMapDialog.error.nameExists")); //$NON-NLS-1$
+ updateStatus(status);
+ }
+/**
+ * Notifies that the ok button of this dialog has been pressed.
+ */
+ protected void okPressed() {
+ fResult = fIdMapText.getText();
+ super.okPressed();
+ }
+
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditMappingDialog.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditMappingDialog.java
new file mode 100644
index 000000000..51147358c
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditMappingDialog.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.HashMap;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.*;
+
+import org.eclipse.compare.examples.xml.ui.StatusDialog;
+import org.eclipse.compare.examples.xml.ui.StatusInfo;
+
+/**
+ * This class is used to add or edit a particular ID Mapping
+ */
+public class XMLCompareEditMappingDialog extends StatusDialog {
+
+ private Mapping fMapping;
+ private HashMap fIdmapHM;
+ private boolean fEdit;
+
+ private Text fElementText;
+ private Text fSignatureText;
+ private Text fIdAttributeText;
+
+ private Button fIdTypeAttributeButton;
+ private Button fIdTypeChildBodyButton;
+
+ /**
+ * Constructs a new edit mapping dialog.
+ */
+ public XMLCompareEditMappingDialog(Shell parent, Mapping mapping, HashMap idmapHM, boolean edit) {
+ super(parent);
+
+ int shellStyle= getShellStyle();
+ setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
+
+
+ fEdit = edit;
+ if (fEdit)
+ setTitle(XMLCompareMessages.getString("XMLCompareEditMappingDialog.editTitle")); //$NON-NLS-1$
+ else
+ setTitle(XMLCompareMessages.getString("XMLCompareEditMappingDialog.newTitle")); //$NON-NLS-1$
+
+ fMapping= mapping;
+ fIdmapHM = idmapHM;
+ }
+/**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite ancestor) {
+ Composite composite= (Composite) super.createDialogArea(ancestor);
+
+ Composite inner= new Composite(composite, SWT.NONE);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ inner.setLayout(layout);
+ inner.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ //Element
+ Label label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.element")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fElementText= new Text(inner, SWT.BORDER);
+ fElementText.setText(fMapping.getElement());
+ fElementText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fElementText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+ //Signature
+ label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.signature")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fSignatureText= new Text(inner, SWT.BORDER);
+ fSignatureText.setText(fMapping.getSignature());
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ data.widthHint = convertWidthInCharsToPixels(50);
+ fSignatureText.setLayoutData(data);
+ fSignatureText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+ //Id Attribute
+ label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.idattribute")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fIdAttributeText= new Text(inner, SWT.BORDER);
+
+ fIdAttributeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fIdAttributeText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+ //Id Source
+ createIdSourceGroup(inner);
+
+ fElementText.setFocus();
+
+ return composite;
+ }
+
+/**
+ * Validate user input
+ */
+ private void doValidation() {
+ StatusInfo status= new StatusInfo();
+ String text = fElementText.getText();
+ String mappingKey = Mapping.getKey(fSignatureText.getText(), text);
+ String errormsg = ""; //$NON-NLS-1$
+ boolean isError = false;
+ if (text.length() == 0) {
+ errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.noname"); //$NON-NLS-1$
+ isError = true;
+ } else if (XMLComparePreferencePage.containsInvalidCharacters(text)) {
+ if (errormsg == "") errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.invalidname"); //$NON-NLS-2$ //$NON-NLS-1$
+ isError = true;
+ } else if (!fEdit && fIdmapHM != null && fIdmapHM.containsKey(mappingKey)) {
+ if (errormsg == "") errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.mappingExists"); //$NON-NLS-2$ //$NON-NLS-1$
+ isError = true;
+ }
+ text = fSignatureText.getText();
+ if (XMLComparePreferencePage.containsInvalidCharacters(text)) {
+ if (errormsg == "") errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.invalidsignature"); //$NON-NLS-2$ //$NON-NLS-1$
+ isError = true;
+ }
+ text = fIdAttributeText.getText();
+ if (text.length() == 0)
+ isError = true;
+ else if (XMLComparePreferencePage.containsInvalidCharacters(text)) {
+ if (errormsg == "") errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.invalididattribute"); //$NON-NLS-2$ //$NON-NLS-1$
+ isError = true;
+ }
+ if (isError) status.setError(errormsg);
+ updateStatus(status);
+ }
+/**
+ * Notifies that the ok button of this dialog has been pressed.
+ */
+ protected void okPressed() {
+ fMapping.setElement(fElementText.getText());
+ fMapping.setSignature(fSignatureText.getText());
+ String idtext = fIdAttributeText.getText();
+ if (fIdTypeChildBodyButton.getSelection()) {
+ idtext = new Character(XMLStructureCreator.ID_TYPE_BODY) + idtext;
+ }
+ fMapping.setIdAttribute(idtext);
+ super.okPressed();
+ }
+
+ private void createIdSourceGroup(Composite composite) {
+ Label titleLabel = new Label(composite, SWT.NONE);
+ titleLabel.setText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.idtype")); //$NON-NLS-1$
+ titleLabel.setToolTipText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.idtype.tooltip")); //$NON-NLS-1$
+
+ Composite buttonComposite = new Composite(composite, SWT.LEFT);
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ buttonComposite.setLayout(layout);
+ composite.setData(new GridData());
+
+ //attribute button
+ fIdTypeAttributeButton= createRadioButton(buttonComposite, XMLCompareMessages.getString("XMLComparePreference.idtype.attribute")); //$NON-NLS-1$
+ fIdTypeAttributeButton.setToolTipText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.idtype.attribute.tooltip")); //$NON-NLS-1$
+
+ //child body button
+ fIdTypeChildBodyButton = createRadioButton(buttonComposite, XMLCompareMessages.getString("XMLComparePreference.idtype.child_body")); //$NON-NLS-1$
+ fIdTypeChildBodyButton.setToolTipText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.idtype.childbody.tooltip")); //$NON-NLS-1$
+
+ String idtext = fMapping.getIdAttribute();
+ if (fEdit && idtext.charAt(0) == XMLStructureCreator.ID_TYPE_BODY) {
+ idtext = idtext.substring(1,idtext.length());
+ fIdTypeChildBodyButton.setSelection(true);
+ } else
+ fIdTypeAttributeButton.setSelection(true);
+ fIdAttributeText.setText(idtext);
+
+ }
+
+ private Button createRadioButton(Composite parent, String label) {
+ Button button = new Button(parent, SWT.RADIO | SWT.LEFT);
+ button.setText(label);
+ GridData data = new GridData();
+ button.setLayoutData(data);
+ return button;
+ }
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditOrderedDialog.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditOrderedDialog.java
new file mode 100644
index 000000000..ea9b37daa
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareEditOrderedDialog.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.ArrayList;
+
+import org.eclipse.compare.examples.xml.ui.StatusDialog;
+import org.eclipse.compare.examples.xml.ui.StatusInfo;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * This class is used to add or edit a particular ID Mapping
+ */
+public class XMLCompareEditOrderedDialog extends StatusDialog {
+
+ private Mapping fMapping;
+ private ArrayList fIdmapAL;
+ private boolean fEdit;
+
+ private Text fElementText;
+ private Text fSignatureText;
+
+/**
+ * Constructs a new edit mapping dialog.
+ */
+ public XMLCompareEditOrderedDialog(Shell parent, Mapping mapping, ArrayList idmapAL, boolean edit) {
+ super(parent);
+
+ int shellStyle= getShellStyle();
+ setShellStyle(shellStyle | SWT.MAX | SWT.RESIZE);
+
+
+ fEdit = edit;
+ if (fEdit)
+ setTitle(XMLCompareMessages.getString("XMLCompareEditOrderedDialog.editTitle")); //$NON-NLS-1$
+ else
+ setTitle(XMLCompareMessages.getString("XMLCompareEditOrderedDialog.newTitle")); //$NON-NLS-1$
+
+ fMapping= mapping;
+ fIdmapAL = idmapAL;
+ }
+/**
+ * Creates and returns the contents of the upper part
+ * of the dialog (above the button bar).
+ *
+ * Subclasses should override.
+ *
+ * @param the parent composite to contain the dialog area
+ * @return the dialog area control
+ */
+ protected Control createDialogArea(Composite ancestor) {
+ Composite composite= (Composite) super.createDialogArea(ancestor);
+
+ Composite inner= new Composite(composite, SWT.NONE);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ inner.setLayout(layout);
+ inner.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ //Element
+ Label label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.element")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fElementText= new Text(inner, SWT.BORDER);
+ fElementText.setText(fMapping.getElement());
+ fElementText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fElementText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+ //Signature
+ label= new Label(inner, SWT.NULL);
+ label.setText(XMLCompareMessages.getString("XMLCompareEditMappingDialog.signature")); //$NON-NLS-1$
+ label.setLayoutData(new GridData());
+
+ fSignatureText= new Text(inner, SWT.BORDER);
+ fSignatureText.setText(fMapping.getSignature());
+ GridData data = new GridData(GridData.FILL_HORIZONTAL);
+ data.widthHint = convertWidthInCharsToPixels(50);
+ fSignatureText.setLayoutData(data);
+ fSignatureText.addModifyListener(new ModifyListener() {
+ public void modifyText(ModifyEvent e){
+ doValidation();
+ }
+ });
+
+ fElementText.setFocus();
+
+ return composite;
+ }
+
+/**
+ * Validate user input
+ */
+ private void doValidation() {
+ StatusInfo status= new StatusInfo();
+ String text = fElementText.getText();
+ String mappingKey = Mapping.getKey(fSignatureText.getText(), text);
+ String errormsg = ""; //$NON-NLS-1$
+ boolean isError = false;
+ if (text.length() == 0) {
+ errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.noname"); //$NON-NLS-1$
+ isError = true;
+ } else if (XMLComparePreferencePage.containsInvalidCharacters(text)) {
+ if (errormsg == "") errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.invalidname"); //$NON-NLS-2$ //$NON-NLS-1$
+ isError = true;
+ } else if (!fEdit && fIdmapAL.contains(mappingKey)) {
+ if (errormsg == "") errormsg = XMLCompareMessages.getString("XMLCompareEditOrderedDialog.error.orderedExists"); //$NON-NLS-1$ //$NON-NLS-2$
+ isError = true;
+ }
+ text = fSignatureText.getText();
+ if (XMLComparePreferencePage.containsInvalidCharacters(text)) {
+ if (errormsg == "") errormsg = XMLCompareMessages.getString("XMLCompareEditMappingDialog.error.invalidsignature"); //$NON-NLS-2$ //$NON-NLS-1$
+ isError = true;
+ }
+ if (isError) status.setError(errormsg);
+ updateStatus(status);
+ }
+/**
+ * Notifies that the ok button of this dialog has been pressed.
+ */
+ protected void okPressed() {
+ fMapping.setElement(fElementText.getText());
+ fMapping.setSignature(fSignatureText.getText());
+ super.okPressed();
+ }
+
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareMessages.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareMessages.java
new file mode 100644
index 000000000..3bf4161c5
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLCompareMessages.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class XMLCompareMessages {
+
+ private static final String BUNDLE_NAME = "org.eclipse.compare.examples.xml.xmlcompare"; //$NON-NLS-1$
+ //$NON-NLS-1$
+
+ private static final ResourceBundle RESOURCE_BUNDLE =
+ ResourceBundle.getBundle(BUNDLE_NAME);
+
+ private XMLCompareMessages() {
+ }
+
+ public static String getString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLComparePreferencePage.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLComparePreferencePage.java
new file mode 100644
index 000000000..77db954a2
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLComparePreferencePage.java
@@ -0,0 +1,837 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.*;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.jface.window.Window;
+
+import org.eclipse.ui.*;
+
+/**
+ * The XMLComparePreferencePage is the page used to set ID Mappings for XML Compare
+ */
+public class XMLComparePreferencePage extends PreferencePage implements IWorkbenchPreferencePage, Listener {
+
+ private Table fIdMapsTable;
+ private Button fAddIdMapButton;
+ private Button fRenameIdMapButton;
+ private Button fRemoveIdMapButton;
+ private Button fEditIdMapButton;
+
+ private Table fMappingsTable;
+ private Button fNewMappingsButton;
+ private Button fEditMappingsButton;
+ private Button fRemoveMappingsButton;
+
+ private Table fOrderedTable;
+ private Button fNewOrderedButton;
+ private Button fEditOrderedButton;
+ private Button fRemoveOrderedButton;
+
+ private HashMap fIdMapsInternal;
+ private HashMap fIdMaps;// HashMap ( idname -> HashMap (signature -> id) )
+ private HashMap fIdExtensionToName;
+
+ //fOrderedElements contains signature of xml element whose children must be compared in ordered fashion
+ private HashMap fOrderedElements;// HashMap ( idname -> ArrayList (signature) )
+ private HashMap fOrderedElementsInternal;
+
+ protected static char[] invalidCharacters;
+ protected static final char SIGN_SEPARATOR = XMLStructureCreator.SIGN_SEPARATOR;
+
+ public static String IDTYPE_ATTRIBUTE= XMLCompareMessages.getString("XMLComparePreference.idtype.attribute"); //$NON-NLS-1$
+ public static String IDTYPE_CHILDBODY= XMLCompareMessages.getString("XMLComparePreference.idtype.child_body"); //$NON-NLS-1$
+
+
+ static {
+ invalidCharacters = new char[] {XMLPlugin.IDMAP_SEPARATOR,XMLPlugin.IDMAP_FIELDS_SEPARATOR,XMLStructureCreator.SIGN_ENCLOSING};
+ }
+
+
+ public XMLComparePreferencePage() {
+ super();
+
+ fIdMaps = new HashMap();
+ XMLPlugin plugin= XMLPlugin.getDefault();
+ HashMap PluginIdMaps = plugin.getIdMaps();
+ Set keySet = PluginIdMaps.keySet();
+ for (Iterator iter = keySet.iterator(); iter.hasNext(); ) {
+ String key = (String) iter.next();
+ fIdMaps.put(key, ((HashMap)PluginIdMaps.get(key)).clone() );
+ }
+ fIdMapsInternal = plugin.getIdMapsInternal();
+
+ fIdExtensionToName= new HashMap();
+ HashMap PluginIdExtensionToName= plugin.getIdExtensionToName();
+ keySet= PluginIdExtensionToName.keySet();
+ for (Iterator iter= keySet.iterator(); iter.hasNext(); ) {
+ String key= (String) iter.next();
+ fIdExtensionToName.put(key, PluginIdExtensionToName.get(key));
+ }
+
+ fOrderedElements= new HashMap();
+ HashMap PluginOrderedElements= plugin.getOrderedElements();
+ keySet= PluginOrderedElements.keySet();
+ for (Iterator iter= keySet.iterator(); iter.hasNext();) {
+ String key= (String) iter.next();
+ fOrderedElements.put(key, ((ArrayList)PluginOrderedElements.get(key)).clone());
+ }
+
+ fOrderedElementsInternal= plugin.getOrderedElementsInternal();
+ }
+
+ /**
+ * @see PreferencePage#createContents(Composite)
+ */
+ protected Control createContents(Composite ancestor) {
+ Composite parent= new Composite(ancestor, SWT.NULL);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 2;
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ parent.setLayout(layout);
+
+ //layout the top table & its buttons
+ Label label = new Label(parent, SWT.LEFT);
+ label.setText(XMLCompareMessages.getString("XMLComparePreference.topTableLabel")); //$NON-NLS-1$
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+
+ fIdMapsTable = new Table(parent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
+ fIdMapsTable.setHeaderVisible(true);
+ data = new GridData(GridData.FILL_BOTH);
+ data.heightHint = fIdMapsTable.getItemHeight()*4;
+ fIdMapsTable.setLayoutData(data);
+ fIdMapsTable.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ selectionChanged();
+ }
+ });
+
+ String column2Text= XMLCompareMessages.getString("XMLComparePreference.topTableColumn2"); //$NON-NLS-1$
+ String column3Text= XMLCompareMessages.getString("XMLComparePreference.topTableColumn3"); //$NON-NLS-1$
+ ColumnLayoutData columnLayouts[]= {
+ new ColumnWeightData(1),
+ new ColumnPixelData(convertWidthInCharsToPixels(column2Text.length()+2), true),
+ new ColumnPixelData(convertWidthInCharsToPixels(column3Text.length()+5), true)};
+ TableLayout tablelayout = new TableLayout();
+ fIdMapsTable.setLayout(tablelayout);
+ for (int i=0; i<3; i++)
+ tablelayout.addColumnData(columnLayouts[i]);
+ TableColumn column = new TableColumn(fIdMapsTable, SWT.NONE);
+ column.setText(XMLCompareMessages.getString("XMLComparePreference.topTableColumn1")); //$NON-NLS-1$
+ column = new TableColumn(fIdMapsTable, SWT.NONE);
+ column.setText(column2Text); //$NON-NLS-1$
+ column = new TableColumn(fIdMapsTable, SWT.NONE);
+ column.setText(column3Text); //$NON-NLS-1$
+
+ fillIdMapsTable();
+
+ Composite buttons= new Composite(parent, SWT.NULL);
+ buttons.setLayout(new GridLayout());
+ data = new GridData();
+ data.verticalAlignment = GridData.FILL;
+ data.horizontalAlignment = GridData.FILL;
+ buttons.setLayoutData(data);
+
+ fAddIdMapButton = new Button(buttons, SWT.PUSH);
+ fAddIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topAdd")); //$NON-NLS-1$
+ fAddIdMapButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ addIdMap(fAddIdMapButton.getShell());
+ }
+ });
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+ int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ data.widthHint = Math.max(widthHint, fAddIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ fAddIdMapButton.setLayoutData(data);
+
+ fRenameIdMapButton = new Button(buttons, SWT.PUSH);
+ fRenameIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topRename")); //$NON-NLS-1$
+ fRenameIdMapButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ renameIdMap(fRenameIdMapButton.getShell());
+ }
+ });
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+ widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ data.widthHint = Math.max(widthHint, fAddIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ fRenameIdMapButton.setLayoutData(data);
+
+ fRemoveIdMapButton = new Button(buttons, SWT.PUSH);
+ fRemoveIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topRemove")); //$NON-NLS-1$
+ fRemoveIdMapButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ removeIdMap(fRemoveIdMapButton.getShell());
+ }
+ });
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+ widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ data.widthHint = Math.max(widthHint, fRemoveIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ fRemoveIdMapButton.setLayoutData(data);
+
+ createSpacer(buttons);
+
+ fEditIdMapButton = new Button(buttons, SWT.PUSH);
+ fEditIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topEdit")); //$NON-NLS-1$
+ fEditIdMapButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ editIdMap(fEditIdMapButton.getShell());
+ }
+ });
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
+ widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
+ data.widthHint = Math.max(widthHint, fEditIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
+ fEditIdMapButton.setLayoutData(data);
+
+ //Spacer
+ label = new Label(parent, SWT.LEFT);
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+
+ //layout the middle table & its buttons
+ label = new Label(parent, SWT.LEFT);
+ label.setText(XMLCompareMessages.getString("XMLComparePreference.middleTableLabel")); //$NON-NLS-1$
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+
+ fMappingsTable = new Table(parent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
+ fMappingsTable.setHeaderVisible(true);
+ data = new GridData(GridData.FILL_BOTH);
+ data.heightHint = fMappingsTable.getItemHeight()*4;
+ data.widthHint= convertWidthInCharsToPixels(70);
+ fMappingsTable.setLayoutData(data);
+
+ column3Text= XMLCompareMessages.getString("XMLComparePreference.middleTableColumn3"); //$NON-NLS-1$
+ String column4Text= XMLCompareMessages.getString("XMLComparePreference.middleTableColumn4"); //$NON-NLS-1$
+ columnLayouts= new ColumnLayoutData[] {
+ new ColumnWeightData(10),
+ new ColumnWeightData(18),
+ new ColumnPixelData(convertWidthInCharsToPixels(column3Text.length()+1), true),
+ new ColumnPixelData(convertWidthInCharsToPixels(column4Text.length()+3), true)};
+ tablelayout = new TableLayout();
+ fMappingsTable.setLayout(tablelayout);
+ for (int i=0; i<4; i++)
+ tablelayout.addColumnData(columnLayouts[i]);
+ column = new TableColumn(fMappingsTable, SWT.NONE);
+ column.setText(XMLCompareMessages.getString("XMLComparePreference.middleTableColumn1")); //$NON-NLS-1$
+ column = new TableColumn(fMappingsTable, SWT.NONE);
+ column.setText(XMLCompareMessages.getString("XMLComparePreference.middleTableColumn2")); //$NON-NLS-1$
+ column = new TableColumn(fMappingsTable, SWT.NONE);
+ column.setText(column3Text); //$NON-NLS-1$
+ column = new TableColumn(fMappingsTable, SWT.NONE);
+ column.setText(column4Text); //$NON-NLS-1$
+
+ buttons= new Composite(parent, SWT.NULL);
+ buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+ layout= new GridLayout();
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ buttons.setLayout(layout);
+
+ fNewMappingsButton= new Button(buttons, SWT.PUSH);
+ fNewMappingsButton.setLayoutData(getButtonGridData(fNewMappingsButton));
+ fNewMappingsButton.setText(XMLCompareMessages.getString("XMLComparePreference.middleNew")); //$NON-NLS-1$
+ fNewMappingsButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ addMapping(fAddIdMapButton.getShell());
+ }
+ });
+
+ fEditMappingsButton= new Button(buttons, SWT.PUSH);
+ fEditMappingsButton.setLayoutData(getButtonGridData(fEditMappingsButton));
+ fEditMappingsButton.setText(XMLCompareMessages.getString("XMLComparePreference.middleEdit")); //$NON-NLS-1$
+ fEditMappingsButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ editMapping(fEditMappingsButton.getShell());
+ }
+ });
+
+ fRemoveMappingsButton= new Button(buttons, SWT.PUSH);
+ fRemoveMappingsButton.setLayoutData(getButtonGridData(fRemoveMappingsButton));
+ fRemoveMappingsButton.setText(XMLCompareMessages.getString("XMLComparePreference.middleRemove")); //$NON-NLS-1$
+ fRemoveMappingsButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ removeMapping(fRemoveMappingsButton.getShell());
+ }
+ });
+
+ createSpacer(buttons);
+
+ //layout the botton table & its buttons
+ label = new Label(parent, SWT.LEFT);
+ label.setText(XMLCompareMessages.getString("XMLComparePreference.bottomTableLabel")); //$NON-NLS-1$
+ data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.horizontalSpan = 2;
+ label.setLayoutData(data);
+
+ fOrderedTable = new Table(parent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
+ fOrderedTable.setHeaderVisible(true);
+ data = new GridData(GridData.FILL_BOTH);
+ data.heightHint = fOrderedTable.getItemHeight()*2;
+ data.widthHint= convertWidthInCharsToPixels(70);
+ fOrderedTable.setLayoutData(data);
+
+ columnLayouts= new ColumnLayoutData[] {
+ new ColumnWeightData(1),
+ new ColumnWeightData(1)};
+ tablelayout = new TableLayout();
+ fOrderedTable.setLayout(tablelayout);
+ for (int i=0; i<2; i++)
+ tablelayout.addColumnData(columnLayouts[i]);
+ column = new TableColumn(fOrderedTable, SWT.NONE);
+ column.setText(XMLCompareMessages.getString("XMLComparePreference.bottomTableColumn1")); //$NON-NLS-1$
+ column = new TableColumn(fOrderedTable, SWT.NONE);
+ column.setText(XMLCompareMessages.getString("XMLComparePreference.bottomTableColumn2")); //$NON-NLS-1$
+
+ buttons= new Composite(parent, SWT.NULL);
+ buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+ layout= new GridLayout();
+ layout.marginHeight= 0;
+ layout.marginWidth= 0;
+ buttons.setLayout(layout);
+
+ fNewOrderedButton= new Button(buttons, SWT.PUSH);
+ fNewOrderedButton.setLayoutData(getButtonGridData(fNewOrderedButton));
+ fNewOrderedButton.setText(XMLCompareMessages.getString("XMLComparePreference.bottomNew")); //$NON-NLS-1$
+ fNewOrderedButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ addOrdered(fNewOrderedButton.getShell());
+ }
+ });
+
+ fEditOrderedButton= new Button(buttons, SWT.PUSH);
+ fEditOrderedButton.setLayoutData(getButtonGridData(fEditOrderedButton));
+ fEditOrderedButton.setText(XMLCompareMessages.getString("XMLComparePreference.bottomEdit")); //$NON-NLS-1$
+ fEditOrderedButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ editOrdered(fEditOrderedButton.getShell());
+ }
+ });
+
+ fRemoveOrderedButton= new Button(buttons, SWT.PUSH);
+ fRemoveOrderedButton.setLayoutData(getButtonGridData(fRemoveOrderedButton));
+ fRemoveOrderedButton.setText(XMLCompareMessages.getString("XMLComparePreference.bottomRemove")); //$NON-NLS-1$
+ fRemoveOrderedButton.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ removeOrdered(fRemoveOrderedButton.getShell());
+ }
+ });
+
+ createSpacer(buttons);
+
+
+
+ fIdMapsTable.setSelection(0);
+ fIdMapsTable.setFocus();
+ selectionChanged();
+
+ return parent;
+ }
+
+ protected void createSpacer(Composite parent) {
+ Label spacer= new Label(parent, SWT.NONE);
+ GridData data= new GridData();
+ data.horizontalAlignment= GridData.FILL;
+ data.verticalAlignment= GridData.BEGINNING;
+ data.heightHint= 4;
+ spacer.setLayoutData(data);
+ }
+
+ private static GridData getButtonGridData(Button button) {
+ GridData data= new GridData(GridData.FILL_HORIZONTAL);
+ data.widthHint= SWTUtil.getButtonWidthHint(button);
+ data.heightHint= SWTUtil.getButtonHeigthHint(button);
+
+ return data;
+ }
+
+ public void init(IWorkbench workbench) {
+ noDefaultAndApplyButton();
+ }
+
+ public void handleEvent(Event event) {
+ }
+
+ private void addIdMap(Shell shell) {
+ IdMap idmap = new IdMap(false);
+ XMLCompareAddIdMapDialog dialog= new XMLCompareAddIdMapDialog(shell,idmap,fIdMaps,fIdMapsInternal,fIdExtensionToName,false);
+ if (dialog.open() == Window.OK) {
+ if (!fIdMaps.containsKey(idmap.getName())) {
+ fIdMaps.put(idmap.getName(),new HashMap());
+ if (!idmap.getExtension().equals("")) //$NON-NLS-1$
+ fIdExtensionToName.put(idmap.getExtension(),idmap.getName());
+ newIdMapsTableItem(idmap,true);
+ }
+ }
+ }
+
+ private void renameIdMap(Shell shell) {
+ TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
+ if (itemsIdMaps.length > 0) {
+ IdMap idmap = (IdMap) itemsIdMaps[0].getData();
+ String old_name = idmap.getName();
+ String old_extension= idmap.getExtension();
+ HashMap idmapHS = (HashMap) fIdMaps.get(old_name);
+ XMLCompareAddIdMapDialog dialog= new XMLCompareAddIdMapDialog(shell,idmap,fIdMaps,fIdMapsInternal,fIdExtensionToName,true);
+ if (dialog.open() == Window.OK) {
+ fIdMaps.remove(old_name);
+ fIdExtensionToName.remove(old_extension);
+ fIdMaps.put(idmap.getName(),idmapHS);
+ if (!idmap.getExtension().equals("")) //$NON-NLS-1$
+ fIdExtensionToName.put(idmap.getExtension(),idmap.getName());
+ fIdMapsTable.remove(fIdMapsTable.indexOf(itemsIdMaps[0]));
+ newIdMapsTableItem(idmap,true);
+ }
+ }
+ }
+
+ private void removeIdMap(Shell shell) {
+ TableItem[] itemsIdMap = fIdMapsTable.getSelection();
+ if (itemsIdMap.length > 0) {
+// fIdMaps.remove(itemsIdMap[0].getText());
+ String IdMapName= ((IdMap)itemsIdMap[0].getData()).getName();
+ fIdMaps.remove( IdMapName );
+ fOrderedElements.remove( IdMapName );
+ //All the corresponding ID Mappings must be removed as well
+ TableItem[] itemsMappings = fMappingsTable.getItems();
+ for (int i=0; i<itemsMappings.length; i++) {
+ itemsMappings[i].dispose();
+ }
+ //All the corresponding Ordered entries must be removed as well
+ TableItem[] itemsOrdered= fOrderedTable.getItems();
+ for (int i= 0; i < itemsOrdered.length; i++) {
+ itemsOrdered[i].dispose();
+ }
+ //Remove extension
+ if (!itemsIdMap[0].getText(2).equals("")) { //$NON-NLS-1$
+ fIdExtensionToName.remove(itemsIdMap[0].getText(2));
+ }
+ itemsIdMap[0].dispose(); //Table is single selection
+ }
+ }
+
+ private void editIdMap(Shell shell) {
+ TableItem[] items = fIdMapsTable.getSelection();
+ if (items.length > 0) {
+ IdMap idmap = (IdMap) items[0].getData();
+ XMLCompareEditCopyIdMapDialog dialog= new XMLCompareEditCopyIdMapDialog(shell,idmap,fIdMaps,fIdMapsInternal);
+ if (dialog.open() == Window.OK) {
+ String new_idmapName = dialog.getResult();
+ if (!fIdMaps.containsKey(new_idmapName)) {
+ //copy over id mappings
+ Vector newMappings = new Vector();
+ IdMap newIdMap = new IdMap(new_idmapName, false, newMappings);
+ HashMap newIdmapHM = new HashMap();
+ fIdMaps.put(newIdMap.getName(),newIdmapHM);
+ Vector Mappings = idmap.getMappings();
+ for (Enumeration enum= Mappings.elements(); enum.hasMoreElements(); ) {
+ Mapping mapping = (Mapping) enum.nextElement();
+ Mapping newMapping = new Mapping(mapping.getElement(), mapping.getSignature(), mapping.getIdAttribute());
+ newMappings.add(newMapping);
+ newIdmapHM.put(newMapping.getKey(), newMapping.getIdAttribute());
+ }
+ //copy over ordered entries
+ ArrayList orderedAL= idmap.getOrdered();
+ if (orderedAL != null && orderedAL.size() > 0) {
+ ArrayList newOrderedAL= new ArrayList();
+ newIdMap.setOrdered(newOrderedAL);
+ ArrayList idmapOrdered= new ArrayList();
+ fOrderedElements.put(newIdMap.getName(),idmapOrdered);
+ for (Iterator iter= orderedAL.iterator(); iter.hasNext();) {
+ Mapping ordered= (Mapping) iter.next();
+ Mapping newOrdered= new Mapping(ordered.getElement(), ordered.getSignature());
+ newOrderedAL.add(newOrdered);
+ idmapOrdered.add(newOrdered.getKey());
+ }
+ }
+
+ newIdMapsTableItem(newIdMap,true);
+ selectionChanged();
+ }
+ }
+ }
+ }
+
+ private void addMapping(Shell shell) {
+ TableItem[] items = fIdMapsTable.getSelection();
+ if (items.length > 0) {
+ IdMap idmap = (IdMap) items[0].getData();
+ Mapping mapping = new Mapping();
+ HashMap idmapHM = (HashMap) fIdMaps.get(idmap.getName());
+ XMLCompareEditMappingDialog dialog= new XMLCompareEditMappingDialog(shell,mapping,idmapHM,false);
+ if (dialog.open() == Window.OK) {
+ String idmapHMKey = mapping.getKey();
+ if (idmapHM == null)
+ idmapHM= new HashMap();
+ if (!idmapHM.containsKey(idmapHMKey)) {
+ idmapHM.put(idmapHMKey, mapping.getIdAttribute());
+ newMappingsTableItem(mapping, true);
+ Vector mappings = idmap.getMappings();
+ mappings.add(mapping);
+ }
+ }
+ }
+ }
+
+ private void editMapping(Shell shell) {
+ TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
+ TableItem[] itemsMappings = fMappingsTable.getSelection();
+ if (itemsMappings.length > 0) {
+ IdMap idmap = (IdMap) itemsIdMaps[0].getData();
+ HashMap idmapHM = (HashMap) fIdMaps.get(idmap.getName());
+ Mapping mapping = (Mapping)itemsMappings[0].getData();
+ String idmapHMKey = mapping.getKey();
+ idmapHM.remove(idmapHMKey);
+ XMLCompareEditMappingDialog dialog= new XMLCompareEditMappingDialog(shell,mapping,null,true);
+ if (dialog.open() == Window.OK) {
+ idmapHMKey = mapping.getKey();
+ idmapHM.put(idmapHMKey, mapping.getIdAttribute());
+ fMappingsTable.remove(fMappingsTable.indexOf(itemsMappings[0]));
+ newMappingsTableItem(mapping, true);
+ }
+ }
+ }
+
+ private void removeMapping(Shell shell) {
+ TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
+ TableItem[] itemsMappings = fMappingsTable.getSelection();
+
+ if (itemsMappings.length > 0 && itemsIdMaps.length > 0) {
+ Mapping mapping = (Mapping)itemsMappings[0].getData();
+ IdMap idmap = (IdMap) itemsIdMaps[0].getData();
+ HashMap idmapHS = (HashMap) fIdMaps.get( idmap.getName() );
+ idmapHS.remove(mapping.getKey());
+ Vector mappings= idmap.getMappings();
+ mappings.remove(mapping);
+ itemsMappings[0].dispose(); //Table is single selection
+ }
+ }
+
+ private void addOrdered(Shell shell) {
+ TableItem[] items = fIdMapsTable.getSelection();
+ if (items.length > 0) {
+// Set orderedSet= fOrderedElements.keySet();
+// for (Iterator iter= orderedSet.iterator(); iter.hasNext(); ) {
+// String IdMapName= (String) iter.next();
+// ArrayList ordered= (ArrayList) fOrderedElements.get(IdMapName);
+// for (Iterator iter2= ordered.iterator(); iter2.hasNext(); ) {
+// System.out.println(IdMapName + ": " + iter2.next()); //$NON-NLS-1$
+// }
+// }
+ IdMap idmap = (IdMap) items[0].getData();
+ Mapping mapping = new Mapping();
+ ArrayList idmapAL= (ArrayList) fOrderedElements.get(idmap.getName());
+ if (idmapAL == null)
+ idmapAL= new ArrayList();
+ XMLCompareEditOrderedDialog dialog= new XMLCompareEditOrderedDialog(shell,mapping,idmapAL,false);
+ if (dialog.open() == Window.OK) {
+ String idmapALKey = mapping.getKey();
+ if (!idmapAL.contains(idmapALKey)) {
+ idmapAL.add(idmapALKey);
+ newOrderedTableItem(mapping, true);
+ ArrayList ordered= idmap.getOrdered();
+ if (ordered == null) {
+ ordered= new ArrayList();
+ ordered.add(mapping);
+ idmap.setOrdered(ordered);
+ } else {
+ ordered.add(mapping);
+ }
+ if (!fOrderedElements.containsKey(idmap.getName()))
+ fOrderedElements.put(idmap.getName(), idmapAL);
+ }
+ }
+ }
+ }
+
+ private void editOrdered(Shell shell) {
+ TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
+ TableItem[] itemsOrdered = fOrderedTable.getSelection();
+ if (itemsOrdered.length > 0) {
+ IdMap idmap = (IdMap) itemsIdMaps[0].getData();
+ ArrayList idmapAL = (ArrayList) fOrderedElements.get(idmap.getName());
+ Mapping mapping = (Mapping)itemsOrdered[0].getData();
+ String idmapALKey = mapping.getKey();
+ idmapAL.remove(idmapALKey);
+ XMLCompareEditOrderedDialog dialog= new XMLCompareEditOrderedDialog(shell,mapping,null,true);
+ if (dialog.open() == Window.OK) {
+ idmapALKey = mapping.getKey();
+ idmapAL.add(idmapALKey);
+ fOrderedTable.remove(fOrderedTable.indexOf(itemsOrdered[0]));
+ newOrderedTableItem(mapping, true);
+ }
+ }
+
+ }
+
+ private void removeOrdered(Shell shell) {
+ TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
+ TableItem[] itemsOrdered = fOrderedTable.getSelection();
+ if (itemsOrdered.length > 0 && itemsIdMaps.length > 0) {
+ Mapping mapping = (Mapping)itemsOrdered[0].getData();
+ IdMap idmap = (IdMap) itemsIdMaps[0].getData();
+ ArrayList idmapAL = (ArrayList) fOrderedElements.get( idmap.getName() );
+ idmapAL.remove(mapping.getKey());
+ if (idmapAL.size() <= 0)
+ fOrderedElements.remove(idmap.getName());
+ ArrayList ordered= idmap.getOrdered();
+ ordered.remove(mapping);
+ if (ordered.size() <= 0)
+ idmap.setOrdered(null);
+ itemsOrdered[0].dispose(); //Table is single selection
+ }
+ }
+
+ protected TableItem newIdMapsTableItem(IdMap idmap, boolean selected) {
+ //find index where to insert table entry
+ TableItem[] items = fIdMapsTable.getItems();
+ int i;
+ for (i=0; i<items.length && idmap.getName().compareToIgnoreCase(items[i].getText(0)) > 0; i++);
+ TableItem item = new TableItem(fIdMapsTable, SWT.NULL, i);
+ String[] values = new String[] {idmap.getName(), (idmap.isInternal())?XMLCompareMessages.getString("XMLComparePreference.topTableColumn2internal"):XMLCompareMessages.getString("XMLComparePreference.topTableColumn2user"),idmap.getExtension()}; //$NON-NLS-2$ //$NON-NLS-1$
+ item.setText(values);
+ item.setData(idmap);
+ if (selected) {
+ fIdMapsTable.setSelection(i);
+ fIdMapsTable.setFocus();
+ selectionChanged();
+ }
+ return item;
+ }
+
+ protected TableItem newMappingsTableItem(Mapping mapping, boolean selected) {
+ TableItem[] items = fMappingsTable.getItems();
+ int i;
+ for (i=0; i<items.length && mapping.getElement().compareToIgnoreCase(items[i].getText(0)) > 0; i++);
+
+ TableItem item = new TableItem(fMappingsTable, SWT.NULL, i);
+ String idtext = mapping.getIdAttribute();
+ String idtype;
+ if (idtext.charAt(0)==XMLStructureCreator.ID_TYPE_BODY) {
+ idtext = idtext.substring(1,idtext.length());
+ idtype = IDTYPE_CHILDBODY;
+ } else
+ idtype = IDTYPE_ATTRIBUTE;
+
+ String[] values = new String[] {mapping.getElement(), mapping.getSignature(), idtext, idtype};
+ item.setText(values);
+ item.setData(mapping);
+ if (selected)
+ fMappingsTable.setSelection(i);
+
+ return item;
+ }
+
+ protected TableItem newOrderedTableItem(Mapping mapping, boolean selected) {
+ TableItem[] items = fOrderedTable.getItems();
+ int i;
+ for (i=0; i<items.length && mapping.getElement().compareToIgnoreCase(items[i].getText(0)) > 0; i++);
+
+ TableItem item = new TableItem(fOrderedTable, SWT.NULL, i);
+
+ String[] values = new String[] {mapping.getElement(), mapping.getSignature()};
+ item.setText(values);
+ item.setData(mapping);
+ if (selected)
+ fOrderedTable.setSelection(i);
+
+ return item;
+ }
+
+
+ protected void fillIdMapsTable() {
+ //fill user idmaps from plugin.xml
+ fillIdMaps(true);
+
+ //fill user idmaps from Preference Store
+ fillIdMaps(false);
+
+ //add user idmaps that have ordered entries but no id mappings
+ //they do not appear in the preference store with name IDMAP_PREFERENCE_NAME
+ Set OrderedKeys= fOrderedElements.keySet();
+ Set IdMapKeys= fIdMaps.keySet();
+ for (Iterator iter_orderedElements= OrderedKeys.iterator(); iter_orderedElements.hasNext();) {
+ String IdMapName= (String) iter_orderedElements.next();
+ if (!IdMapKeys.contains(IdMapName)) {
+ IdMap idmap= new IdMap(IdMapName, false);
+ ArrayList idmapOrdered= (ArrayList) fOrderedElements.get(IdMapName);
+ setOrdered(idmap, idmapOrdered);
+ newIdMapsTableItem(idmap, false);
+ }
+ }
+ }
+
+ private void fillIdMaps(boolean internal) {
+ HashMap IdMaps= (internal)?fIdMapsInternal:fIdMaps;
+ HashMap OrderedElements= (internal)?fOrderedElementsInternal:fOrderedElements;
+ Set IdMapKeys = IdMaps.keySet();
+ for (Iterator iter_internal = IdMapKeys.iterator(); iter_internal.hasNext(); ) {
+ String IdMapName = (String) iter_internal.next();
+ Vector Mappings = new Vector();
+ IdMap idmap = new IdMap(IdMapName, internal, Mappings);
+ //create mappings of internal idmaps
+ HashMap idmapHM = (HashMap) IdMaps.get(IdMapName);
+ Set idmapKeys = idmapHM.keySet();
+ for (Iterator iter_idmap = idmapKeys.iterator(); iter_idmap.hasNext(); ) {
+ Mapping mapping = new Mapping();
+ String signature = (String) iter_idmap.next();
+ int end_of_signature = signature.lastIndexOf(SIGN_SEPARATOR,signature.length()-2);
+ if (end_of_signature < XMLStructureCreator.ROOT_ID.length() + 1)
+ mapping.setSignature(""); //$NON-NLS-1$
+ else
+ mapping.setSignature(signature.substring(XMLStructureCreator.ROOT_ID.length() + 1,end_of_signature));
+ mapping.setElement(signature.substring(end_of_signature+1,signature.length()-1));
+ mapping.setIdAttribute((String)idmapHM.get(signature));
+ Mappings.add(mapping);
+ }
+ //create ordered mappings
+ ArrayList idmapOrdered= (ArrayList) OrderedElements.get(IdMapName);
+ if (idmapOrdered != null) {
+ setOrdered(idmap, idmapOrdered);
+ }
+ //set extension
+ if (fIdExtensionToName.containsValue(IdMapName)) {
+ Set keySet= fIdExtensionToName.keySet();
+ String extension= new String();
+ for (Iterator iter= keySet.iterator(); iter.hasNext(); ) {
+ extension= (String)iter.next();
+ if ( ((String)fIdExtensionToName.get(extension)).equals(IdMapName) )
+ break;
+ }
+ idmap.setExtension(extension);
+ }
+ newIdMapsTableItem(idmap, false);
+ }
+ }
+
+ protected static void setOrdered(IdMap idmap, ArrayList idmapOrdered) {
+ ArrayList Ordered= new ArrayList();
+ for (Iterator iter_ordered= idmapOrdered.iterator(); iter_ordered.hasNext();) {
+ Mapping mapping= new Mapping();
+ String signature= (String) iter_ordered.next();
+ int end_of_signature = signature.lastIndexOf(SIGN_SEPARATOR,signature.length()-2);
+ if (end_of_signature < XMLStructureCreator.ROOT_ID.length() + 1)
+ mapping.setSignature(""); //$NON-NLS-1$
+ else
+ mapping.setSignature(signature.substring(XMLStructureCreator.ROOT_ID.length() + 1,end_of_signature));
+ mapping.setElement(signature.substring(end_of_signature+1,signature.length()-1));
+ Ordered.add(mapping);
+ }
+ idmap.setOrdered(Ordered);
+ }
+
+ /**
+ * @see IWorkbenchPreferencePage#performDefaults
+ */
+ public boolean performOk() {
+ XMLPlugin plugin= XMLPlugin.getDefault();
+ if (!plugin.getIdMaps().equals(fIdMaps)
+ || !plugin.getIdExtensionToName().equals(fIdExtensionToName)
+ || !plugin.getOrderedElements().equals(fOrderedElements) )
+ plugin.setIdMaps(fIdMaps,fIdExtensionToName,fOrderedElements,true);
+ //XMLPlugin.getDefault().setIdMaps(fIdMaps,fIdExtensionToName,null);
+ return super.performOk();
+ }
+
+ public boolean performCancel() {
+ fIdMaps = (HashMap) XMLPlugin.getDefault().getIdMaps().clone();
+ return super.performCancel();
+ }
+
+ protected void selectionChanged() {
+ TableItem[] items = fIdMapsTable.getSelection();
+ if (items.length > 0) {
+ //Refresh Mappings Table
+ fMappingsTable.removeAll();
+ Vector Mappings = ((IdMap)items[0].getData()).getMappings();
+ for (Enumeration enum = Mappings.elements(); enum.hasMoreElements(); ) {
+ newMappingsTableItem((Mapping)enum.nextElement(), false);
+ }
+ //Refresh Ordered Table
+ fOrderedTable.removeAll();
+ ArrayList Ordered= ((IdMap)items[0].getData()).getOrdered();
+ if (Ordered != null) {
+ for (Iterator iter_ordered= Ordered.iterator(); iter_ordered.hasNext();) {
+ newOrderedTableItem((Mapping)iter_ordered.next(), false);
+ }
+ }
+ }
+ updateEnabledState();
+ }
+
+ /**
+ * Updates the state (enabled, not enabled) of the buttons
+ */
+ private void updateEnabledState() {
+ TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
+ if (itemsIdMaps.length > 0) {
+ IdMap idmap = (IdMap) itemsIdMaps[0].getData();
+ if (idmap.isInternal()) {
+ fRenameIdMapButton.setEnabled(false);
+ fRemoveIdMapButton.setEnabled(false);
+ fEditIdMapButton.setEnabled(true);
+
+ fNewMappingsButton.setEnabled(false);
+ fEditMappingsButton.setEnabled(false);
+ fRemoveMappingsButton.setEnabled(false);
+
+ fNewOrderedButton.setEnabled(false);
+ fEditOrderedButton.setEnabled(false);
+ fRemoveOrderedButton.setEnabled(false);
+ } else {
+ fRenameIdMapButton.setEnabled(true);
+ fRemoveIdMapButton.setEnabled(true);
+ fEditIdMapButton.setEnabled(false);
+
+ fNewMappingsButton.setEnabled(true);
+ fEditMappingsButton.setEnabled(true);
+ fRemoveMappingsButton.setEnabled(true);
+
+ fNewOrderedButton.setEnabled(true);
+ fEditOrderedButton.setEnabled(true);
+ fRemoveOrderedButton.setEnabled(true);
+ }
+ }
+ }
+
+ static protected boolean containsInvalidCharacters(String text) {
+ for (int i=0; i<invalidCharacters.length; i++) {
+ if (text.indexOf(invalidCharacters[i]) > -1)
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLNode.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLNode.java
new file mode 100644
index 000000000..b527fdb3f
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLNode.java
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import org.eclipse.compare.CompareUI;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.structuremergeviewer.DocumentRangeNode;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Objects that make up the parse tree.
+ */
+public class XMLNode extends DocumentRangeNode implements ITypedElement {
+
+ private String fValue;
+ private String fName;
+ private String fSignature;
+ private String fOrigId;
+ private XMLNode parent;
+ private String fXMLType;
+ private boolean fUsesIDMAP;
+ private boolean fOrderedChild;
+
+ public int bodies;//counts the number of bodies
+
+ public XMLNode(String XMLType, String id, String value, String signature, IDocument doc, int start, int length) {
+ super(0, id, doc, start, length);
+ fXMLType = XMLType;
+ fValue= value;
+ fSignature= signature;
+ fOrigId= id;
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Created XMLNode with XMLType: "+XMLType+", id: "+id+", value: "+value+", signature: " +fSignature); //$NON-NLS-1$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$
+ bodies=0;
+ fUsesIDMAP = false;
+ fOrderedChild= false;
+ }
+
+ void setValue(String value) {
+ fValue = value;
+ }
+
+ String getValue() {
+ return fValue;
+ }
+ /**
+ * @see ITypedElement#getName
+ */
+ public String getName() {
+ if (fName != null)
+ return fName;
+ return this.getId();
+ }
+
+ public void setName(String name) {
+ fName = name;
+ }
+ /**
+ * Every xml node is of type "txt" so that the builtin TextMergeViewer is used automatically.
+ * @see ITypedElement#getType
+ */
+ public String getType() {
+ return "txt"; //$NON-NLS-1$
+ }
+
+ public void setIsOrderedChild(boolean isOrderedChild) {
+ fOrderedChild= isOrderedChild;
+ }
+ /**
+ * @see ITypedElement#getImage
+ */
+ public Image getImage() {
+ if (fOrderedChild)
+ return CompareUI.getImage(XMLPlugin.IMAGE_TYPE_PREFIX + XMLStructureCreator.TYPE_ELEMENT + XMLPlugin.IMAGE_TYPE_ORDERED_SUFFIX);
+ else
+ return CompareUI.getImage(XMLPlugin.IMAGE_TYPE_PREFIX + getXMLType());
+ }
+
+ public void setParent(XMLNode parent0) {
+ this.parent = parent0;
+ }
+
+ public XMLNode getParent() {
+ return this.parent;
+ }
+
+ String getXMLType() {
+ return fXMLType;
+ }
+
+ String getSignature() {
+ return fSignature;
+ }
+
+ void setOrigId(String id) {
+ fOrigId= id;
+ }
+
+ public String getOrigId() {
+ return fOrigId;
+ }
+
+ public void setUsesIDMAP(boolean b) {
+ fUsesIDMAP = b;
+ }
+
+ public boolean usesIDMAP() {
+ return fUsesIDMAP;
+ }
+
+ //for tests
+ public boolean testEquals(Object obj) {
+ if (obj instanceof XMLNode) {
+ XMLNode n= (XMLNode) obj;
+ return fValue.equals(n.getValue())
+ && fSignature.equals(n.getSignature())
+ && fXMLType.equals(n.getXMLType())
+ && fUsesIDMAP == n.usesIDMAP();
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the subtree rooted at this node is equals to the subtree rooted at <code>obj</code>
+ */
+ public boolean subtreeEquals(Object obj) {
+ if (!testEquals(obj))
+ return false;
+ if (obj instanceof XMLNode) {
+ XMLNode n= (XMLNode) obj;
+ if (getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE) && n.getXMLType().equals(XMLStructureCreator.TYPE_ATTRIBUTE))
+ return true;
+ Object[] children= getChildren();
+ Object[] n_children= n.getChildren();
+ //if both nodes have no children, return true;
+ if ( (children == null || children.length <= 0) && (n_children == null || n_children.length <= 0) )
+ return true;
+ //now at least one of the two nodes has children;
+ /* so if one of the two nodes has no children, or they don't have the same number of children,
+ * return false;
+ */
+ if ( (children == null || children.length <= 0) || (n_children == null || n_children.length <= 0)
+ || (children.length != n_children.length ) )
+ return false;
+ //now both have children and the same number of children
+ for (int i= 0; i < children.length; i++) {
+ /* if the subtree rooted at children[i] is not equal to the subtree rooted at n_children[i],
+ * return false
+ */
+ if ( !((XMLNode)children[i]).subtreeEquals(n_children[i]) )
+ return false;
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLPlugin.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLPlugin.java
new file mode 100644
index 000000000..90de2894d
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLPlugin.java
@@ -0,0 +1,395 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+import org.eclipse.swt.widgets.*;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.jface.util.ListenerList;
+
+import org.eclipse.compare.CompareUI;
+import org.eclipse.core.runtime.*;
+
+/**
+ * This class is the plug-in runtime class for the
+ * <code>"org.eclipse.compare.xml"</code> plug-in.
+ * </p>
+ */
+public final class XMLPlugin extends AbstractUIPlugin {
+
+ private ListenerList fViewers;
+
+ public static final String PLUGIN_ID= "org.eclipse.compare.examples.xml"; //$NON-NLS-1$
+
+ private static final String ID_MAPPING_EXTENSION_POINT= "idMapping"; //$NON-NLS-1$
+ private static final String MAPPING_ELEMENT_NAME= "mapping"; //$NON-NLS-1$
+ private static final String IDMAP_NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
+ private static final String EXTENSION_NAME_ATTRIBUTE= "extension"; //$NON-NLS-1$
+ private static final String MAPPING_SIGNATURE_ATTRIBUTE= "signature"; //$NON-NLS-1$
+ private static final String MAPPING_ID_ATTRIBUTE= "id"; //$NON-NLS-1$
+ private static final String MAPPING_ID_SOURCE= "id-source"; //$NON-NLS-1$
+ private static final String MAPPING_ID_SOURCE_BODY= "body"; //$NON-NLS-1$
+ private static final String ORDERED_ELEMENT_NAME= "ordered"; //$NON-NLS-1$
+ private static final String ORDERED_SIGNATURE_ATTRIBUTE= "signature"; //$NON-NLS-1$
+
+ public static final String DEFAULT_PREFIX = "XML"; //$NON-NLS-1$
+ public static final String IMAGE_TYPE_PREFIX = "xml_"; //$NON-NLS-1$
+ public static final String IMAGE_TYPE_ORDERED_SUFFIX = "_ordered"; //$NON-NLS-1$
+ public static final String IDMAP_PREFERENCE_NAME = "idmap"; //$NON-NLS-1$
+ public static final String IDMAP_PREFIX = "idmap"; //$NON-NLS-1$
+ public static final char IDMAP_SEPARATOR = '*';
+ public static final char IDMAP_FIELDS_SEPARATOR = '!';
+
+ public static final String ORDERED_PREFERENCE_NAME = "ordered"; //$NON-NLS-1$
+ public static final char ORDERED_FIELDS_SEPARATOR = IDMAP_FIELDS_SEPARATOR;
+
+ private static XMLPlugin fgXMLPlugin;
+ private IPreferenceStore fPrefStore;
+
+ private HashMap fIdMapsInternal;
+ private HashMap fIdMaps;
+ private HashMap fIdExtensionToName;
+ private HashMap fOrderedElementsInternal;
+ private HashMap fOrderedElements;
+
+ /**
+ * Creates the <code>XMLPlugin</code> object and registers all
+ * structure creators, content merge viewers, and structure merge viewers
+ * contributed to this plug-in's extension points.
+ * <p>
+ * Note that instances of plug-in runtime classes are automatically created
+ * by the platform in the course of plug-in activation.
+ * </p>
+ *
+ * @param descriptor the plug-in descriptor
+ */
+ public XMLPlugin(IPluginDescriptor descriptor) {
+ super(descriptor);
+ fgXMLPlugin= this;
+ fViewers = new ListenerList();
+
+ CompareUI.removeAllStructureViewerAliases(DEFAULT_PREFIX);
+ initPrefStore();
+ CompareUI.registerImageDescriptor(IMAGE_TYPE_PREFIX + XMLStructureCreator.TYPE_ELEMENT, getImageDescriptor("obj16/element_obj.gif")); //$NON-NLS-1$
+ CompareUI.registerImageDescriptor(IMAGE_TYPE_PREFIX + XMLStructureCreator.TYPE_ATTRIBUTE, getImageDescriptor("obj16/attribute_obj.gif")); //$NON-NLS-1$
+ CompareUI.registerImageDescriptor(IMAGE_TYPE_PREFIX + XMLStructureCreator.TYPE_TEXT, getImageDescriptor("obj16/text_obj.gif")); //$NON-NLS-1$
+ CompareUI.registerImageDescriptor(IMAGE_TYPE_PREFIX + XMLStructureCreator.TYPE_ELEMENT + IMAGE_TYPE_ORDERED_SUFFIX, getImageDescriptor("obj16/element_ordered_obj.gif")); //$NON-NLS-1$
+ registerExtensions();
+ }
+
+ protected ImageDescriptor getImageDescriptor(String relativePath) {
+
+ URL installURL= getDescriptor().getInstallURL();
+ if (installURL != null) {
+ try {
+ URL url= new URL(installURL, "icons/full/" + relativePath); //$NON-NLS-1$
+ return ImageDescriptor.createFromURL(url);
+ } catch (MalformedURLException e) {
+ Assert.isTrue(false);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the singleton instance of this plug-in runtime class.
+ *
+ * @return the XMLPlugin instance
+ */
+ public static XMLPlugin getDefault() {
+ return fgXMLPlugin;
+ }
+
+ /**
+ * Reads the Preference Store associated with XMLPlugin and initializes ID Mappings.
+ */
+ public void initPrefStore() {
+ fIdMaps = new HashMap();
+ fIdExtensionToName= new HashMap();
+ fPrefStore = getPreferenceStore();
+ String IdMapPrefValue = fPrefStore.getString(IDMAP_PREFERENCE_NAME);
+ int start = 0;
+ int end = IdMapPrefValue.indexOf(IDMAP_SEPARATOR);
+ while (end >= 0) {
+ String CurrentIdMap = IdMapPrefValue.substring(start,end);
+ int end_of_IdMapName = CurrentIdMap.indexOf(IDMAP_FIELDS_SEPARATOR);
+ String IdMapName = CurrentIdMap.substring(0,end_of_IdMapName);
+ int end_of_signature = CurrentIdMap.indexOf(IDMAP_FIELDS_SEPARATOR,end_of_IdMapName+1);
+ String IdMapSignature = CurrentIdMap.substring(end_of_IdMapName+1,end_of_signature);
+ int end_of_attribute= CurrentIdMap.indexOf(IDMAP_FIELDS_SEPARATOR,end_of_signature+1);
+ String IdMapAttribute;
+ if (end_of_attribute < 0) {//for backward compatibility
+ IdMapAttribute = CurrentIdMap.substring(end_of_signature+1,CurrentIdMap.length());
+ } else {//normal case
+ IdMapAttribute = CurrentIdMap.substring(end_of_signature+1,end_of_attribute);
+ String IdMapExtension= CurrentIdMap.substring(end_of_attribute+1,CurrentIdMap.length());
+ //if extension already associated, do not associate with this idmap
+ if (!IdMapExtension.equals("") && !fIdExtensionToName.containsKey(IdMapExtension)) { //$NON-NLS-1$
+ fIdExtensionToName.put(IdMapExtension,IdMapName);
+ CompareUI.addStructureViewerAlias(DEFAULT_PREFIX, IdMapExtension);
+ }
+ }
+
+ if (fIdMaps.containsKey(IdMapName)) {
+ HashMap Mappings = (HashMap) fIdMaps.get(IdMapName);
+ Mappings.put(IdMapSignature,IdMapAttribute);
+ } else {
+ HashMap Mappings = new HashMap();
+ Mappings.put(IdMapSignature,IdMapAttribute);
+ fIdMaps.put(IdMapName,Mappings);
+ }
+ start = end+1;
+ end = IdMapPrefValue.indexOf(IDMAP_SEPARATOR,end+1);
+ }
+
+ fOrderedElements= new HashMap();
+ String OrderedPrefValue= fPrefStore.getString(ORDERED_PREFERENCE_NAME);
+ StringTokenizer orderedTokens= new StringTokenizer(OrderedPrefValue, (new Character(ORDERED_FIELDS_SEPARATOR)).toString());
+ while (orderedTokens.hasMoreTokens()) {
+ String IdMapName= orderedTokens.nextToken();
+ String signature= orderedTokens.nextToken();
+ if (fOrderedElements.containsKey(IdMapName)) {
+ ArrayList idmapAL= (ArrayList) fOrderedElements.get(IdMapName);
+ idmapAL.add(signature);
+ } else {
+ ArrayList idmapAL= new ArrayList();
+ idmapAL.add(signature);
+ fOrderedElements.put(IdMapName, idmapAL);
+ }
+ }
+
+ }
+
+ /**
+ * Updates the user Id Mappings, the IdExtensionToName mappings and refreshes the preference store.
+ * @param IdMap the new Id Mappings
+ * @param IdExtensionToName the new IdExtensionToName mappings
+ * @param refresh whether all the open StructureViewers should be refreshed with the new IdMapping settings
+ */
+ public void setIdMaps(HashMap IdMap, HashMap IdExtensionToName, HashMap OrderedElements, boolean refresh) {
+ fIdMaps = IdMap;
+ if (IdExtensionToName != null && !IdExtensionToName.equals(fIdExtensionToName)) {
+ CompareUI.removeAllStructureViewerAliases(DEFAULT_PREFIX);
+ fIdExtensionToName= IdExtensionToName;
+ Set newkeySet= fIdExtensionToName.keySet();
+ for (Iterator iter= newkeySet.iterator(); iter.hasNext(); ) {
+ String extension= (String)iter.next();
+ CompareUI.addStructureViewerAlias(DEFAULT_PREFIX, extension);
+ }
+ }
+ StringBuffer IdMapPrefValue = new StringBuffer();
+ Set idmapKeys = fIdMaps.keySet();
+ for (Iterator iter_idmap = idmapKeys.iterator(); iter_idmap.hasNext(); ) {
+ String IdMapName = (String) iter_idmap.next();
+ HashMap idmapHM = (HashMap) fIdMaps.get(IdMapName);
+ Set mappingKeys = idmapHM.keySet();
+ String extension= ""; //$NON-NLS-1$
+ if (fIdExtensionToName.containsValue(IdMapName)) {
+ Set keySet= fIdExtensionToName.keySet();
+ for (Iterator iter= keySet.iterator(); iter.hasNext(); ) {
+ extension= (String)iter.next();
+ if ( ((String)fIdExtensionToName.get(extension)).equals(IdMapName) )
+ break;
+ }
+ }
+ for (Iterator iter_mapping = mappingKeys.iterator(); iter_mapping.hasNext(); ) {
+ String signature = (String) iter_mapping.next();
+ IdMapPrefValue.append(IdMapName+IDMAP_FIELDS_SEPARATOR+signature+IDMAP_FIELDS_SEPARATOR+idmapHM.get(signature)+IDMAP_FIELDS_SEPARATOR+extension+IDMAP_SEPARATOR);
+ }
+ }
+ fPrefStore.setValue(IDMAP_PREFERENCE_NAME,IdMapPrefValue.toString());
+ //fPrefStore.setValue(IDMAP_PREFERENCE_NAME,"");
+
+ //stores OrderedElements
+ if (OrderedElements != null) {
+ fOrderedElements= OrderedElements;
+ StringBuffer OrderedPrefValue= new StringBuffer();
+ Set orderedKeys= fOrderedElements.keySet();
+ for (Iterator iter_ordered= orderedKeys.iterator(); iter_ordered.hasNext();) {
+ String IdMapName= (String) iter_ordered.next();
+ ArrayList idmapAL= (ArrayList) fOrderedElements.get(IdMapName);
+ for (Iterator iter_idmapAL= idmapAL.iterator(); iter_idmapAL.hasNext();) {
+ String signature= (String) iter_idmapAL.next();
+ OrderedPrefValue.append(IdMapName+ORDERED_FIELDS_SEPARATOR+signature+ORDERED_FIELDS_SEPARATOR);
+ }
+ }
+ fPrefStore.setValue(ORDERED_PREFERENCE_NAME,OrderedPrefValue.toString());
+ //fPrefStore.setValue(ORDERED_PREFERENCE_NAME,"");
+ }
+
+ if (refresh) {
+ Object[] viewers = fViewers.getListeners();
+ for (int i = 0; i < viewers.length; ++i) {
+ XMLStructureViewer viewer = (XMLStructureViewer) viewers[i];
+ viewer.updateIdMaps();
+ viewer.contentChanged();
+ }
+ }
+ }
+
+ public HashMap getIdMaps() {
+ return fIdMaps;
+ }
+
+ public HashMap getIdMapsInternal() {
+ return fIdMapsInternal;
+ }
+
+ public HashMap getIdExtensionToName() {
+ return fIdExtensionToName;
+ }
+
+ public HashMap getOrderedElements() {
+ return fOrderedElements;
+ }
+
+ public HashMap getOrderedElementsInternal() {
+ return fOrderedElementsInternal;
+ }
+
+ /**
+ * Registers all internal Id Mapping schemes
+ * that are found in plugin.xml files.
+ */
+ private void registerExtensions() {
+ IPluginRegistry registry= Platform.getPluginRegistry();
+
+ // collect all Id Mappings
+ IConfigurationElement[] idmaps= registry.getConfigurationElementsFor(PLUGIN_ID, ID_MAPPING_EXTENSION_POINT);
+ fIdMapsInternal = new HashMap();
+ fOrderedElementsInternal= new HashMap();
+ for (int i_idmap= 0; i_idmap < idmaps.length; i_idmap++) {
+ final IConfigurationElement idmap= idmaps[i_idmap];
+ //handle IDMAP_NAME_ATTRIBUTE
+ String idmap_name= idmap.getAttribute(IDMAP_NAME_ATTRIBUTE);
+ //ignores idmap if its name equals the reserved name for unordered matching or the the name for ordered matching
+ if ( !idmap_name.equals(XMLStructureCreator.USE_UNORDERED) && !idmap_name.equals(XMLStructureCreator.USE_ORDERED) ) {
+ //handle mappings
+ HashMap idmapHM = new HashMap();
+ fIdMapsInternal.put(idmap_name, idmapHM);
+ IConfigurationElement[] mappings = idmap.getChildren(MAPPING_ELEMENT_NAME);
+ for (int i_mapping= 0; i_mapping < mappings.length; i_mapping++) {
+ IConfigurationElement mapping = mappings[i_mapping];
+ //add SIGN_SEPARATOR at the end because not contained in signatures of plugin.xml
+ //also add prefix at beginning
+ String signature= mapping.getAttribute(MAPPING_SIGNATURE_ATTRIBUTE);
+ String attribute= mapping.getAttribute(MAPPING_ID_ATTRIBUTE);
+ String idsource= mapping.getAttribute(MAPPING_ID_SOURCE);
+ String bodyid= ""; //$NON-NLS-1$
+ if (signature != null && !signature.equals("") //$NON-NLS-1$
+ && attribute != null && !attribute.equals("")) { //$NON-NLS-1$
+ if (idsource != null && idsource.equals(MAPPING_ID_SOURCE_BODY))
+ bodyid= (new Character(XMLStructureCreator.ID_TYPE_BODY)).toString();
+ idmapHM.put(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR
+ + signature + XMLStructureCreator.SIGN_SEPARATOR, bodyid + attribute);
+ }
+ }
+ //handles ordered entries
+ IConfigurationElement[] orderedEntries= idmap.getChildren(ORDERED_ELEMENT_NAME);
+ if (orderedEntries.length > 0) {
+ ArrayList orderedAL= new ArrayList();
+ for (int i_ordered= 0; i_ordered < orderedEntries.length; i_ordered++) {
+ IConfigurationElement ordered= orderedEntries[i_ordered];
+ //add SIGN_SEPARATOR at the end because not contained in signatures of plugin.xml
+ //also add prefix at beginning
+ String signature= ordered.getAttribute(ORDERED_SIGNATURE_ATTRIBUTE);
+ if (signature != null && !signature.equals("")) //$NON-NLS-1$
+ orderedAL.add(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + signature + XMLStructureCreator.SIGN_SEPARATOR);
+ }
+ if (orderedAL.size() > 0)
+ fOrderedElementsInternal.put(idmap_name, orderedAL);
+ }
+ //handle EXTENSION_NAME_ATTRIBUTE
+ String ext_name= idmap.getAttribute(EXTENSION_NAME_ATTRIBUTE);
+ if (ext_name != null && !fIdExtensionToName.containsKey(ext_name)) {
+ ext_name= ext_name.toLowerCase();
+ fIdExtensionToName.put(ext_name,idmap_name);
+ CompareUI.addStructureViewerAlias(DEFAULT_PREFIX, ext_name);
+ }
+ }
+ }
+ }
+
+ public ListenerList getViewers() {
+ return fViewers;
+ }
+
+ public static Shell getActiveWorkbenchShell() {
+ IWorkbenchWindow window= getActiveWorkbenchWindow();
+ if (window != null)
+ return window.getShell();
+ return null;
+ }
+
+ public static IWorkbenchWindow getActiveWorkbenchWindow() {
+ IWorkbenchWindow window= fgXMLPlugin.getWorkbench().getActiveWorkbenchWindow();
+ if (window == null) {
+ final WindowRef windowRef= new WindowRef();
+ Display.getDefault().syncExec(new Runnable() {
+ public void run() {
+ setActiveWorkbenchWindow(windowRef);
+ }
+ });
+ return windowRef.window;
+ }
+ else
+ return window;
+ }
+
+ private static class WindowRef {
+ public IWorkbenchWindow window;
+ }
+
+ private static void setActiveWorkbenchWindow(WindowRef windowRef) {
+ windowRef.window= null;
+ Display display= Display.getCurrent();
+ if (display == null)
+ return;
+ Control shell= display.getActiveShell();
+ while (shell != null) {
+ Object data= shell.getData();
+ if (data instanceof IWorkbenchWindow) {
+ windowRef.window= (IWorkbenchWindow)data;
+ return;
+ }
+ shell= shell.getParent();
+ }
+ Shell shells[]= display.getShells();
+ for (int i= 0; i < shells.length; i++) {
+ Object data= shells[i].getData();
+ if (data instanceof IWorkbenchWindow) {
+ windowRef.window= (IWorkbenchWindow)data;
+ return;
+ }
+ }
+ }
+
+ public static void log(Throwable e) {
+ log(new Status(IStatus.ERROR, getPluginId(), IStatus.ERROR, "Internal Error", e)); //$NON-NLS-1$
+ }
+
+ public static void log(IStatus status) {
+ getDefault().getLog().log(status);
+ }
+
+ public static String getPluginId() {
+ return getDefault().getDescriptor().getUniqueIdentifier();
+ }
+
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureCreator.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureCreator.java
new file mode 100644
index 000000000..26ad0beac
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureCreator.java
@@ -0,0 +1,728 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import org.apache.xerces.parsers.SAXParser;
+import org.eclipse.compare.IEditableContent;
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.structuremergeviewer.Differencer;
+import org.eclipse.compare.structuremergeviewer.IDiffContainer;
+import org.eclipse.compare.structuremergeviewer.IStructureComparator;
+import org.eclipse.compare.structuremergeviewer.IStructureCreator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.Position;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.LocatorImpl;
+
+/**
+ * This structure analyzer builds a parse tree of an XML document found in
+ * a <code>IByteContentAccessor</code> input by calling getStructure(Object)
+ */
+public class XMLStructureCreator implements IStructureCreator {
+
+ protected static final boolean DEBUG_MODE = false;
+
+ private XMLNode fcurrentParent;
+ private String fsignature;
+ private Document fdoc;
+ private boolean ignoreBodies = false;
+ //private String fName;
+
+ public static final String DEFAULT_NAME = XMLCompareMessages.getString("XMLStructureCreator.pluginname"); //$NON-NLS-1$
+
+ private HashMap fIdMapsInternal;
+ private HashMap fIdMaps;
+ private HashMap fIdExtensionToName;
+ private HashMap fOrderedElementsInternal;
+ private HashMap fOrderedElements;
+ private HashMap idMap;
+ private ArrayList fOrdered;
+
+ public static final String USE_UNORDERED = XMLCompareMessages.getString("XMLStructureCreator.unordered"); //$NON-NLS-1$
+ public static final String USE_ORDERED = XMLCompareMessages.getString("XMLStructureCreator.ordered"); //$NON-NLS-1$
+ public static final String DEFAULT_IDMAP= USE_ORDERED;
+ private String fIdMapToUse;
+ private boolean fUseIdMap;
+
+ public static final String TYPE_ELEMENT = "element"; //$NON-NLS-1$
+ public static final String TYPE_TEXT = "text"; //$NON-NLS-1$
+ public static final String TYPE_ATTRIBUTE = "attribute"; //$NON-NLS-1$
+
+ //for signatures
+ public static final String ROOT_ID = "root"; //$NON-NLS-1$
+ public static final char SIGN_SEPARATOR = '>';//'.'
+ public static final char SIGN_ENCLOSING = '$';
+ public static final String SIGN_ELEMENT = SIGN_ENCLOSING + TYPE_ELEMENT + SIGN_ENCLOSING;
+ public static final String SIGN_TEXT = SIGN_ENCLOSING + TYPE_TEXT + SIGN_ENCLOSING;
+ public static final String SIGN_ATTRIBUTE = SIGN_ENCLOSING + TYPE_ATTRIBUTE + SIGN_ENCLOSING;
+
+ public static final String IDMAP_UNORDERED = XMLCompareMessages.getString("XMLStructureCreator.idmap_unordered"); //$NON-NLS-1$
+
+ public static final char ID_SEPARATOR = '<';
+ public static final char ID_TYPE_BODY = '<';
+
+ private static final String parserName = "org.apache.xerces.parsers.SAXParser"; //$NON-NLS-1$
+
+ private static boolean setValidation = false; //defaults
+ private static boolean setNameSpaces = true;
+ private static boolean setSchemaSupport = true;
+ private static boolean setSchemaFullSupport = false;
+
+ private String fFileExt;
+ private boolean fFirstCall = true;
+
+ private boolean fRemoveWhiteSpace;
+
+ protected class XMLHandler extends DefaultHandler {
+
+ protected Locator prevlocator; //previous locator
+ protected Locator locator; //current locator
+
+ public void setDocumentLocator (Locator locator0) {
+ this.locator = locator0;
+ }
+
+ //
+ // DocumentHandler methods
+ //
+ /** Processing instruction. */
+ public void processingInstruction(String target, String data) {
+
+// System.out.println("target: " + target);
+// System.out.println("data: " + data);
+// System.out.print("<?");
+// System.out.print(target);
+// if (data != null && data.length() > 0) {
+// System.out.print(' ');
+// System.out.print(data);
+// }
+// System.out.print("?>");
+// System.out.flush();
+ prevlocator = new LocatorImpl(locator);
+ } // processingInstruction(String,String)
+
+ /** Start document. */
+ public void startDocument() {
+
+ prevlocator = new LocatorImpl(locator);
+
+ } // startDocument()
+
+ /** Start element. */
+ public void startElement(String uri, String local, String raw,
+ Attributes attrs) {
+ XMLNode currentElement;
+
+ /* add root node for this element */
+
+ if (XMLStructureCreator.DEBUG_MODE) {
+ if (locator != null && prevlocator != null) {
+ System.out.println("prevlocator: line " + prevlocator.getLineNumber() + " column " + prevlocator.getColumnNumber() + " id " + prevlocator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ System.out.println("locator: line " + locator.getLineNumber() + " column " + locator.getColumnNumber() + " id " + locator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+
+ try {
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Node where children field accessed: " + fcurrentParent.getId()); //$NON-NLS-1$
+ XMLChildren currentParent = (XMLChildren) fcurrentParent;
+ currentParent.children++;
+ String elementId;
+ String elementName;
+ IRegion r= fdoc.getLineInformation(prevlocator.getLineNumber()-1);
+
+ String parentSig= fsignature;
+ fsignature = fsignature + raw + SIGN_SEPARATOR;
+
+ if ( isUseIdMap() && idMap.containsKey(fsignature) ) {
+ String attrName = (String)idMap.get(fsignature);
+ elementId = raw + new Character(ID_SEPARATOR) + attrs.getValue(attrName);
+ elementName = raw + " [" + attrName + "=" + attrs.getValue(attrName) + "]"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ } else {
+ if ( !currentParent.childElements.containsKey(raw) ) {
+ currentParent.childElements.put(raw,new Integer(1));
+ } else {
+ currentParent.childElements.put(raw,new Integer(((Integer)currentParent.childElements.get(raw)).intValue()+1));
+ }
+ elementId = raw+new Character(ID_SEPARATOR)+"["+currentParent.childElements.get(raw)+"]"; //$NON-NLS-2$ //$NON-NLS-1$
+ elementName = MessageFormat.format("{0} [{1}]",new String[] {raw,currentParent.childElements.get(raw).toString()}); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ currentElement = new XMLChildren(TYPE_ELEMENT,elementId,elementId,(fsignature+SIGN_ELEMENT),fdoc,r.getOffset()+prevlocator.getColumnNumber()-1,0);
+ currentElement.setName(elementName);
+ if ( isUseIdMap() && idMap.containsKey(fsignature))
+ currentElement.setUsesIDMAP(true);
+ if (fOrdered != null && fOrdered.contains(parentSig))
+ currentElement.setIsOrderedChild(true);
+
+ fcurrentParent.addChild(currentElement);
+ currentElement.setParent(fcurrentParent);
+ fcurrentParent = currentElement;
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("\nAdded Element " + raw + " with offset " + r.getOffset()); //$NON-NLS-2$ //$NON-NLS-1$
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("fcurrentParent1: " + fcurrentParent.getId()); //$NON-NLS-1$
+
+ if (attrs != null) {
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("attrs != null, fcurrentParent is " + fcurrentParent.getId()); //$NON-NLS-1$
+ //attrs = sortAttributes(attrs);
+ int len = attrs.getLength();
+ int element_lines_length_size;
+ int[] element_lines_length;
+ int column_offset;
+ String element_string;
+ if (fcurrentParent.getParent().getId().equals(ROOT_ID)) {
+ element_lines_length_size = locator.getLineNumber()-prevlocator.getLineNumber();
+ element_lines_length = new int[element_lines_length_size];
+ column_offset = 0;
+ element_string = ""; //$NON-NLS-1$
+ for (int i_ell=0; i_ell<element_lines_length.length; i_ell++) {
+ IRegion attr_r = fdoc.getLineInformation(i_ell+prevlocator.getLineNumber());
+ element_lines_length[i_ell] = fdoc.get(attr_r.getOffset(), attr_r.getLength()).length()+1;
+ element_string = element_string + fdoc.get(attr_r.getOffset(), attr_r.getLength()) + " "; //$NON-NLS-1$
+ }
+ } else {
+ element_lines_length_size = locator.getLineNumber()-prevlocator.getLineNumber()+1;
+ //if (element_lines_length_size < 1) element_lines_length_size = 1;
+ element_lines_length = new int[element_lines_length_size];
+ IRegion first_line = fdoc.getLineInformation(prevlocator.getLineNumber()-1);
+ column_offset = prevlocator.getColumnNumber()-1;
+ int first_line_relevant_offset = first_line.getOffset()+column_offset;
+ int first_line_relevant_length = first_line.getLength()-column_offset;
+ element_string = fdoc.get(first_line_relevant_offset, first_line_relevant_length) + " "; //$NON-NLS-1$
+ element_lines_length[0] = element_string.length();
+ for (int i_ell=1; i_ell<element_lines_length.length; i_ell++) {
+ IRegion attr_r = fdoc.getLineInformation(i_ell+prevlocator.getLineNumber()-1);
+ element_lines_length[i_ell] = fdoc.get(attr_r.getOffset(), attr_r.getLength()).length()+1;
+ element_string = element_string + fdoc.get(attr_r.getOffset(), attr_r.getLength()) + " "; //$NON-NLS-1$
+ }
+ }
+
+ for (int i_attr = 0; i_attr < len; i_attr++) {
+ String attr_name = attrs.getQName(i_attr);
+ String attr_value = attrs.getValue(i_attr);
+
+ /* find range of attribute in doc; manually parses the line */
+ boolean found = false;
+ int first_quotes = -1;
+ int second_quotes = -1;
+ int id_index = -1;
+ while (!found) {
+ first_quotes = element_string.indexOf("\"",second_quotes+1); //$NON-NLS-1$
+ second_quotes = element_string.indexOf("\"",first_quotes+1); //$NON-NLS-1$
+ String value;
+ try {
+ value = element_string.substring(first_quotes+1,second_quotes);
+ } catch (Exception e) {
+ value = ""; //$NON-NLS-1$
+ }
+ if (value.equals("")) //$NON-NLS-1$
+ found = true;
+ else if (value.equals(attr_value)) {
+ id_index = element_string.lastIndexOf(attr_name,first_quotes-1);
+ boolean wrong = false;
+ boolean found_equal = false;
+ for (int i_char=id_index+attr_name.length(); i_char<first_quotes && !wrong; i_char++) {
+ if (element_string.charAt(i_char) == '=')
+ if (!found_equal)
+ found_equal = true;
+ else
+ wrong = true;
+ else if (!Character.isWhitespace(element_string.charAt(i_char)))
+ wrong = true;
+ }
+ if (!wrong) found = true;
+ }
+ }
+ //id_index has one char missing for every line (the final cr)
+ int line_of_index = 0;
+ for (line_of_index = 0; id_index > element_lines_length[line_of_index]-1; line_of_index++)
+ id_index -= (element_lines_length[line_of_index]);
+ if (line_of_index == 0) id_index += column_offset;
+ if (fcurrentParent.getParent().getId().equals(ROOT_ID))
+ line_of_index += prevlocator.getLineNumber();
+ else
+ line_of_index += prevlocator.getLineNumber()-1;
+ //index at line line_of_index, line offset id_index
+ int line_of_end_of_value = 0;
+ int end_of_value_index = second_quotes;
+ for (line_of_end_of_value = 0; end_of_value_index > element_lines_length[line_of_end_of_value]-1; line_of_end_of_value++)
+ end_of_value_index -= (element_lines_length[line_of_end_of_value]);
+ if (line_of_end_of_value == 0) end_of_value_index += column_offset;
+ if (fcurrentParent.getParent().getId().equals(ROOT_ID))
+ line_of_end_of_value += prevlocator.getLineNumber();
+ else
+ line_of_end_of_value += prevlocator.getLineNumber()-1;
+ //end of value at line line_of_end_of_value, line offset end_of_value_index
+
+ int attr_start_doc_offset = fdoc.getLineInformation(line_of_index).getOffset()+id_index;
+ //int attr_length_doc_offset = fdoc.getLineInformation(line_of_value).getOffset()+value_index+attr_value.length()+1+(line_of_end_of_value-line_of_index) - attr_start_doc_offset;
+ int attr_length_doc_offset = fdoc.getLineInformation(line_of_end_of_value).getOffset()+end_of_value_index +1 - attr_start_doc_offset;
+ currentElement = new XMLNode(TYPE_ATTRIBUTE,attr_name,attr_value,(fsignature+attr_name+SIGN_SEPARATOR+SIGN_ATTRIBUTE),fdoc,attr_start_doc_offset,attr_length_doc_offset);
+ currentElement.setName(attr_name);
+ fcurrentParent.addChild(currentElement);
+ currentElement.setParent(fcurrentParent);
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("added attribute " + currentElement.getId() + " with value >" + currentElement.getValue() + "<" + " to element " + fcurrentParent.getId() + " which has parent " + fcurrentParent.getParent().getId()); //$NON-NLS-5$ //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+ } catch (BadLocationException ex) {
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("BadLocationException in startElement(...) " + ex); //$NON-NLS-1$
+ currentElement = new XMLChildren(TYPE_ELEMENT,raw+"_("+((XMLChildren)fcurrentParent).children+")",raw+"_("+((XMLChildren)fcurrentParent).children+")",(fsignature+SIGN_ELEMENT),fdoc,0,0); //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("At the end of startElement(...), fcurrentParent is " + fcurrentParent.getId()); //$NON-NLS-1$
+ prevlocator = new LocatorImpl(locator);
+ } // startElement(String,String,String,Attributes)
+
+ /** Characters. */
+ public void characters(char ch[], int start, int length) {
+ if (!ignoreBodies) {
+// String chars = (new String(ch, start, length)).trim();
+ String chars= new String(ch, start, length);
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("characters: >" + chars + "<"); //$NON-NLS-2$ //$NON-NLS-1$
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Body Location: line " + locator.getLineNumber() + " column " + locator.getColumnNumber()); //$NON-NLS-2$ //$NON-NLS-1$
+
+ //if text contains only white space, it will be ignored.
+ if (!trimWhiteSpace(chars).equals("")) { //$NON-NLS-1$
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Adding body"); //$NON-NLS-1$
+ try {
+ IRegion r= fdoc.getLineInformation(locator.getLineNumber()-1);
+ //location returns the END of the characters
+ //offset of BEGINNING of characters:
+ int offset = r.getOffset()+locator.getColumnNumber()-1-length;
+ fcurrentParent.bodies++;
+ String body_value = new String(ch, start, length);
+ if (fRemoveWhiteSpace) {
+ body_value= removeWhiteSpace(body_value);
+ }
+ XMLNode bodynode = new XMLNode(TYPE_TEXT,"body_("+fcurrentParent.bodies+")",body_value,(fsignature+SIGN_TEXT),fdoc,offset,length); //$NON-NLS-2$ //$NON-NLS-1$
+ bodynode.setName(MessageFormat.format("{0} ({1})",new String[] {XMLCompareMessages.getString("XMLStructureCreator.body"),Integer.toString(fcurrentParent.bodies)})); //$NON-NLS-2$ //$NON-NLS-1$
+ fcurrentParent.addChild(bodynode);
+ bodynode.setParent(fcurrentParent);
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Created body " + fcurrentParent.bodies //$NON-NLS-1$
+ + " with offset " + offset + " and length " + length //$NON-NLS-2$ //$NON-NLS-1$
+ + " with parent " + bodynode.getParent().getId()); //$NON-NLS-1$
+ //bodies as id attributes
+ String popsig = fcurrentParent.getParent().getSignature(); //signature of parent of parent
+ popsig = popsig.substring(0,popsig.lastIndexOf(SIGN_ELEMENT));
+ if (isUseIdMap() && fcurrentParent.bodies == 1 && idMap.containsKey(popsig)) {
+ String pid= fcurrentParent.getId();//id of parent
+ String pelementname= pid.substring(0,pid.indexOf("<"));//name of parent element //$NON-NLS-1$
+ if ( ((String)idMap.get(popsig)).equals(ID_TYPE_BODY+pelementname) ) {
+ XMLNode pop= fcurrentParent.getParent();
+ String popid= pop.getId();
+ String popelementname= popid.substring(0,popid.indexOf("<")); //$NON-NLS-1$
+ pop.setId(popelementname + "<" + body_value); //$NON-NLS-1$
+ pop.setOrigId(popelementname + "<" + body_value); //$NON-NLS-1$
+ pop.setName(MessageFormat.format("{0} [{1}={2}]",new String[] {popelementname, pelementname, body_value})); //$NON-NLS-1$
+ pop.setUsesIDMAP(true);
+ }
+ }
+ } catch (BadLocationException ex) {
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("BadLocationException in characters(...) " + ex); //$NON-NLS-1$
+ fcurrentParent.addChild(new XMLNode(TYPE_TEXT,"body_("+fcurrentParent.bodies+")",new String(ch, start, length),(fsignature+SIGN_TEXT),fdoc,0,0)); //$NON-NLS-2$ //$NON-NLS-1$
+ }
+ }
+ }
+ prevlocator = new LocatorImpl(locator);
+ } // characters(char[],int,int);
+
+ /** Ignorable whitespace. */
+ public void ignorableWhitespace(char ch[], int start, int length) {
+//
+//// characters(ch, start, length);
+//// System.out.flush();
+//
+ prevlocator = new LocatorImpl(locator);
+ } // ignorableWhitespace(char[],int,int);
+
+ /** End element. */
+ public void endElement(String uri, String local, String raw) {
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("\nExiting element " + fcurrentParent.getId()); //$NON-NLS-1$
+
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("prevlocator: line " + prevlocator.getLineNumber() + " column " + prevlocator.getColumnNumber() + " id " + prevlocator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("locator: line " + locator.getLineNumber() + " column " + locator.getColumnNumber() + " id " + locator.getPublicId()); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+
+ if (fcurrentParent.getParent() != null) {
+ try {
+ IRegion r2= fdoc.getLineInformation(locator.getLineNumber()-1);
+ Position pos = fcurrentParent.getRange();
+
+ int elem_length = r2.getOffset()+locator.getColumnNumber()-1 - pos.getOffset();//length of element from start tag to end tag
+ fcurrentParent.setLength(elem_length);
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("pos.getOffset: " + pos.getOffset() + " elem_length: " + elem_length); //$NON-NLS-2$ //$NON-NLS-1$
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("fdoc.get(pos.getOffset()+elem_length-5,4): >" + fdoc.get(pos.getOffset()+elem_length-5,4) + "<"); //$NON-NLS-2$ //$NON-NLS-1$
+ //if (fdoc.get(pos.getOffset()+elem_length-2,1) != ">") elem_length-=1;
+ try {
+ fcurrentParent.setValue(fdoc.get(pos.getOffset(),elem_length));
+ } catch (BadLocationException ex) {
+ try {
+ fcurrentParent.setValue(fdoc.get(pos.getOffset(),elem_length-1));
+ } catch (BadLocationException ex2) {
+ if (XMLStructureCreator.DEBUG_MODE) {
+ System.out.println("BadLocationException in endElement(...) while attempting fcurrentParent.setValue(...): " + ex); //$NON-NLS-1$
+ System.out.println("Attempt to correct BadLocationException failed: " + ex2); //$NON-NLS-1$
+ }
+ }
+ }
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Value of " + fcurrentParent.getId() + " is >" + fcurrentParent.getValue() + "<"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+ //going from ending element to parent element
+ fcurrentParent = fcurrentParent.getParent();
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("fcurrentParent = fcurrentParent.getParent();"); //$NON-NLS-1$
+ } catch (BadLocationException ex) {
+ if (XMLStructureCreator.DEBUG_MODE) {
+ System.out.println("BadLocationException in endElement(...): " + ex); //$NON-NLS-1$
+ System.out.println("fcurrentParent.getId(): " + fcurrentParent.getId()); //$NON-NLS-1$
+ }
+ }
+ } else {
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Error: Cannot reach Parent of Parent"); //$NON-NLS-1$
+ }
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("fcurrentParent is now " + fcurrentParent.getId()); //$NON-NLS-1$
+
+ prevlocator = new LocatorImpl(locator);
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Signature before cutting: " + fsignature); //$NON-NLS-1$
+ int ssi = fsignature.lastIndexOf(SIGN_SEPARATOR);//fsignature separator index
+ ssi = fsignature.lastIndexOf(SIGN_SEPARATOR,ssi-1);//second-last ".", e.g. in root.a.b. to obtain root.a.
+ fsignature = fsignature.substring(0,ssi+1);
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Signature after cutting: " + fsignature); //$NON-NLS-1$
+ } // endElement(String)
+
+ //
+ // ErrorHandler methods
+ //
+
+ /** Warning. */
+ public void warning(SAXParseException ex) {
+ System.err.println("[Warning] "+ //$NON-NLS-1$
+ getLocationString(ex)+": "+ //$NON-NLS-1$
+ ex.getMessage());
+ }
+
+ /** Error. */
+ public void error(SAXParseException ex) {
+ System.err.println("[Error] "+ //$NON-NLS-1$
+ getLocationString(ex)+": "+ //$NON-NLS-1$
+ ex.getMessage());
+ }
+
+ /** Fatal error. */
+ public void fatalError(SAXParseException ex) throws SAXException {
+ System.err.println("[Fatal Error] "+ //$NON-NLS-1$
+ getLocationString(ex)+": "+ //$NON-NLS-1$
+ ex.getMessage());
+ //System.out.println(ex);
+ //throw ex;
+ }
+
+ /** Returns a string of the location. */
+ private String getLocationString(SAXParseException ex) {
+ StringBuffer str = new StringBuffer();
+
+ String systemId = ex.getSystemId();
+ if (systemId != null) {
+ int index = systemId.lastIndexOf('/');
+ if (index != -1)
+ systemId = systemId.substring(index + 1);
+ str.append(systemId);
+ }
+ str.append(':');
+ str.append(ex.getLineNumber());
+ str.append(':');
+ str.append(ex.getColumnNumber());
+
+ return str.toString();
+
+ } // getLocationString(SAXParseException):String
+
+ };
+
+ public XMLStructureCreator() {
+ //set default idmap
+ fIdMapToUse= DEFAULT_IDMAP;
+ fUseIdMap= false;
+ XMLPlugin plugin= XMLPlugin.getDefault();
+ //if statement required for tests
+ if (plugin != null) {
+ fIdMaps = plugin.getIdMaps();
+ fIdMapsInternal = plugin.getIdMapsInternal();
+ fIdExtensionToName = plugin.getIdExtensionToName();
+ fOrderedElements= plugin.getOrderedElements();
+ fOrderedElementsInternal= plugin.getOrderedElementsInternal();
+ }
+ fRemoveWhiteSpace= false;
+ }
+
+// public void setNameScheme(String idmap_name) {
+// fName = MessageFormat.format("{0} ({1})", new String[] {DEFAULT_NAME,idmap_name}); //$NON-NLS-1$
+// }
+//
+ /**
+ * This title will be shown in the title bar of the structure compare pane.
+ */
+ public String getName() {
+ return DEFAULT_NAME;
+ }
+
+ /**
+ * Set File extension of the parsed file. This extension will be used to choose an Id Map scheme.
+ */
+ public void setFileExtension(String ext) {
+ fFileExt= ext;
+ }
+
+ /**
+ * Initialize the Id Mappings for the Id Mapping Scheme and the Ordered Elements
+ * This method must be called before getStructure(Object) is called on the two/three inputs of the compare
+ */
+ public void initIdMaps() {
+ if (fFirstCall && fFileExt != null) {
+ fFirstCall = false;
+ String fileExtLower= fFileExt.toLowerCase();
+ if (fIdExtensionToName.containsKey(fileExtLower))
+ setIdMap((String)fIdExtensionToName.get(fileExtLower));
+ }
+
+ setUseIdMap();
+ fOrdered= null;
+ if (!isUseIdMap())
+ idMap = null;
+ else if (fIdMaps.containsKey(fIdMapToUse)) {
+ idMap = (HashMap) fIdMaps.get(fIdMapToUse);
+ } else if (fIdMapsInternal.containsKey(fIdMapToUse)) {
+ idMap = (HashMap) fIdMapsInternal.get(fIdMapToUse);
+ }
+
+ if (fOrderedElements != null)
+ fOrdered= (ArrayList) fOrderedElements.get(fIdMapToUse);
+ if (fOrdered == null && fOrderedElementsInternal != null)
+ fOrdered= (ArrayList) fOrderedElementsInternal.get(fIdMapToUse);
+ }
+
+ /**
+ * Returns the XML parse tree of the input.
+ */
+ public IStructureComparator getStructure(Object input) {
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("Starting parse"); //$NON-NLS-1$
+
+ if (!(input instanceof IStreamContentAccessor))
+ return null;
+
+ IStreamContentAccessor sca= (IStreamContentAccessor) input;
+
+ try {
+
+ //Input parsed with parser.parse(new InputSource(sca.getContents));
+ String contents= readString(sca.getContents());
+ if (contents == null)
+ contents= ""; //$NON-NLS-1$
+
+ fdoc= new Document(contents);
+ fsignature = ROOT_ID + SIGN_SEPARATOR;
+ XMLChildren root= new XMLChildren(TYPE_ELEMENT,ROOT_ID, "",(fsignature+SIGN_ELEMENT), fdoc, 0, fdoc.getLength()); //$NON-NLS-1$
+ fcurrentParent = root;
+
+ XMLHandler handler = new XMLHandler();
+
+ try {
+ SAXParser parser = (SAXParser)Class.forName(parserName).newInstance();
+
+ parser.setFeature( "http://xml.org/sax/features/validation",setValidation); //$NON-NLS-1$
+ parser.setFeature( "http://xml.org/sax/features/namespaces",setNameSpaces ); //$NON-NLS-1$
+ parser.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false); //$NON-NLS-1$
+ parser.setFeature( "http://apache.org/xml/features/validation/schema",setSchemaSupport ); //$NON-NLS-1$
+ parser.setFeature( "http://apache.org/xml/features/validation/schema-full-checking",setSchemaFullSupport ); //$NON-NLS-1$
+
+ parser.setContentHandler(handler);
+ parser.setErrorHandler(handler);
+
+ parser.parse(new InputSource(sca.getContents()));
+ if (XMLStructureCreator.DEBUG_MODE) System.out.println("End of parse"); //$NON-NLS-1$
+ } catch (SAXParseException e) {
+ XMLPlugin.log(e);
+ return null;
+ } catch (Exception e) {
+// MessageDialog.openError(XMLPlugin.getActiveWorkbenchShell(),"Error in XML parser","An error occured in the XML parser.\nNo structured compare can be shown");
+ XMLPlugin.log(e);
+ return null;
+ }
+
+ return root;
+ } catch (CoreException ex) {
+ XMLPlugin.log(ex);
+ }
+ return null;
+ }
+
+ public boolean canSave() {
+ return true;
+ }
+
+ public boolean canRewriteTree() {
+ return false;
+ }
+
+ public void rewriteTree(Differencer differencer, IDiffContainer root) {
+ }
+
+ public void save(IStructureComparator structure, Object input) {
+ if (input instanceof IEditableContent && structure instanceof XMLNode) {
+ IDocument doc= ((XMLNode)structure).getDocument();
+ IEditableContent bca= (IEditableContent) input;
+ String c= doc.get();
+ bca.setContent(c.getBytes());
+ }
+ }
+
+ public String getContents(Object node, boolean ignoreWhitespace) {
+ if (node instanceof XMLNode) {
+ String s= ((XMLNode)node).getValue();
+ if (ignoreWhitespace)
+ s= s.trim();
+ return s;
+ }
+ return null;
+ }
+
+ public IStructureComparator locate(Object path, Object source) {
+ return null;
+ }
+
+ /**
+ * Returns null if an error occurred.
+ */
+ static String readString(InputStream is) {
+ if (is == null)
+ return null;
+ BufferedReader reader= null;
+ try {
+ StringBuffer buffer= new StringBuffer();
+ char[] part= new char[2048];
+ int read= 0;
+ reader= new BufferedReader(new InputStreamReader(is));
+
+ while ((read= reader.read(part)) != -1)
+ buffer.append(part, 0, read);
+
+ return buffer.toString();
+
+ } catch (IOException ex) {
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException ex) {
+ }
+ }
+ }
+ return null;
+ }
+
+ /** Returns a sorted list of attributes. */
+ /* Taken from SAX2Writer sample of xerces */
+ protected Attributes sortAttributes(Attributes attrs) {
+
+ AttributesImpl attributes = new AttributesImpl();
+ int len = (attrs != null) ? attrs.getLength() : 0;
+ for (int i = 0; i < len; i++) {
+ String name = attrs.getQName(i);
+ int count = attributes.getLength();
+ int j = 0;
+ while (j < count) {
+ if (name.compareTo(attributes.getQName(j)) < 0) {
+ break;
+ }
+ j++;
+ }
+ attributes.insertAttributeAt(j, name, attrs.getType(i),
+ attrs.getValue(i));
+ }
+
+ return attributes;
+
+ } // sortAttributes(AttributeList):AttributeList
+
+ public void setIdMap(String idmap_name) {
+ fIdMapToUse= idmap_name;
+ }
+
+ /** Returns the name of the IdMap Scheme that will be used to set ids.
+ */
+ public String getIdMap() {
+ return fIdMapToUse;
+ }
+
+ public void setUseIdMap() {
+ if (fIdMaps != null && fIdMapsInternal != null)
+ fUseIdMap= fIdMaps.containsKey(fIdMapToUse) || fIdMapsInternal.containsKey(fIdMapToUse);
+ }
+
+ public boolean isUseIdMap() {
+ return fUseIdMap;
+ }
+
+ public void updateIdMaps() {
+ fIdMaps = XMLPlugin.getDefault().getIdMaps();
+ fOrderedElements= XMLPlugin.getDefault().getOrderedElements();
+ }
+
+ protected boolean isWhiteSpace(char c) {
+ return c == '\t' || c == '\n' || c == '\r' || c == ' ';
+ }
+
+ protected String removeWhiteSpace(String str) {
+ str= trimWhiteSpace(str);
+ StringBuffer retStr= new StringBuffer();
+ int start= 0, end= 0;
+ outer_while:
+ while (true) {
+ while ( end < str.length() && !isWhiteSpace(str.charAt(end)) ) { end++; }
+ if (end > str.length()) break outer_while;
+ if ( start != 0) retStr.append(' ');
+ retStr.append(str.substring(start, end));
+ end++;
+ while ( end < str.length() && isWhiteSpace(str.charAt(end)) ) { end++; }
+ start= end;
+ }
+ return retStr.toString();
+ }
+
+ protected String trimWhiteSpace(String str) {
+ int start=0, end= str.length()-1;
+ while (start < str.length() && isWhiteSpace(str.charAt(start))) { start++; }
+ if ( start == str.length() )
+ return ""; //$NON-NLS-1$
+ while (end >= 0 && isWhiteSpace(str.charAt(end))) { end--; }
+ return str.substring(start, end+1);
+ }
+
+ public void setRemoveWhiteSpace(boolean removeWhiteSpace) {
+ fRemoveWhiteSpace= removeWhiteSpace;
+ }
+
+ public boolean getRemoveWhiteSpace() {
+ return fRemoveWhiteSpace;
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewer.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewer.java
new file mode 100644
index 000000000..390d5c20e
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewer.java
@@ -0,0 +1,494 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.lang.reflect.InvocationTargetException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.CompareViewerSwitchingPane;
+import org.eclipse.compare.ITypedElement;
+import org.eclipse.compare.internal.TimeoutContext;
+import org.eclipse.compare.structuremergeviewer.DiffNode;
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.compare.structuremergeviewer.IStructureComparator;
+import org.eclipse.compare.structuremergeviewer.StructureDiffViewer;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.ToolBarManager;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * An XML diff tree viewer that can be configured with a <code>IStructureCreator</code>
+ * to retrieve a hierarchical structure from the input object (an <code>ICompareInput</code>)
+ * and perform a two-way or three-way compare on it.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed outside
+ * this package.
+ * </p>
+ *
+ * @see IStructureCreator
+ * @see ICompareInput
+ */
+public class XMLStructureViewer extends StructureDiffViewer {
+
+ private CompareViewerSwitchingPane fParent;
+
+ private HashMap fIdMapsInternal;
+ private HashMap fIdMaps;
+ private HashMap fOrderedElementsInternal;
+ private HashMap fOrderedElements;
+
+ protected static final char SIGN_SEPARATOR= XMLStructureCreator.SIGN_SEPARATOR;
+ /**
+ * Creates a new viewer for the given SWT tree control with the specified configuration.
+ *
+ * @param tree the tree control
+ * @param configuration the configuration for this viewer
+ */
+
+ class XMLSorter extends ViewerSorter {
+
+ ArrayList fOrdered;
+ boolean fAlwaysOrderSort;
+
+ public XMLSorter() {
+ super();
+ fAlwaysOrderSort= false;
+ }
+
+ public void setOrdered(ArrayList ordered) {
+ fOrdered= ordered;
+ }
+
+ public void setAlwaysOrderSort(boolean alwaysOrderSort) {
+ fAlwaysOrderSort= alwaysOrderSort;
+ }
+
+ public int category(Object node) {
+ if (node instanceof DiffNode) {
+ Object o= ((DiffNode) node).getId();
+ if (o instanceof XMLNode) {
+ String xmlType= ((XMLNode) o).getXMLType();
+ if (xmlType.equals(XMLStructureCreator.TYPE_ATTRIBUTE) ) return 1;
+ if (xmlType.equals(XMLStructureCreator.TYPE_ELEMENT) ) return 2;
+ if (xmlType.equals(XMLStructureCreator.TYPE_TEXT) ) return 2;
+ }
+ }
+ return 0;
+ }
+
+ public void sort(final Viewer viewer, Object[] elements) {
+ if ( (fOrdered != null || fAlwaysOrderSort)
+ && elements != null && elements.length > 0 && elements[0] instanceof DiffNode) {
+ Object o= ((DiffNode) elements[0]).getId();
+ if (o instanceof XMLNode) {
+ XMLNode parent= ((XMLNode) o).getParent();
+ String sig= parent.getSignature();
+ if (sig.endsWith(XMLStructureCreator.SIGN_ELEMENT)) {
+ String newSig= sig.substring(0, sig.length() - XMLStructureCreator.SIGN_ELEMENT.length());
+ if (fAlwaysOrderSort || fOrdered.contains(newSig)) {
+ final ArrayList originalTree= new ArrayList(Arrays.asList(parent.getChildren()));
+ Arrays.sort(elements, new Comparator() {
+ public int compare(Object a, Object b) {
+ return XMLSorter.this.compare((DiffNode) a, (DiffNode) b, originalTree);
+ }
+ });
+ return;
+ }
+ }
+ }
+ }
+ super.sort(viewer, elements);
+ }
+
+ private int compare(DiffNode a, DiffNode b, ArrayList originalTree) {
+
+ int index_a= originalTree.indexOf( (XMLNode)a.getId() );
+ int index_b= originalTree.indexOf( (XMLNode)b.getId() );
+ if (index_a < index_b)
+ return -1;
+ else
+ return 1;
+ }
+ }
+
+
+
+
+ public XMLStructureViewer(Tree tree, CompareConfiguration configuration) {
+ super(tree, configuration);
+ initialize();
+ }
+
+ /**
+ * Creates a new viewer under the given SWT parent with the specified configuration.
+ *
+ * @param parent the SWT control under which to create the viewer
+ * @param configuration the configuration for this viewer
+ */
+ public XMLStructureViewer(Composite parent, CompareConfiguration configuration) {
+ super(parent, configuration);
+ if (parent instanceof CompareViewerSwitchingPane) {
+ fParent= (CompareViewerSwitchingPane) parent;
+ }
+ initialize();
+ }
+
+ private void initialize() {
+ setStructureCreator(new XMLStructureCreator());
+ XMLPlugin plugin= XMLPlugin.getDefault();
+
+ plugin.getViewers().add(this);
+
+ fIdMaps= plugin.getIdMaps();
+ fIdMapsInternal= plugin.getIdMapsInternal();
+ fOrderedElements= plugin.getOrderedElements();
+ fOrderedElementsInternal= plugin.getOrderedElementsInternal();
+
+ XMLSorter sorter= new XMLSorter();
+ setSorter(sorter);
+
+ }
+
+ protected XMLStructureCreator getXMLStructureCreator() {
+ return (XMLStructureCreator) getStructureCreator();
+ }
+
+ /* (non Javadoc)
+ * Overridden to unregister all listeners.
+ */
+ protected void handleDispose(DisposeEvent event) {
+
+ XMLPlugin.getDefault().getViewers().remove(this);
+
+ super.handleDispose(event);
+ }
+
+ /**
+ * Recreates the comparable structures for the input sides.
+ */
+ protected void compareInputChanged(ICompareInput input) {
+ if (input != null) {
+ ITypedElement t= input.getLeft();
+ if (t != null) {
+ String fileExtension= t.getType();
+ getXMLStructureCreator().setFileExtension(fileExtension);
+ }
+ }
+
+ getXMLStructureCreator().initIdMaps();
+ super.compareInputChanged(input);
+
+ if (input != null && fParent.getTitleArgument() == null)
+ appendToTitle(getXMLStructureCreator().getIdMap());
+ }
+
+ /**
+ * Calls <code>diff</code> whenever the byte contents changes.
+ */
+ protected void contentChanged() {
+ fIdMaps = XMLPlugin.getDefault().getIdMaps();
+ fOrderedElements= XMLPlugin.getDefault().getOrderedElements();
+ getXMLStructureCreator().updateIdMaps();
+ if (isIdMapRemoved()) {
+ getXMLStructureCreator().setIdMap(XMLStructureCreator.DEFAULT_IDMAP);
+ }
+
+ getXMLStructureCreator().initIdMaps();
+
+ contentChanged(null);
+
+ if (fParent.getTitleArgument() == null)
+ appendToTitle(getXMLStructureCreator().getIdMap());
+
+ }
+
+ public IRunnableWithProgress getMatchingRunnable(final XMLNode left, final XMLNode right, final XMLNode ancestor) {
+ return new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException, OperationCanceledException {
+ if (monitor == null) {
+ monitor= new NullProgressMonitor();
+ }
+ int totalWork;
+ if (ancestor != null)
+ totalWork= 1;
+ else
+ totalWork= 3;
+ monitor.beginTask(XMLCompareMessages.getString("XMLStructureViewer.matching.beginTask"),totalWork); //$NON-NLS-1$
+ ArrayList ordered= null;
+ if (!getXMLStructureCreator().getIdMap().equals(XMLStructureCreator.USE_UNORDERED)
+ && !getXMLStructureCreator().getIdMap().equals(XMLStructureCreator.USE_ORDERED) ) {
+ ordered= (ArrayList) fOrderedElements.get(getXMLStructureCreator().getIdMap());
+ if (ordered == null)
+ ordered= (ArrayList) fOrderedElementsInternal.get(getXMLStructureCreator().getIdMap());
+ }
+ if (getSorter() instanceof XMLSorter)
+ ((XMLSorter)getSorter()).setOrdered(ordered);
+ AbstractMatching m;
+ if (getXMLStructureCreator().getIdMap().equals(XMLStructureCreator.USE_ORDERED)) {
+ m= new OrderedMatching();
+ if (getSorter() instanceof XMLSorter)
+ ((XMLSorter)getSorter()).setAlwaysOrderSort(true);
+ } else {
+ m= new GeneralMatching(ordered);
+ if (getSorter() instanceof XMLSorter)
+ ((XMLSorter)getSorter()).setAlwaysOrderSort(false);
+ }
+ try {
+ m.match((XMLNode) left, (XMLNode) right, false, monitor);
+ if (ancestor != null) {
+ m.match((XMLNode) left, (XMLNode) ancestor, true, new SubProgressMonitor(monitor,1));
+ m.match((XMLNode) right, (XMLNode) ancestor, true, new SubProgressMonitor(monitor,1));
+ }
+// } catch (InterruptedException e) {
+// System.out.println("in run");
+// e.printStackTrace();
+ } finally {
+ monitor.done();
+ }
+ }
+ };
+ }
+
+
+ protected void preDiffHook(IStructureComparator ancestor, IStructureComparator left, IStructureComparator right) {
+ // if (!xsc.getIdMap().equals(XMLStructureCreator.USE_ORDERED)) {
+ //TimeoutContext.run(true, TIMEOUT, getControl().getShell(), runnable);
+ if (left != null && right != null) {
+ try {
+ TimeoutContext.run(true, 500, XMLPlugin.getActiveWorkbenchShell(), getMatchingRunnable((XMLNode) left, (XMLNode) right, (XMLNode) ancestor));
+ } catch (Exception e) {
+ XMLPlugin.log(e);
+ }
+ }
+ }
+
+ /**
+ * Overriden to create buttons in the viewer's pane control bar.
+ * <p>
+ *
+ * @param toolbarManager the toolbar manager for which to add the buttons
+ */
+ protected void createToolItems(ToolBarManager toolBarManager) {
+ super.createToolItems(toolBarManager);
+ toolBarManager.appendToGroup("modes", new ChooseMatcherDropDownAction(this)); //$NON-NLS-1$
+ toolBarManager.appendToGroup("modes", new CreateNewIdMapAction(this)); //$NON-NLS-1$
+ }
+
+ /**
+ * Overriden to create a context menu.
+ * <p>
+ *
+ * @param manager the menu manager for which to add menu items
+ */
+ protected void fillContextMenu(IMenuManager manager) {
+ super.fillContextMenu(manager);
+ ISelection s= getSelection();
+ if (s instanceof StructuredSelection
+ && ((StructuredSelection) s).getFirstElement() instanceof DiffNode
+ && ((DiffNode)((StructuredSelection) s).getFirstElement()).getId() instanceof XMLNode) {
+ DiffNode diffnode = (DiffNode) ((StructuredSelection) s).getFirstElement();
+ String diffnodeIdSig = ((XMLNode)diffnode.getId()).getSignature();
+ fIdMaps = XMLPlugin.getDefault().getIdMaps();
+ String idmap_name = getXMLStructureCreator().getIdMap();
+ if ( diffnodeIdSig.endsWith(XMLStructureCreator.SIGN_ATTRIBUTE) || (diffnodeIdSig.endsWith(XMLStructureCreator.SIGN_TEXT) && ((XMLNode)diffnode.getId()).getOrigId().endsWith("(1)")) ) { //$NON-NLS-1$
+ Action action = new SetAsIdAction(diffnode);
+ if (!fIdMaps.containsKey(idmap_name)) {
+ action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.notUserIdMap")); //$NON-NLS-1$
+ action.setEnabled(false);
+ }
+ else {
+ HashMap idmapHM = (HashMap)fIdMaps.get(idmap_name);
+ XMLNode idNode = (XMLNode) diffnode.getId();
+ String signature = idNode.getSignature();
+ String idname = ""; //$NON-NLS-1$
+ if ( idNode.getSignature().endsWith(XMLStructureCreator.SIGN_ATTRIBUTE) ) {
+ signature = signature.substring(0,signature.indexOf(XMLStructureCreator.SIGN_ATTRIBUTE));
+ int end_of_signature = signature.lastIndexOf(SIGN_SEPARATOR,signature.length()-2);
+ idname = signature.substring(end_of_signature+1,signature.length()-1);
+ signature = signature.substring(0,end_of_signature+1);
+ } else if ( idNode.getSignature().endsWith(XMLStructureCreator.SIGN_TEXT) ) {
+ XMLNode textNode = (XMLNode) diffnode.getId();
+ XMLNode idelem = textNode.getParent();
+ XMLNode elem = idelem.getParent();
+ signature = elem.getSignature().substring(0,elem.getSignature().indexOf(XMLStructureCreator.SIGN_ELEMENT));
+ idname= idelem.getOrigId();
+ idname= idname.substring(0,idname.indexOf(XMLStructureCreator.ID_SEPARATOR));
+ idname= new Character(XMLStructureCreator.ID_TYPE_BODY) + idname;
+ }
+ if (idmapHM.containsKey(signature)) {
+ if (idmapHM.get(signature).equals(idname)) {
+ action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setId.text1")); //$NON-NLS-1$
+ action.setEnabled(false);
+ } else {
+ String oldId= (String) idmapHM.get(signature);
+ if (oldId.startsWith((new Character(XMLStructureCreator.ID_TYPE_BODY)).toString()))
+ oldId= oldId.substring(1);
+ action.setText(MessageFormat.format("{0} {1}",new String[] {XMLCompareMessages.getString("XMLStructureViewer.action.setId.text2"),oldId})); //$NON-NLS-2$ //$NON-NLS-1$
+ action.setEnabled(true);
+ }
+ } else {
+ action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setId.text3")); //$NON-NLS-1$
+ action.setEnabled(true);
+ }
+ }
+ manager.add(action);
+ } else if ( diffnodeIdSig.endsWith(XMLStructureCreator.SIGN_ELEMENT) ) {
+ SetOrderedAction action = new SetOrderedAction(idmap_name);
+ if (!fIdMaps.containsKey(idmap_name)) {
+ action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.notUserIdMap")); //$NON-NLS-1$
+ action.setEnabled(false);
+ }
+ else {
+ ArrayList idmapOrdered= (ArrayList) fOrderedElements.get(idmap_name);
+ XMLNode idNode= (XMLNode) diffnode.getId();
+ String signature= idNode.getSignature();
+// String idname= "";
+ signature = signature.substring(0,signature.indexOf(XMLStructureCreator.SIGN_ELEMENT));
+ if (idmapOrdered != null && idmapOrdered.contains(signature)) {
+ action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setOrdered.exists")); //$NON-NLS-1$
+ action.setEnabled(false);
+ } else {
+ action.setText(XMLCompareMessages.getString("XMLStructureViewer.action.setOrdered")); //$NON-NLS-1$
+ action.setSignature(signature);
+ action.setEnabled(true);
+ }
+ }
+
+ manager.add(action);
+ }
+ }
+ }
+
+ protected void appendToTitle(String idmap_name) {
+ if (fParent != null) {
+ getXMLStructureCreator().setIdMap(idmap_name);
+ fParent.setTitleArgument(idmap_name);
+ }
+ }
+
+ /**
+ * Returns true if the current Id Map scheme has been removed.
+ */
+ private boolean isIdMapRemoved() {
+ XMLStructureCreator xsc= getXMLStructureCreator();
+ String IdMapName= xsc.getIdMap();
+ return !IdMapName.equals(XMLStructureCreator.USE_UNORDERED)
+ && !IdMapName.equals(XMLStructureCreator.USE_ORDERED)
+ && !fIdMaps.containsKey(IdMapName)
+ && !fIdMapsInternal.containsKey(IdMapName)
+ && !fOrderedElements.containsKey(IdMapName);
+ }
+
+ protected class SetAsIdAction extends Action {
+
+ DiffNode fDiffNode;
+
+ public SetAsIdAction(DiffNode diffnode) {
+ fDiffNode= diffnode;
+ }
+
+ public void run() {
+ XMLStructureCreator sc = getXMLStructureCreator();
+// DiffNode diffnode = (DiffNode) ((StructuredSelection) getSelection()).getFirstElement();
+ String idmap_name = sc.getIdMap();
+ if (fIdMaps.containsKey(idmap_name)) {
+ HashMap idmapHM = (HashMap)fIdMaps.get(idmap_name);
+ if ( ((XMLNode)fDiffNode.getId()).getSignature().endsWith(XMLStructureCreator.SIGN_ATTRIBUTE) ) {
+ XMLNode attrNode = (XMLNode) fDiffNode.getId();
+ String signature = attrNode.getSignature();
+ signature = signature.substring(0,signature.indexOf(XMLStructureCreator.SIGN_ATTRIBUTE));
+ int end_of_signature = signature.lastIndexOf(SIGN_SEPARATOR,signature.length()-2);
+ String idattr = signature.substring(end_of_signature+1,signature.length()-1);
+ signature = signature.substring(0,end_of_signature+1);
+ idmapHM.put(signature,idattr);
+ XMLPlugin.getDefault().setIdMaps(fIdMaps,null,null,false);
+ //contentChanged();
+ } else if ( ((XMLNode)fDiffNode.getId()).getSignature().endsWith(XMLStructureCreator.SIGN_TEXT) ) {
+ XMLNode textNode = (XMLNode) fDiffNode.getId();
+ XMLNode idelem = textNode.getParent();
+ XMLNode elem = idelem.getParent();
+ String signature = elem.getSignature().substring(0,elem.getSignature().indexOf(XMLStructureCreator.SIGN_ELEMENT));
+ String idname= idelem.getOrigId();
+ idname= idname.substring(0,idname.indexOf(XMLStructureCreator.ID_SEPARATOR));
+ idname= new Character(XMLStructureCreator.ID_TYPE_BODY) + idname;
+ idmapHM.put(signature,idname);
+ XMLPlugin.getDefault().setIdMaps(fIdMaps,null,null,false);
+ //contentChanged();
+ }
+ }
+ }
+ }
+
+ protected class SetOrderedAction extends Action {
+
+ String fIdMapName;
+ String fSignature;
+
+
+ public SetOrderedAction(String idmap_name) {
+ fIdMapName= idmap_name;
+ }
+
+ public void run() {
+ //String idmap_name= getXMLStructureCreator().getIdMap();
+ if (fSignature != null) {
+ ArrayList idmapOrdered= (ArrayList) fOrderedElements.get(fIdMapName);
+ if (idmapOrdered == null) {
+ idmapOrdered= new ArrayList();
+ fOrderedElements.put(fIdMapName, idmapOrdered);
+ }
+ idmapOrdered.add(fSignature);
+ }
+ }
+
+ public void setSignature(String signature) {
+ fSignature= signature;
+ }
+ }
+
+ protected void updateIdMaps() {
+ getXMLStructureCreator().updateIdMaps();
+ }
+
+ /**
+ * Tracks property changes of the configuration object.
+ * Clients may override to track their own property changes.
+ * In this case they must call the inherited method.
+ */
+ protected void propertyChange(PropertyChangeEvent event) {
+ String key= event.getProperty();
+ if (key.equals(CompareConfiguration.IGNORE_WHITESPACE)) {
+ getXMLStructureCreator().setRemoveWhiteSpace(!getXMLStructureCreator().getRemoveWhiteSpace());
+ contentChanged();
+ }
+// else
+// super.propertyChange(event);
+ }
+}
+
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewerCreator.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewerCreator.java
new file mode 100644
index 000000000..0dd2aa2a9
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/XMLStructureViewerCreator.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import org.eclipse.swt.widgets.Composite;
+
+import org.eclipse.jface.viewers.Viewer;
+
+import org.eclipse.compare.CompareConfiguration;
+import org.eclipse.compare.IViewerCreator;
+
+/**
+ * A factory object for the <code>TextMergeViewer</code>.
+ * This indirection is necessary because only objects with a default
+ * constructor can be created via an extension point
+ * (this precludes Viewers).
+ */
+public class XMLStructureViewerCreator implements IViewerCreator {
+
+ public Viewer createViewer(Composite parent, CompareConfiguration mp) {
+ return new XMLStructureViewer(parent, mp);
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/MessageLine.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/MessageLine.java
new file mode 100644
index 000000000..a609e1f12
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/MessageLine.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml.ui;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A message line. It distinguishs between "normal" messages and errors.
+ * Setting an error message hides a currently displayed message until
+ * <code>clearErrorMessage</code> is called.
+ */
+public class MessageLine extends CLabel {
+
+ public static final RGB RED= new RGB(200, 0, 0);
+ private static RGB fgDefaultErrorRGB= RED;
+
+ private String fMessageText;
+ private String fErrorText;
+
+ private Color fDefaultColor;
+ private RGB fErrorRGB;
+ private Color fErrorColor;
+
+ /**
+ * Creates a new message line as a child of the given parent.
+ * Error message will be shown in <code>RED</code>.
+ */
+ public MessageLine(Composite parent) {
+ this(parent, SWT.LEFT);
+ }
+
+ /**
+ * Creates a new message line as a child of the parent and with the given SWT stylebits.
+ * Error message will be shown in <code>RED</code>.
+ */
+ public MessageLine(Composite parent, int style) {
+ super(parent, style);
+ fDefaultColor= getForeground();
+ fErrorRGB= fgDefaultErrorRGB;
+ }
+
+ /**
+ * Creates a new message line as a child of the parent and with the given SWT stylebits.
+ * Error message will be shown with in the given rgb color.
+ */
+ public MessageLine(Composite parent, int style, RGB errorRGB) {
+ super(parent, style);
+ fDefaultColor= getForeground();
+ fErrorRGB= errorRGB;
+ }
+
+ /**
+ * Clears the currently displayed error message and redisplayes
+ * the message which was active before the error message was set.
+ */
+ public void clearErrorMessage() {
+ setErrorMessage(null);
+ }
+
+ /**
+ * Clears the currently displayed message.
+ */
+ public void clearMessage() {
+ setMessage(null);
+ }
+
+ /**
+ * Get the currently displayed error text.
+ * @return The error message. If no error message is displayed <code>null</code> is returned.
+ */
+ public String getErrorMessage() {
+ return fErrorText;
+ }
+
+ /**
+ * Get the currently displayed message.
+ * @return The message. If no message is displayed <code>null<code> is returned.
+ */
+ public String getMessage() {
+ return fMessageText;
+ }
+
+ /**
+ * Sets the default error color used by all message lines.
+ * Note: a call to this method only affects newly created MessageLines not existing ones.
+ */
+ public static void setDefaultErrorColor(RGB color) {
+ fgDefaultErrorRGB= color;
+ }
+
+ /**
+ * Display the given error message. A currently displayed message
+ * is saved and will be redisplayed when the error message is cleared.
+ */
+ public void setErrorMessage(String message) {
+ fErrorText= message;
+
+ if (message == null) {
+ setMessage(fMessageText);
+ } else {
+ if (fErrorColor == null) {
+ fErrorColor= new Color(getDisplay(), fErrorRGB);
+ addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ fErrorColor.dispose();
+ }
+ });
+ }
+ setForeground(fErrorColor);
+ setText(message);
+ }
+ }
+
+ /**
+ * Set the message text. If the message line currently displays an error,
+ * the message is stored and will be shown after a call to clearErrorMessage
+ */
+ public void setMessage(String message) {
+ fMessageText= message;
+ if (message == null)
+ message= ""; //$NON-NLS-1$
+ if (fErrorText == null) {
+ setForeground(fDefaultColor);
+ setText(message);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusDialog.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusDialog.java
new file mode 100644
index 000000000..00f07fb24
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusDialog.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml.ui;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * An abstract base class for dialogs with a status bar and ok/cancel buttons.
+ * The status message must be passed over as StatusInfo object and can be
+ * an error, warning or ok. The OK button is enabled or disabled depending
+ * on the status.
+ */
+public abstract class StatusDialog extends Dialog {
+
+ private Button fOkButton;
+ private MessageLine fStatusLine;
+ private IStatus fLastStatus;
+ private String fTitle;
+ private Image fImage;
+
+ /**
+ * Creates an instane of a status dialog.
+ */
+ public StatusDialog(Shell parent) {
+ super(parent);
+ }
+
+ /**
+ * Specifies whether status line appears to the left of the buttons (default)
+ * or above them.
+ *
+ * @param aboveButtons if <code>true</code> status line is placed above buttons; if
+ * <code>false</code> to the right
+ */
+ public void setStatusLineAboveButtons(boolean aboveButtons) {
+ }
+
+ /**
+ * Update the dialog's status line to reflect the given status.
+ * It is save to call this method before the dialog has been opened.
+ */
+ protected void updateStatus(IStatus status) {
+ fLastStatus= status;
+ if (fStatusLine != null && !fStatusLine.isDisposed()) {
+ updateButtonsEnableState(status);
+ StatusUtil.applyToStatusLine(fStatusLine, status);
+ }
+ }
+
+ // 1GFCRWW: ITPJUI:ALL - Compile errors in VA/Java
+ /**
+ * Returns the last status.
+ */
+ public IStatus getStatus() {
+ return fLastStatus;
+ }
+
+ /**
+ * Updates the status of the ok button to reflect the given status.
+ * Subclasses may override this method to update additional buttons.
+ * @param status the status.
+ */
+ protected void updateButtonsEnableState(IStatus status) {
+ if (fOkButton != null && !fOkButton.isDisposed())
+ fOkButton.setEnabled(!status.matches(IStatus.ERROR));
+ }
+
+ /*
+ * @see Window#create(Shell)
+ */
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ if (fTitle != null)
+ shell.setText(fTitle);
+ }
+
+ /*
+ * @see Window#create()
+ */
+ public void create() {
+ super.create();
+ if (fLastStatus != null) {
+ // policy: dialogs are not allowed to come up with an error message
+ if (fLastStatus.matches(IStatus.ERROR)) {
+ StatusInfo status= new StatusInfo();
+ status.setError(""); //$NON-NLS-1$
+ fLastStatus= status;
+ }
+ updateStatus(fLastStatus);
+ }
+ }
+
+ /*
+ * @see Dialog#createButtonsForButtonBar(Composite)
+ */
+ protected void createButtonsForButtonBar(Composite parent) {
+ fOkButton= createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+ }
+
+ /*
+ * @see Dialog#createButtonBar(Composite)
+ */
+ protected Control createButtonBar(Composite parent) {
+ Composite composite= new Composite(parent, SWT.NULL);
+ GridLayout layout= new GridLayout();
+ layout.numColumns= 1;
+ layout.marginHeight= 0;
+ layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+ fStatusLine= new MessageLine(composite);
+ fStatusLine.setAlignment(SWT.LEFT);
+ fStatusLine.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fStatusLine.setMessage(""); //$NON-NLS-1$
+
+ super.createButtonBar(composite);
+ return composite;
+ }
+
+ /**
+ * Sets the title for this dialog.
+ * @param title the title.
+ */
+ public void setTitle(String title) {
+ fTitle= title != null ? title : ""; //$NON-NLS-1$
+ Shell shell= getShell();
+ if ((shell != null) && !shell.isDisposed())
+ shell.setText(fTitle);
+ }
+
+ /**
+ * Sets the image for this dialog.
+ * @param image the image.
+ */
+ public void setImage(Image image) {
+ fImage= image;
+ Shell shell= getShell();
+ if ((shell != null) && !shell.isDisposed())
+ shell.setImage(fImage);
+ }
+
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusInfo.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusInfo.java
new file mode 100644
index 000000000..c3b6575c5
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusInfo.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml.ui;
+
+import org.eclipse.core.runtime.IStatus;
+
+import org.eclipse.jface.util.Assert;
+
+/**
+ * A settable IStatus.
+ * Can be an error, warning, info or ok. For error, info and warning states,
+ * a message describes the problem.
+ */
+public class StatusInfo implements IStatus {
+
+ private String fStatusMessage;
+ private int fSeverity;
+
+ /**
+ * Creates a status set to OK (no message)
+ */
+ public StatusInfo() {
+ this(OK, null);
+ }
+
+ /**
+ * Creates a status .
+ * @param severity The status severity: ERROR, WARNING, INFO and OK.
+ * @param message The message of the status. Applies only for ERROR,
+ * WARNING and INFO.
+ */
+ public StatusInfo(int severity, String message) {
+ fStatusMessage= message;
+ fSeverity= severity;
+ }
+
+ /**
+ * Returns if the status' severity is OK.
+ */
+ public boolean isOK() {
+ return fSeverity == IStatus.OK;
+ }
+
+ /**
+ * Returns if the status' severity is WARNING.
+ */
+ public boolean isWarning() {
+ return fSeverity == IStatus.WARNING;
+ }
+
+ /**
+ * Returns if the status' severity is INFO.
+ */
+ public boolean isInfo() {
+ return fSeverity == IStatus.INFO;
+ }
+
+ /**
+ * Returns if the status' severity is ERROR.
+ */
+ public boolean isError() {
+ return fSeverity == IStatus.ERROR;
+ }
+
+ /**
+ * @see IStatus#getMessage
+ */
+ public String getMessage() {
+ return fStatusMessage;
+ }
+
+ /**
+ * Sets the status to ERROR.
+ * @param The error message (can be empty, but not null)
+ */
+ public void setError(String errorMessage) {
+ Assert.isNotNull(errorMessage);
+ fStatusMessage= errorMessage;
+ fSeverity= IStatus.ERROR;
+ }
+
+ /**
+ * Sets the status to WARNING.
+ * @param The warning message (can be empty, but not null)
+ */
+ public void setWarning(String warningMessage) {
+ Assert.isNotNull(warningMessage);
+ fStatusMessage= warningMessage;
+ fSeverity= IStatus.WARNING;
+ }
+
+ /**
+ * Sets the status to INFO.
+ * @param The info message (can be empty, but not null)
+ */
+ public void setInfo(String infoMessage) {
+ Assert.isNotNull(infoMessage);
+ fStatusMessage= infoMessage;
+ fSeverity= IStatus.INFO;
+ }
+
+ /**
+ * Sets the status to OK.
+ */
+ public void setOK() {
+ fStatusMessage= null;
+ fSeverity= IStatus.OK;
+ }
+
+ /*
+ * @see IStatus#matches(int)
+ */
+ public boolean matches(int severityMask) {
+ return (fSeverity & severityMask) != 0;
+ }
+
+ /**
+ * Returns always <code>false</code>.
+ * @see IStatus#isMultiStatus()
+ */
+ public boolean isMultiStatus() {
+ return false;
+ }
+
+ /*
+ * @see IStatus#getSeverity()
+ */
+ public int getSeverity() {
+ return fSeverity;
+ }
+
+ /*
+ * @see IStatus#getPlugin()
+ */
+ public String getPlugin() {
+ return "XMLPlugIn"; //$NON-NLS-1$
+ }
+
+ /**
+ * Returns always <code>null</code>.
+ * @see IStatus#getException()
+ */
+ public Throwable getException() {
+ return null;
+ }
+
+ /**
+ * Returns always the error severity.
+ * @see IStatus#getCode()
+ */
+ public int getCode() {
+ return fSeverity;
+ }
+
+ /**
+ * Returns always <code>null</code>.
+ * @see IStatus#getChildren()
+ */
+ public IStatus[] getChildren() {
+ return new IStatus[0];
+ }
+
+} \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusUtil.java b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusUtil.java
new file mode 100644
index 000000000..4de9644ab
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/ui/StatusUtil.java
@@ -0,0 +1 @@
+/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.compare.examples.xml.ui; import org.eclipse.jface.dialogs.DialogPage; import org.eclipse.core.runtime.IStatus; /** * A utility class to work with IStatus. */ public class StatusUtil { /** * Compares two instances of <code>IStatus</code>. The more severe is returned: * An error is more severe than a warning, and a warning is more severe * than ok. If the two stati have the same severity, the second is returned. */ public static IStatus getMoreSevere(IStatus s1, IStatus s2) { if (s1.getSeverity() > s2.getSeverity()) { return s1; } else { return s2; } } /** * Finds the most severe status from a array of stati. * An error is more severe than a warning, and a warning is more severe * than ok. */ public static IStatus getMostSevere(IStatus[] status) { IStatus max= null; for (int i= 0; i < status.length; i++) { IStatus curr= status[i]; if (curr.matches(IStatus.ERROR)) { return curr; } if (max == null || curr.getSeverity() > max.getSeverity()) { max= curr; } } return max; } /** * Returns error-message / warning-message for a status. * @return Array of size 2. Index 0 is the error message or <null> * if not an error. Index 1 the warning message or <null> if not a warning. */ private static String[] getErrorMessages(IStatus status) { String message= status.getMessage(); if (status.matches(IStatus.ERROR) && !"".equals(message)) { //$NON-NLS-1$ return new String[] { message, null }; } else if (status.matches(IStatus.WARNING | IStatus.INFO)) { return new String[] { null, message }; } else { return new String[] { null, null }; } } /** * Applies the status to the status line of a dialog page. */ public static void applyToStatusLine(DialogPage page, IStatus status) { String[] messages= getErrorMessages(status); page.setErrorMessage(messages[0]); page.setMessage(messages[1]); } /** * Applies the status to a message line */ public static void applyToStatusLine(MessageLine messageLine, IStatus status) { String[] messages= getErrorMessages(status); messageLine.setErrorMessage(messages[0]); messageLine.setMessage(messages[1]); } } \ No newline at end of file
diff --git a/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/xmlcompare.properties b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/xmlcompare.properties
new file mode 100644
index 000000000..387ce2f45
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/src/org/eclipse/compare/examples/xml/xmlcompare.properties
@@ -0,0 +1,109 @@
+###############################################################################
+# Copyright (c) 2000, 2003 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Common Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/cpl-v10.html
+#
+# Contributors:
+# IBM Corporation - initial API and implementation
+###############################################################################
+
+#
+# Structure Creator
+#
+XMLStructureCreator.pluginname= XML Compare
+XMLStructureCreator.unordered= Unordered
+XMLStructureCreator.ordered= Ordered
+XMLStructureCreator.idmap_unordered= Unordered
+XMLStructureCreator.id_map_scheme= Id Map Scheme:
+XMLStructureCreator.body= body
+
+
+#
+# Id Scheme Drop Down Menu
+#
+ChooseMatcherDropDownAction.text= Compare Mode
+ChooseMatcherDropDownAction.tooltip= Compare Mode
+
+#
+# Preference Page
+#
+XMLComparePreference.idtype.attribute= attribute
+XMLComparePreference.idtype.child_body= child text
+XMLComparePreference.topTableLabel= Id Mapping schemes:
+XMLComparePreference.topTableColumn1= name
+XMLComparePreference.topTableColumn2= internal/user
+XMLComparePreference.topTableColumn2internal= internal
+XMLComparePreference.topTableColumn2user= user
+XMLComparePreference.topTableColumn3= extension
+XMLComparePreference.topAdd= &Add...
+XMLComparePreference.topRename= &Edit...
+XMLComparePreference.topRemove= &Remove
+XMLComparePreference.topEdit= Edit &Copy...
+XMLComparePreference.middleTableColumn1= element
+XMLComparePreference.middleTableColumn2= path
+XMLComparePreference.middleTableColumn3= id attribute
+XMLComparePreference.middleTableColumn4= id source
+XMLComparePreference.middleNew= &New...
+XMLComparePreference.middleEdit= E&dit...
+XMLComparePreference.middleRemove= Re&move
+XMLComparePreference.middleTableLabel=Element mappings of selected Id Mapping Scheme:
+XMLComparePreference.bottomTableLabel=Elements whose children are compared in ordered fashion:
+XMLComparePreference.bottomTableColumn1=element
+XMLComparePreference.bottomTableColumn2=path
+XMLComparePreference.bottomNew=Ne&w...
+XMLComparePreference.bottomEdit=Edi&t...
+XMLComparePreference.bottomRemove=Remo&ve
+
+#
+# Dialogs
+#
+XMLCompareAddIdMapDialog.editTitle= Edit Id Mapping Scheme
+XMLCompareAddIdMapDialog.newTitle= New Id Mapping Scheme
+XMLCompareAddIdMapDialog.label= ID Map Name:
+XMLCompareAddIdMapDialog.extlabel= Extension (optional)
+XMLCompareAddIdMapDialog.error.noname= Enter Id Map Name.
+XMLCompareAddIdMapDialog.error.invalidname= Invalid Id Map Name.
+XMLCompareAddIdMapDialog.error.idmapExists= Id Map already exists.
+XMLCompareAddIdMapDialog.error.extfullstop= Extension cannot contain '.'
+XMLCompareAddIdMapDialog.error.extExists= Extension already set for
+
+XMLCompareEditCopyIdMapDialog.title= Create Editable Copy of Internal Scheme
+XMLCompareEditCopyIdMapDialog.comment= You cannon edit an internal Id Map Scheme.\nTherefore, a user copy of the Id Map Scheme will created for editing.\nThe extension associated with the internal Id Map Scheme will not be transferred.\n\nPlease Enter a new name for the Id Map Scheme copy.
+XMLCompareEditCopyIdMapDialog.label= ID Map Name of Copy:
+XMLCompareEditCopyIdMapDialog.error.noname= Enter Id Map Name.
+XMLCompareEditCopyIdMapDialog.error.invalidname= Invalid Id Map Name.
+XMLCompareEditCopyIdMapDialog.error.nameExists= Id Map Name already exists.
+
+XMLCompareEditMappingDialog.editTitle= Edit Mapping
+XMLCompareEditMappingDialog.newTitle= New Mapping
+XMLCompareEditMappingDialog.element= Element
+XMLCompareEditMappingDialog.signature= Path
+XMLCompareEditMappingDialog.idattribute= ID
+XMLCompareEditMappingDialog.idtype= ID Source
+XMLCompareEditMappingDialog.idtype.tooltip= Select whether the ID is an attribute of the element or the text of a child
+XMLCompareEditMappingDialog.idtype.attribute.tooltip= ID is an attribute of the element
+XMLCompareEditMappingDialog.idtype.childbody.tooltip= ID is the text of a child element
+XMLCompareEditMappingDialog.error.noname= Enter Element Name.
+XMLCompareEditMappingDialog.error.invalidname= Invalid Element Name.
+XMLCompareEditMappingDialog.error.mappingExists= Mapping already exists.
+XMLCompareEditMappingDialog.error.invalidsignature= Invalid Signature.
+XMLCompareEditMappingDialog.error.invalididattribute= Invalid ID Attribute.
+
+XMLCompareEditOrderedDialog.newTitle=New Ordered
+XMLCompareEditOrderedDialog.editTitle=Edit Ordered
+XMLCompareEditOrderedDialog.error.orderedExists=Ordered entry already exists
+
+#
+# XMLStructureViewer
+#
+XMLStructureViewer.newtask= Create new Id Map Scheme
+XMLStructureViewer.action.notUserIdMap= Please select a User Id Mapping Scheme
+XMLStructureViewer.action.setId.text1= Already set as Id
+XMLStructureViewer.action.setId.text2= Replace existing Id
+XMLStructureViewer.action.setId.text3= Set as Id
+XMLStructureViewer.action.setOrdered.exists= Ordered entry exists already
+XMLStructureViewer.action.setOrdered=Set children as ordered
+XMLStructureViewer.matching.beginTask=Running Matching algorithm...
+
diff --git a/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/AllXMLCompareTests.java b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/AllXMLCompareTests.java
new file mode 100644
index 000000000..fb2b69248
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/AllXMLCompareTests.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import junit.framework.*;
+
+/**
+ * TestSuite that runs all the XML Compare tests.
+ */
+public class AllXMLCompareTests {
+
+ public static void main (String[] args) {
+ junit.textui.TestRunner.run (suite());
+ }
+
+ public static Test suite ( ) {
+ TestSuite suite= new TestSuite("All XML Compare Tests"); //$NON-NLS-1$
+ suite.addTest(TestMinCostBipartiteMatching.suite());
+ suite.addTest(TestGeneralMatching.suite());
+ suite.addTest(TestXMLStructureCreator.suite());
+ return suite;
+ }
+}
+
diff --git a/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestGeneralMatching.java b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestGeneralMatching.java
new file mode 100644
index 000000000..0bc3c3b72
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestGeneralMatching.java
@@ -0,0 +1,2378 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.ListIterator;
+import java.util.Vector;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.eclipse.compare.examples.xml.GeneralMatching;
+import org.eclipse.compare.examples.xml.XMLChildren;
+import org.eclipse.compare.examples.xml.AbstractMatching.Match;
+import org.eclipse.jface.text.Document;
+
+/**
+ * Runs General Matching algorithm in GeneralMatching.java, which uses a distance table
+ * which is filled using the min cost bipartite matching algorithm
+ */
+public class TestGeneralMatching extends TestCase {
+
+ GeneralMatching fGM;
+ Document fdoc;
+
+ class Pair {
+ int fx;
+ int fy;
+
+ Pair(int x, int y) {
+ fx= x;
+ fy= y;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof Pair) {
+ Pair p= (Pair) obj;
+ return fx == p.fx && fy == p.fy;
+ }
+ return false;
+ }
+
+ public String toString() {
+ return "(" + fx + "," + fy + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ }
+
+ public TestGeneralMatching(String name) {
+ super(name);
+ }
+ public static void main(String[] args) {
+ junit.textui.TestRunner.run(suite());
+ //TestRunner.run(suite());
+ }
+
+ protected void setUp() {
+ System.out.println("TestGeneralMatching.name()==" + getName()); //$NON-NLS-1$
+ fGM= new GeneralMatching();
+ fdoc= new Document();
+ }
+
+ protected void tearDown() throws Exception {
+ //remove set-up
+ }
+
+ public static Test suite() {
+ return new TestSuite(TestGeneralMatching.class);
+ }
+
+ //General case without ids
+ public void test0() {
+ XMLChildren LeftTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ XMLChildren RightTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ //create Left Tree
+ XMLChildren parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "a_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setName(Integer.toString(1));
+ LeftTree.addChild(parent);
+ parent.setParent(LeftTree);
+ XMLChildren current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(2));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(3));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b1_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b1" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(4));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[2]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(5));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[3]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(6));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(7));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ XMLNode attr=
+ new XMLNode(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "attr", //$NON-NLS-1$
+ "hello", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "attr" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ attr.setName(Integer.toString(8));
+ parent.addChild(attr);
+ attr.setParent(parent);
+
+ //create Right Tree
+ parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "a_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setName(Integer.toString(1));
+ RightTree.addChild(parent);
+ parent.setParent(RightTree);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(2));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(3));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ attr=
+ new XMLNode(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "attr", //$NON-NLS-1$
+ "hello", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "attr" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ attr.setName(Integer.toString(4));
+ parent.addChild(attr);
+ attr.setParent(parent);
+ parent= (XMLChildren) parent.getParent().getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[2]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(5));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[3]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(6));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(7));
+ parent.addChild(current);
+ current.setParent(parent);
+
+ //run matching algorithm
+ try {
+ fGM.match(LeftTree, RightTree, false, null);
+ } catch (InterruptedException e) {
+ }
+ Vector expected= new Vector(8);
+ expected.add(new Pair(0, 0));
+ expected.add(new Pair(1, 1));
+ expected.add(new Pair(6, 2));
+ expected.add(new Pair(5, 5));
+ expected.add(new Pair(2, 6));
+ expected.add(new Pair(4, -1));
+ expected.add(new Pair(7, 3));
+ expected.add(new Pair(3, 7));
+ expected.add(new Pair(8, 4));
+ Vector Matches= fGM.getMatches();
+ Vector MatchingPairs= new Vector();
+ for (ListIterator it_M= Matches.listIterator(); it_M.hasNext();) {
+ Match m= (Match) it_M.next();
+ MatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null) ? -1 : Integer.parseInt(m.fy.getName())));
+ }
+ // for (Enumeration enum = MatchingPairs.elements(); enum.hasMoreElements(); ) {
+ // System.out.print(enum.nextElement() + " ");
+ // }
+ // System.out.println();
+ assertTrue(expected.size() == MatchingPairs.size());
+ for (Enumeration enum= expected.elements(); enum.hasMoreElements();) {
+ assertTrue(MatchingPairs.contains(enum.nextElement()));
+ }
+ }
+
+ //Simulate plugin.xml with ids
+ public void test1() {
+ XMLChildren LeftTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ LeftTree.setName(Integer.toString(0));
+ XMLChildren RightTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ RightTree.setName(Integer.toString(0));
+ int numbering= 1;
+ //create Left Tree
+ XMLChildren parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setUsesIDMAP(true);
+ parent.setName(Integer.toString(numbering++));
+ LeftTree.addChild(parent);
+ parent.setParent(LeftTree);
+ XMLChildren current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "id", //$NON-NLS-1$
+ "org.eclipse.ui", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "runtime<[1]", //$NON-NLS-1$
+ "runtime<[1]", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "runtime<[2]", //$NON-NLS-1$
+ "runtime<[2]", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "library<workbench.jar", //$NON-NLS-1$
+ "library<workbench.jar", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "library" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "export<*", //$NON-NLS-1$
+ "export<*", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "library" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "export" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent().getParent();
+ //parent is now plugin
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<importWizards", //$NON-NLS-1$
+ "extension-point<importWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "library" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "export" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<popupMenus", //$NON-NLS-1$
+ "extension-point<popupMenus", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension<org.eclipse.ui.newWizards", //$NON-NLS-1$
+ "extension<org.eclipse.ui.newWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current= parent;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "wizard<org.eclipse.ui.wizards.new.project.addedsomething", //$NON-NLS-1$
+ "wizard<org.eclipse.ui.wizards.new.project.addedsomething", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "wizard" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "wizard<org.eclipse.ui.wizards.new.folder", //$NON-NLS-1$
+ "wizard<org.eclipse.ui.wizards.new.folder", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "wizard" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+
+ //showNodeNames(LeftTree);
+
+ //create Right Tree
+ numbering= 1;
+ parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setUsesIDMAP(true);
+ parent.setName(Integer.toString(numbering++));
+ RightTree.addChild(parent);
+ parent.setParent(RightTree);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "id", //$NON-NLS-1$
+ "org.eclipse.ui", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "runtime<[1]", //$NON-NLS-1$
+ "runtime<[1]", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "library<workbench.jar", //$NON-NLS-1$
+ "library<workbench.jar", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "library" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "export<*", //$NON-NLS-1$
+ "export<*", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "library" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "export" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent().getParent();
+ //parent is now plugin
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<popupMenus", //$NON-NLS-1$
+ "extension-point<popupMenus", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<exportWizards", //$NON-NLS-1$
+ "extension-point<importWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "library" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "export" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension<org.eclipse.ui.newWizards", //$NON-NLS-1$
+ "extension<org.eclipse.ui.newWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current= parent;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "wizard<org.eclipse.ui.wizards.new.project", //$NON-NLS-1$
+ "wizard<org.eclipse.ui.wizards.new.project.addedsomething", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "wizard" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "wizard<org.eclipse.ui.wizards.new.folder", //$NON-NLS-1$
+ "wizard<org.eclipse.ui.wizards.new.folder", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "wizard" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+
+ //showNodeNames(RightTree);
+
+ //run matching algorithm
+ try {
+ fGM.match(LeftTree, RightTree, false, null);
+ } catch (InterruptedException e) {
+ }
+ Vector expected= new Vector();
+ expected.add(new Pair(0, 0));
+ expected.add(new Pair(1, 1));
+ expected.add(new Pair(8, 6));
+ expected.add(new Pair(9, 8));
+ expected.add(new Pair(11, 10));
+ expected.add(new Pair(2, 2));
+ expected.add(new Pair(4, 3));
+ expected.add(new Pair(3, -1));
+ expected.add(new Pair(5, 4));
+ expected.add(new Pair(6, 5));
+ Vector Matches= fGM.getMatches();
+ Vector MatchingPairs= new Vector();
+ for (ListIterator it_M= Matches.listIterator(); it_M.hasNext();) {
+ Match m= (Match) it_M.next();
+ MatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null) ? -1 : Integer.parseInt(m.fy.getName())));
+ }
+ // for (Enumeration enum = MatchingPairs.elements(); enum.hasMoreElements(); ) {
+ // System.out.print(enum.nextElement() + " ");
+ // }
+ // System.out.println();
+ assertTrue(expected.size() == MatchingPairs.size());
+ for (Enumeration enum= expected.elements(); enum.hasMoreElements();) {
+ assertTrue(MatchingPairs.contains(enum.nextElement()));
+ }
+ }
+
+ //Three-way compare, general case without ids
+ public void test2() {
+ XMLChildren AncestorTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ XMLChildren LeftTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ XMLChildren RightTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ int numbering= 1;
+ //create Ancestor Tree
+ XMLChildren parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "a_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setName(Integer.toString(numbering++));
+ AncestorTree.addChild(parent);
+ parent.setParent(AncestorTree);
+ XMLChildren current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[2]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ XMLNode attr=
+ new XMLNode(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "attr", //$NON-NLS-1$
+ "world", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "attr" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ attr.setName(Integer.toString(numbering++));
+ parent.addChild(attr);
+ attr.setParent(parent);
+
+ //create Left Tree
+ numbering= 1;
+ parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "a_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setName(Integer.toString(numbering++));
+ LeftTree.addChild(parent);
+ parent.setParent(LeftTree);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[2]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ attr=
+ new XMLNode(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "attr", //$NON-NLS-1$
+ "hello", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "attr" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ attr.setName(Integer.toString(numbering++));
+ parent.addChild(attr);
+ attr.setParent(parent);
+
+ //create Right Tree
+ numbering= 1;
+ parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "a_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setName(Integer.toString(numbering++));
+ RightTree.addChild(parent);
+ parent.setParent(RightTree);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b1_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "e_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[2]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ attr=
+ new XMLNode(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "attr", //$NON-NLS-1$
+ "world", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "attr" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ attr.setName(Integer.toString(numbering++));
+ parent.addChild(attr);
+ attr.setParent(parent);
+
+ //run matching algorithm
+ try {
+ fGM.match(LeftTree, RightTree, false, null);
+ Vector LRMatches= fGM.getMatches();
+ Vector LRMatchingPairs= new Vector();
+ for (ListIterator it_M= LRMatches.listIterator();
+ it_M.hasNext();
+ ) {
+ Match m= (Match) it_M.next();
+ LRMatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null)
+ ? -1
+ : Integer.parseInt(m.fy.getName())));
+ }
+ fGM.match(LeftTree, AncestorTree, true, null);
+ Vector LAMatches= fGM.getMatches();
+ Vector LAMatchingPairs= new Vector();
+ for (ListIterator it_M= LAMatches.listIterator();
+ it_M.hasNext();
+ ) {
+ Match m= (Match) it_M.next();
+ LAMatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null)
+ ? -1
+ : Integer.parseInt(m.fy.getName())));
+
+ }
+ fGM.match(RightTree, AncestorTree, true, null);
+ Vector RAMatches= fGM.getMatches();
+ Vector RAMatchingPairs= new Vector();
+ for (ListIterator it_M= RAMatches.listIterator();
+ it_M.hasNext();
+ ) {
+ Match m= (Match) it_M.next();
+ RAMatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null)
+ ? -1
+ : Integer.parseInt(m.fy.getName())));
+ }
+ Vector LRexpected= new Vector();
+ LRexpected.add(new Pair(0, 0));
+ LRexpected.add(new Pair(1, 1));
+ LRexpected.add(new Pair(2, 2));
+ LRexpected.add(new Pair(-1, 4));
+ LRexpected.add(new Pair(4, 6));
+ LRexpected.add(new Pair(3, 3));
+ LRexpected.add(new Pair(5, 7));
+ Vector LAexpected= new Vector();
+ LAexpected.add(new Pair(0, 0));
+ LAexpected.add(new Pair(1, 1));
+ LAexpected.add(new Pair(2, 2));
+ LAexpected.add(new Pair(3, 3));
+ LAexpected.add(new Pair(4, 4));
+ LAexpected.add(new Pair(5, 5));
+ Vector RAexpected= new Vector();
+ RAexpected.add(new Pair(0, 0));
+ RAexpected.add(new Pair(1, 1));
+ RAexpected.add(new Pair(2, 2));
+ RAexpected.add(new Pair(6, 4));
+ RAexpected.add(new Pair(4, -1));
+ RAexpected.add(new Pair(3, 3));
+ RAexpected.add(new Pair(7, 5));
+
+ assertTrue(LRexpected.size() == LRMatchingPairs.size());
+ for (Enumeration enum= LRexpected.elements();
+ enum.hasMoreElements();
+ ) {
+ assertTrue(LRMatchingPairs.contains(enum.nextElement()));
+ }
+ assertTrue(LAexpected.size() == LAMatchingPairs.size());
+ for (Enumeration enum= LAexpected.elements();
+ enum.hasMoreElements();
+ ) {
+ assertTrue(LAMatchingPairs.contains(enum.nextElement()));
+ }
+ assertTrue(RAexpected.size() == RAMatchingPairs.size());
+ for (Enumeration enum= RAexpected.elements();
+ enum.hasMoreElements();
+ ) {
+ assertTrue(RAMatchingPairs.contains(enum.nextElement()));
+ }
+ } catch (InterruptedException e) {
+ }
+
+ }
+
+ //Three-way compare of plugin.xml with ids
+ public void test3() {
+ XMLChildren AncestorTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ AncestorTree.setName(Integer.toString(0));
+ XMLChildren LeftTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ LeftTree.setName(Integer.toString(0));
+ XMLChildren RightTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ RightTree.setName(Integer.toString(0));
+ int numbering= 1;
+ //create Ancestor Tree
+ XMLChildren parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setUsesIDMAP(true);
+ parent.setName(Integer.toString(numbering++));
+ AncestorTree.addChild(parent);
+ parent.setParent(AncestorTree);
+ XMLChildren current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "id", //$NON-NLS-1$
+ "org.eclipse.ui", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ //parent is plugin
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<importWizards", //$NON-NLS-1$
+ "extension-point<importWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "library" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "export" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<editorActions", //$NON-NLS-1$
+ "extension-point<editorActions", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<popupMenus", //$NON-NLS-1$
+ "extension-point<popupMenus", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<exportWizards", //$NON-NLS-1$
+ "extension-point<exportWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+
+ //create LeftTree Tree
+ numbering= 1;
+ parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setUsesIDMAP(true);
+ parent.setName(Integer.toString(numbering++));
+ LeftTree.addChild(parent);
+ parent.setParent(LeftTree);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "id", //$NON-NLS-1$
+ "org.eclipse.ui", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ //parent is plugin
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<editorActions", //$NON-NLS-1$
+ "extension-point<editorActions", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<popupMenus", //$NON-NLS-1$
+ "extension-point<popupMenus", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<exportWizards", //$NON-NLS-1$
+ "extension-point<exportWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+
+ //create RightTree Tree
+ numbering= 1;
+ parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ "plugin" + XMLStructureCreator.ID_SEPARATOR + "org.eclipse.ui", //$NON-NLS-1$ //$NON-NLS-2$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setUsesIDMAP(true);
+ parent.setName(Integer.toString(numbering++));
+ RightTree.addChild(parent);
+ parent.setParent(RightTree);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ATTRIBUTE,
+ "id", //$NON-NLS-1$
+ "org.eclipse.ui", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "runtime" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ATTRIBUTE),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ //parent is plugin
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<editorActions", //$NON-NLS-1$
+ "extension-point<editorActions", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<popupMenus", //$NON-NLS-1$
+ "extension-point<popupMenus", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "extension-point<importWizards", //$NON-NLS-1$
+ "extension-point<importWizards", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "plugin" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "extension-point" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setUsesIDMAP(true);
+ current.setName(Integer.toString(numbering++));
+ parent.addChild(current);
+ current.setParent(parent);
+
+ //run matching algorithm
+ try {
+ fGM.match(LeftTree, RightTree, false, null);
+ Vector LRMatches= fGM.getMatches();
+ Vector LRMatchingPairs= new Vector();
+ for (ListIterator it_M= LRMatches.listIterator();
+ it_M.hasNext();
+ ) {
+ Match m= (Match) it_M.next();
+ LRMatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null)
+ ? -1
+ : Integer.parseInt(m.fy.getName())));
+ }
+ fGM.match(LeftTree, AncestorTree, true, null);
+ Vector LAMatches= fGM.getMatches();
+ Vector LAMatchingPairs= new Vector();
+ for (ListIterator it_M= LAMatches.listIterator();
+ it_M.hasNext();
+ ) {
+ Match m= (Match) it_M.next();
+ LAMatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null)
+ ? -1
+ : Integer.parseInt(m.fy.getName())));
+ }
+ fGM.match(RightTree, AncestorTree, true, null);
+ Vector RAMatches= fGM.getMatches();
+ Vector RAMatchingPairs= new Vector();
+ for (ListIterator it_M= RAMatches.listIterator();
+ it_M.hasNext();
+ ) {
+ Match m= (Match) it_M.next();
+ RAMatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null)
+ ? -1
+ : Integer.parseInt(m.fy.getName())));
+ }
+ Vector LRexpected= new Vector();
+ LRexpected.add(new Pair(0, 0));
+ LRexpected.add(new Pair(1, 1));
+ LRexpected.add(new Pair(2, 2));
+ LRexpected.add(new Pair(3, 3));
+ LRexpected.add(new Pair(4, 4));
+ Vector LAexpected= new Vector();
+ LAexpected.add(new Pair(0, 0));
+ LAexpected.add(new Pair(1, 1));
+ LAexpected.add(new Pair(2, 2));
+ LAexpected.add(new Pair(3, 4));
+ LAexpected.add(new Pair(4, 5));
+ LAexpected.add(new Pair(5, 6));
+ Vector RAexpected= new Vector();
+ RAexpected.add(new Pair(0, 0));
+ RAexpected.add(new Pair(1, 1));
+ RAexpected.add(new Pair(2, 2));
+ RAexpected.add(new Pair(3, 4));
+ RAexpected.add(new Pair(4, 5));
+ RAexpected.add(new Pair(5, 3));
+
+ assertTrue(LRexpected.size() == LRMatchingPairs.size());
+ for (Enumeration enum= LRexpected.elements();
+ enum.hasMoreElements();
+ ) {
+ assertTrue(LRMatchingPairs.contains(enum.nextElement()));
+ }
+ assertTrue(LAexpected.size() == LAMatchingPairs.size());
+ for (Enumeration enum= LAexpected.elements();
+ enum.hasMoreElements();
+ ) {
+ assertTrue(LAMatchingPairs.contains(enum.nextElement()));
+ }
+ assertTrue(RAexpected.size() == RAMatchingPairs.size());
+ for (Enumeration enum= RAexpected.elements();
+ enum.hasMoreElements();
+ ) {
+ assertTrue(RAMatchingPairs.contains(enum.nextElement()));
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public void test4() {
+ ArrayList Ordered= new ArrayList();
+ Ordered.add("root>a>b>"); //$NON-NLS-1$
+ Ordered.add("root>a>b>c>"); //$NON-NLS-1$
+ fGM= new GeneralMatching(Ordered);
+ int i= 1;
+ XMLChildren LeftTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ XMLChildren RightTree=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ XMLStructureCreator.ROOT_ID,
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ //create Left Tree
+ XMLChildren parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "a_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setName(Integer.toString(i++));
+ LeftTree.addChild(parent);
+ parent.setParent(LeftTree);
+ XMLChildren current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c1_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c1" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c2_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c2" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c3_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c3" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[2]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "d1_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "d1" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "d2_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "d2" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "d3_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "d3" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent().getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[3]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+
+ //create Right Tree
+ i= 1;
+ parent=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "a_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ parent.setName(Integer.toString(i++));
+ RightTree.addChild(parent);
+ parent.setParent(RightTree);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c1_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c1" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c2_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c2" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c4_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c4" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c3_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c3" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[2]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "c_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= current;
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "d1_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "d1" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "d3_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "d3" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "d2_[1]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "c" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "d2" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+ parent= (XMLChildren) parent.getParent().getParent();
+ current=
+ new XMLChildren(
+ XMLStructureCreator.TYPE_ELEMENT,
+ "b_[3]", //$NON-NLS-1$
+ "", //$NON-NLS-1$
+ (XMLStructureCreator.ROOT_ID
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "a" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + "b" //$NON-NLS-1$
+ + XMLStructureCreator.SIGN_SEPARATOR
+ + XMLStructureCreator.SIGN_ELEMENT),
+ fdoc,
+ 0,
+ 0);
+ current.setName(Integer.toString(i++));
+ parent.addChild(current);
+ current.setParent(parent);
+
+ //run matching algorithm
+ try {
+ fGM.match(LeftTree, RightTree, false, null);
+ } catch (InterruptedException e) {
+ }
+ Vector expected= new Vector(8);
+ expected.add(new Pair(0, 0));
+ expected.add(new Pair(1, 1));
+ expected.add(new Pair(2, 2));
+ expected.add(new Pair(6, 7));
+ expected.add(new Pair(11, 12));
+ expected.add(new Pair(3, 3));
+ expected.add(new Pair(4, 4));
+ expected.add(new Pair(-1, 5));
+ expected.add(new Pair(5, 6));
+ expected.add(new Pair(7, 8));
+ expected.add(new Pair(8, 9));
+ expected.add(new Pair(-1, 10));
+ expected.add(new Pair(9, 11));
+ expected.add(new Pair(10, -1));
+ Vector Matches= fGM.getMatches();
+ Vector MatchingPairs= new Vector();
+ for (ListIterator it_M= Matches.listIterator(); it_M.hasNext();) {
+ Match m= (Match) it_M.next();
+ MatchingPairs.add(
+ new Pair(
+ (m.fx == null) ? -1 : Integer.parseInt(m.fx.getName()),
+ (m.fy == null) ? -1 : Integer.parseInt(m.fy.getName())));
+ // System.out.println("("+ ((m.fx==null)?-1:Integer.parseInt(m.fx.getName()))+","+ ((m.fy==null)?-1:Integer.parseInt(m.fy.getName())) +")");
+ }
+ // for (Enumeration enum = MatchingPairs.elements(); enum.hasMoreElements(); ) {
+ // System.out.print(enum.nextElement() + " ");
+ // }
+ // System.out.println();
+ assertTrue(expected.size() == MatchingPairs.size());
+ for (Enumeration enum= expected.elements(); enum.hasMoreElements();) {
+ assertTrue(MatchingPairs.contains(enum.nextElement()));
+ }
+ }
+
+ protected void showNodeNames(XMLNode root) {
+ if (root != null) {
+ System.out.print(root.getName() + ", "); //$NON-NLS-1$
+ Object[] children= root.getChildren();
+ if (children != null) {
+ for (int i= 0; i < children.length; i++)
+ showNodeNames((XMLNode) children[i]);
+ }
+ }
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestMinCostBipartiteMatching.java b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestMinCostBipartiteMatching.java
new file mode 100644
index 000000000..6ee2e471f
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestMinCostBipartiteMatching.java
@@ -0,0 +1,352 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import junit.framework.*;
+import org.eclipse.compare.examples.xml.HungarianMethod;
+
+public class TestMinCostBipartiteMatching extends TestCase {
+
+ int[][] fA; //matrix that represents instance of matching problem
+ int[] fC; //solution returned by HungarianMethod
+ int fT; //cost of solution returned by HungarianMethod
+ int[] fC2; //actual solution of matching
+ int fT2; //actual cost of matching
+ HungarianMethod fH;
+
+ public TestMinCostBipartiteMatching(String name) {
+ super(name);
+ }
+ public static void main(String[] args) {
+ //junit.textui.TestRunner.run (suite());
+ //TestRunner.run(suite());
+ }
+
+ protected void setUp() {
+ System.out.println("TestMinCostBipartiteMatching.name()==" + getName()); //$NON-NLS-1$
+ fH= new HungarianMethod();
+ }
+
+ protected void tearDown() throws Exception {
+ //remove set-up
+ }
+
+ public static Test suite() {
+ return new TestSuite(TestMinCostBipartiteMatching.class);
+ }
+
+ public void test0() {
+ fA= new int[][] { { 0, 0, 0, 0, 0, 0, 0 }, {
+ 0, 7, 2, 1, 9, 4, 0 }, {
+ 0, 9, 6, 9, 5, 5, 0 }, {
+ 0, 3, 8, 3, 1, 8, 0 }, {
+ 0, 7, 9, 4, 2, 2, 0 }, {
+ 0, 8, 4, 7, 4, 8, 0 }
+ };
+ fC= new int[6];
+ ;
+
+ fT2= 15;
+ //optimal matching: {(1,3), (2,5), (3,1), (4,4), (5,2)}
+ fC2= new int[] { 0, 3, 5, 1, 4, 2 };
+
+ fT= fH.solve(fA, fC);
+
+ for (int J= 1; J <= 5; J++) {
+ assertTrue(fC[J] == fC2[J]);
+ }
+ assertTrue(fT == fT2);
+ }
+
+ public void test1() {
+ /* checks case where number of vertices on the two sides are not equal
+ * and dummy vertices (here, 2nd right vertice (see 3rd column)) are introduced
+ * with dummy cost
+ */
+ fA= new int[][] { { 0, 0, 0, 0 }, {
+ 0, 2, 3, 0 }, {
+ 0, 0, 3, 0 }
+ };
+ fC= new int[3];
+
+ fT2= 3;
+ //optimal matching: {(1,2), (2,1)}
+ fC2= new int[] { 0, 2, 1 };
+
+ fT= fH.solve(fA, fC);
+
+ for (int J= 1; J < fC.length; J++) {
+ assertTrue(fC[J] == fC2[J]);
+ }
+ assertTrue(fT == fT2);
+ }
+
+ public void test2() {
+ fA= new int[][] { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, {
+ 0,
+ 1542,
+ 3533,
+ 2787,
+ 1891,
+ 3833,
+ 3558,
+ 1173,
+ 2187,
+ 3307,
+ 2836,
+ 3792,
+ 2106,
+ 1444,
+ 1924,
+ 0 },
+ {
+ 0,
+ 1510,
+ 3766,
+ 3186,
+ 1815,
+ 4931,
+ 3221,
+ 1478,
+ 2107,
+ 3344,
+ 2830,
+ 4816,
+ 2359,
+ 1223,
+ 1936,
+ 0 },
+ {
+ 0,
+ 1160,
+ 3901,
+ 2100,
+ 1545,
+ 4484,
+ 3326,
+ 1355,
+ 1824,
+ 3088,
+ 2563,
+ 3627,
+ 2197,
+ 1354,
+ 1689,
+ 0 },
+ {
+ 0,
+ 1203,
+ 4049,
+ 2295,
+ 1586,
+ 3556,
+ 4009,
+ 1110,
+ 2282,
+ 3990,
+ 2692,
+ 3751,
+ 2399,
+ 1691,
+ 1786,
+ 0 },
+ {
+ 0,
+ 1426,
+ 3163,
+ 2242,
+ 1659,
+ 4617,
+ 3240,
+ 1712,
+ 1987,
+ 3637,
+ 3037,
+ 4471,
+ 2166,
+ 1356,
+ 1878,
+ 0 },
+ {
+ 0,
+ 1172,
+ 3912,
+ 1951,
+ 1469,
+ 4272,
+ 3239,
+ 1546,
+ 1924,
+ 3560,
+ 2513,
+ 4694,
+ 2127,
+ 1951,
+ 1693,
+ 0 },
+ {
+ 0,
+ 1647,
+ 3889,
+ 2097,
+ 1646,
+ 3749,
+ 3656,
+ 970,
+ 1957,
+ 3373,
+ 2678,
+ 3711,
+ 1788,
+ 1279,
+ 1752,
+ 0 },
+ {
+ 0,
+ 1219,
+ 3754,
+ 2348,
+ 1686,
+ 4297,
+ 3677,
+ 1364,
+ 1995,
+ 4133,
+ 2888,
+ 3643,
+ 1993,
+ 1481,
+ 1880,
+ 0 },
+ {
+ 0,
+ 1637,
+ 3895,
+ 2165,
+ 1575,
+ 4512,
+ 3903,
+ 1499,
+ 1935,
+ 2760,
+ 3151,
+ 3162,
+ 2306,
+ 1493,
+ 1710,
+ 0 },
+ {
+ 0,
+ 1391,
+ 3992,
+ 1942,
+ 1846,
+ 4450,
+ 3211,
+ 1626,
+ 1952,
+ 3495,
+ 2951,
+ 4541,
+ 2014,
+ 1639,
+ 1932,
+ 0 },
+ {
+ 0,
+ 1282,
+ 4292,
+ 3048,
+ 2074,
+ 4458,
+ 3460,
+ 1300,
+ 1952,
+ 3495,
+ 2951,
+ 4541,
+ 2014,
+ 1639,
+ 1932,
+ 0 },
+ {
+ 0,
+ 1598,
+ 3721,
+ 2457,
+ 1880,
+ 4073,
+ 3164,
+ 1829,
+ 1952,
+ 3495,
+ 2951,
+ 4541,
+ 2014,
+ 1639,
+ 1932,
+ 0 },
+ {
+ 0,
+ 1384,
+ 1742,
+ 2447,
+ 1858,
+ 4367,
+ 3189,
+ 1774,
+ 1699,
+ 3040,
+ 2499,
+ 3911,
+ 2203,
+ 1433,
+ 1676,
+ 0 },
+ {
+ 0,
+ 1474,
+ 3815,
+ 2214,
+ 1997,
+ 4515,
+ 3202,
+ 1352,
+ 1942,
+ 3274,
+ 2502,
+ 5138,
+ 2395,
+ 1767,
+ 2136,
+ 0 }
+ };
+
+ fT2= 29858;
+ //optimal matching: {(8,1) (13,2) (10,3) (6,4) (4,5) (12,6) (1,7) (11,8) (3,9) (14,10) (9,11) (7,12) (2,13) (5,14)}
+ fC2= new int[] { 0, 8, 13, 10, 6, 4, 12, 1, 11, 3, 14, 9, 7, 2, 5 };
+
+ fC= new int[15];
+
+ fT= fH.solve(fA, fC);
+
+ // for (int J=1; J<fC.length; J++) {
+ // System.out.print("("+fC[J]+","+J+") ");
+ // }
+ // System.out.println();
+ // System.out.println("Cost: "+fT);
+
+ for (int J= 1; J < fC.length; J++) {
+ assertTrue(fC[J] == fC2[J]);
+ }
+ assertTrue(fT == fT2);
+ }
+}
diff --git a/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestXMLStructureCreator.java b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestXMLStructureCreator.java
new file mode 100644
index 000000000..811c9ca20
--- /dev/null
+++ b/examples/org.eclipse.compare.examples.xml/tests/org/eclipse/compare/examples/xml/TestXMLStructureCreator.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.compare.examples.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import junit.framework.*;
+
+import org.eclipse.jface.text.Document;
+
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.examples.xml.XMLChildren;
+import org.eclipse.compare.examples.xml.XMLNode;
+import org.eclipse.compare.examples.xml.XMLStructureCreator;
+import org.eclipse.core.runtime.CoreException;
+
+public class TestXMLStructureCreator extends TestCase {
+
+ Document fdoc;
+ XMLStructureCreator fsc;
+
+ public class TestStream implements IStreamContentAccessor {
+ String fString;
+
+ public TestStream(String string) {
+ fString= string;
+ }
+
+ public InputStream getContents() throws CoreException {
+ return new ByteArrayInputStream(fString.getBytes());
+ }
+ }
+
+ public TestXMLStructureCreator(String name) {
+ super(name);
+ }
+
+ protected void setUp() {
+ System.out.println("TestXMLStructureCreator.name()==" + getName()); //$NON-NLS-1$
+ fdoc = new Document();
+ fsc = new XMLStructureCreator();
+ }
+
+ protected void tearDown() throws Exception {
+ //remove set-up
+ }
+
+ public static Test suite() {
+ return new TestSuite(TestXMLStructureCreator.class);
+ }
+
+ public void test0() {
+ TestStream s= new TestStream("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<a attr1=\"&lt;b&gt;&lt;/b&gt;\"\nattr2=\"he\n ll\n o2\" attr3=\"hello3\"\nattr4=\"hello4\"><b attr=\n\"battr\" attr2=\"battr2\">\n<c/>\n</b>\n<b2/>\n</a>\n"); //$NON-NLS-1$
+ XMLChildren Tree= (XMLChildren) fsc.getStructure(s);
+
+ XMLChildren ExpectedTree = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,XMLStructureCreator.ROOT_ID, "",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$
+ //create Expected Tree
+ XMLChildren parent = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"a<[1]","<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<a attr1=\"&lt;b&gt;&lt;/b&gt;\"\nattr2=\"he\n ll\n o2\" attr3=\"hello3\"\nattr4=\"hello4\"><b attr=\n\"battr\" attr2=\"battr2\">\n<c/>\n</b>\n<b2/>\n</a>\n",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ parent.setName("a [1]"); //$NON-NLS-1$
+ ExpectedTree.addChild(parent);
+ parent.setParent(ExpectedTree);
+ XMLChildren current = new XMLChildren(XMLStructureCreator.TYPE_ATTRIBUTE,"attr1","<b></b>",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "attr1" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ATTRIBUTE), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("attr1"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ATTRIBUTE,"attr2","he ll o2",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "attr2" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ATTRIBUTE), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("attr2"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ATTRIBUTE,"attr3","hello3",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "attr3" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ATTRIBUTE), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("attr3"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ATTRIBUTE,"attr4","hello4",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "attr4" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ATTRIBUTE), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("attr4"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"b<[1]","<b attr=\n\"battr\" attr2=\"battr2\">\n<c/>\n</b>\n",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR +"b" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("b [1]"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = current;
+ current = new XMLChildren(XMLStructureCreator.TYPE_ATTRIBUTE,"attr","battr",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "attr" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ATTRIBUTE), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ current.setName("attr"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ATTRIBUTE,"attr2","battr2",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "attr2" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ATTRIBUTE), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ current.setName("attr2"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"c<[1]","<c/>",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "c" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ current.setName("c [1]"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = (XMLChildren) parent.getParent();
+ current = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"b2<[1]","<b2/>",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR +"b2" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("b2 [1]"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+
+ checkTrees(Tree,ExpectedTree);
+ }
+
+ public void test1() {
+ TestStream s= new TestStream("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<a>body_a_1\n <b>body_b_1\n <c>body_c_1\n <d2>body_d2\n </d2>\nbody_c_2\n </c>\nbody_b_2\n </b>\nbody_a_2\n <b2>\n </b2>\nbody_a_3\n</a>"); //$NON-NLS-1$
+ XMLChildren Tree= (XMLChildren) fsc.getStructure(s);
+
+ XMLChildren ExpectedTree = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,XMLStructureCreator.ROOT_ID, "",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$
+ //create Expected Tree
+ XMLChildren parent = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"a<[1]","<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<a>body_a_1\n <b>body_b_1\n <c>body_c_1\n <d2>body_d2\n </d2>\nbody_c_2\n </c>\nbody_b_2\n </b>\nbody_a_2\n <b2>\n </b2>\nbody_a_3\n</a>",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ parent.setName("a [1]"); //$NON-NLS-1$
+ ExpectedTree.addChild(parent);
+ parent.setParent(ExpectedTree);
+ XMLChildren current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(1)","body_a_1\n ",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ current.setName("body (1)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"b<[1]","<b>body_b_1\n <c>body_c_1\n <d2>body_d2\n </d2>\nbody_c_2\n </c>\nbody_b_2\n </b>\n",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("b [1]"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = current;
+ current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(1)","body_b_1\n ",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("body (1)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"c<[1]","<c>body_c_1\n <d2>body_d2\n </d2>\nbody_c_2\n </c>\n",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR +"a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "c" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ current.setName("c [1]"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = current;
+ current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(1)","body_c_1\n ",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "c" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ current.setName("body (1)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"d2<[1]","<d2>body_d2\n </d2>\n",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "c" + XMLStructureCreator.SIGN_SEPARATOR + "d2" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ current.setName("d2 [1]"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = current;
+ current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(1)","body_d2\n ",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "c" + XMLStructureCreator.SIGN_SEPARATOR + "d2" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ current.setName("body (1)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = (XMLChildren) parent.getParent();
+ current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(2)","\nbody_c_2\n ",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + "c" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+ current.setName("body (2)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = (XMLChildren) parent.getParent();
+ current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(2)","\nbody_b_2\n ",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + "b" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("body (2)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ parent = (XMLChildren) parent.getParent();
+ current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(2)","\nbody_a_2\n ",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ current.setName("body (2)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_ELEMENT,"b2<[1]","<b2>\n </b2>\n",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + "b2" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_ELEMENT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ current.setName("b2 [1]"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+ current = new XMLChildren(XMLStructureCreator.TYPE_TEXT,"body_(3)","\nbody_a_3\n",(XMLStructureCreator.ROOT_ID + XMLStructureCreator.SIGN_SEPARATOR + "a" + XMLStructureCreator.SIGN_SEPARATOR + XMLStructureCreator.SIGN_TEXT), fdoc, 0, 0); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ current.setName("body (2)"); //$NON-NLS-1$
+ parent.addChild(current);
+ current.setParent(parent);
+
+ checkTrees(Tree,ExpectedTree);
+ }
+
+ protected void checkTrees(XMLNode left, XMLNode right) {
+ if (left != null && right != null) {
+ //System.out.println(left.getName() + ", " + right.getName());
+ //System.out.println(">" + left.getValue() + "<\n>" + right.getValue() + "<");
+ assertTrue(left.testEquals(right));
+ Object[] leftChildren = left.getChildren();
+ Object[] rightChildren = right.getChildren();
+ if (leftChildren != null && rightChildren != null) {
+ if (leftChildren.length == rightChildren.length) {
+ for (int i=0; i<leftChildren.length; i++)
+ checkTrees((XMLNode) leftChildren[i], (XMLNode) rightChildren[i]);
+ } else
+ assertTrue(false);
+ }
+ } else if ( ((left == null) && (right != null)) || ((left != null) && (right == null)) ) {
+ assertTrue(false);
+ }
+ }
+}
+

Back to the top