]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
764e21668429451279215aac14955645288c2d7f
[tmp/jakarta-migration.git] /
1 /**\r
2  * This document is a part of the source code and related artifacts\r
3  * for CollectionSpace, an open source collections management system\r
4  * for museums and related institutions:\r
5  *\r
6  * http://www.collectionspace.org\r
7  * http://wiki.collectionspace.org\r
8  *\r
9  * Copyright (c) 2009 Regents of the University of California\r
10  *\r
11  * Licensed under the Educational Community License (ECL), Version 2.0.\r
12  * You may not use this file except in compliance with this License.\r
13  *\r
14  * You may obtain a copy of the ECL 2.0 License at\r
15  * https://source.collectionspace.org/collection-space/LICENSE.txt\r
16  *\r
17  *  Unless required by applicable law or agreed to in writing, software\r
18  *  distributed under the License is distributed on an "AS IS" BASIS,\r
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
20  *  See the License for the specific language governing permissions and\r
21  *  limitations under the License.\r
22  */\r
23 package org.collectionspace.services.IntegrationTests.xmlreplay;\r
24 \r
25 import org.collectionspace.services.common.api.Tools;\r
26 import org.jdom.Document;\r
27 import org.jdom.Element;\r
28 import org.jdom.JDOMException;\r
29 import org.jdom.Namespace;\r
30 import org.jdom.input.SAXBuilder;\r
31 import org.jaxen.XPath;\r
32 import org.jaxen.jdom.JDOMXPath;\r
33 \r
34 \r
35 import java.io.IOException;\r
36 import java.io.StringReader;\r
37 import java.util.ArrayList;\r
38 import java.util.HashMap;\r
39 import java.util.List;\r
40 import java.util.Map;\r
41 \r
42 import org.collectionspace.services.IntegrationTests.xmlreplay.TreeWalkResults.TreeWalkEntry;\r
43 import org.jdom.output.XMLOutputter;\r
44 \r
45 /**\r
46  * User: laramie\r
47  * $LastChangedRevision:  $\r
48  * $LastChangedDate:  $\r
49  */\r
50 public class XmlCompareJdom {\r
51 \r
52 private static final String DEFAULT_SAX_DRIVER_CLASS = "org.apache.xerces.parsers.SAXParser";\r
53 \r
54     public static org.jdom.Document getDocumentFromContent(String source) throws IOException, JDOMException {\r
55         org.jdom.Document doc;\r
56         SAXBuilder builder;\r
57         builder = new SAXBuilder();\r
58         builder.setValidation(false); //has no effect, I think.\r
59         doc = builder.build(new StringReader(source));\r
60         return doc;\r
61     }\r
62 \r
63     public static TreeWalkResults compareParts(String expectedContent, String leftID, String actualPartContent, String rightID){\r
64 \r
65         System.out.println("expected: \r\n"+expectedContent+"\r\n\r\n");\r
66         System.out.println("ACTUAL: \r\n"+actualPartContent);\r
67 \r
68         TreeWalkResults list = new TreeWalkResults();\r
69         try {\r
70 \r
71             list.leftID = leftID;\r
72             list.rightID = rightID;\r
73             TreeWalkResults.TreeWalkEntry infoentry = new TreeWalkResults.TreeWalkEntry();\r
74             infoentry.status = TreeWalkResults.TreeWalkEntry.STATUS.INFO;\r
75             infoentry.message = "\r\n    LEFT file: "+leftID+"\r\n    RIGHT file: "+rightID;\r
76             list.add(infoentry);\r
77             if (Tools.isEmpty(expectedContent)){\r
78                 TreeWalkEntry entry = new TreeWalkEntry();\r
79                 entry.status = TreeWalkEntry.STATUS.DOC_ERROR;\r
80                 entry.errmessage = "L dom was empty.";\r
81                 list.add(entry);\r
82             } else if (Tools.isEmpty(actualPartContent)){\r
83                 TreeWalkEntry entry = new TreeWalkEntry();\r
84                 entry.errmessage = "R dom was empty.";\r
85                 entry.status = TreeWalkEntry.STATUS.DOC_ERROR;\r
86                 list.add(entry);\r
87             } else {\r
88                 Document expected = getDocumentFromContent(expectedContent);\r
89                 Document actual = getDocumentFromContent(actualPartContent);\r
90                 treeWalk(expected, actual, list);\r
91             }\r
92         } catch (Throwable t){\r
93             String msg = "ERROR in XmlReplay.compareParts(): "+t;\r
94             System.out.println(msg);\r
95             TreeWalkEntry entry = new TreeWalkEntry();\r
96                 entry.status = TreeWalkEntry.STATUS.DOC_ERROR;\r
97                 entry.errmessage = msg;\r
98                 list.add(entry);\r
99         }\r
100         return list;\r
101     }\r
102 \r
103     public static List select(Element element, String xpathExpression, Namespace namespace) throws Exception {\r
104         XPath xpath = new JDOMXPath(xpathExpression);\r
105         String prefix = namespace.getPrefix();\r
106         String uri = namespace.getURI();\r
107         xpath.addNamespace(prefix, uri);\r
108         return xpath.selectNodes(element);\r
109     }\r
110 \r
111     public static Object selectSingleNode(Element element, String xpathExpression, Namespace namespace) throws Exception {\r
112         XPath xpath = new JDOMXPath(xpathExpression);\r
113         if (namespace != null) {\r
114             String prefix = namespace.getPrefix();\r
115             String uri = namespace.getURI();\r
116             xpath.addNamespace(prefix, uri);\r
117         }\r
118         return xpath.selectSingleNode(element);\r
119     }\r
120 \r
121     public static Object selectSingleNode(String docSource, String xpathExpression, Namespace namespace) throws Exception {\r
122         Document doc = getDocumentFromContent(docSource);\r
123         Element element = doc.getRootElement();\r
124         XPath xpath = new JDOMXPath(xpathExpression);\r
125         if (namespace != null) {\r
126             String prefix = namespace.getPrefix();\r
127             String uri = namespace.getURI();\r
128             xpath.addNamespace(prefix, uri);\r
129         }\r
130         return xpath.selectSingleNode(element);\r
131     }\r
132 \r
133     public static boolean treeWalk(Document left, Document right, TreeWalkResults list) throws Exception {\r
134         boolean res = treeWalk(left.getRootElement(), right.getRootElement(), "/", list);\r
135         return res;\r
136     }\r
137 \r
138     public static boolean treeWalk(Element left, Element right, String parentPath, TreeWalkResults msgList) throws Exception {\r
139         String SPACE = "     ";\r
140         if (left == null && right == null){\r
141             return true;\r
142         }\r
143         if (left == null){\r
144             return false;\r
145         }\r
146         if (right == null){\r
147             return false;\r
148         }\r
149         List l = left.getChildren();\r
150         Map foundRightMap = new HashMap();\r
151         List<String> foundRepeatingList = new ArrayList<String>();\r
152         boolean result = true;\r
153         for (Object o : l) {\r
154             if (!(o instanceof Element)){\r
155                 continue;\r
156             }\r
157             Element leftChild = (Element)o;\r
158             //String leftChildName = leftChild.getName();\r
159             String leftChildName = leftChild.getQualifiedName();\r
160             if (Tools.isEmpty(leftChildName)){\r
161                 continue;\r
162             }\r
163 \r
164             Namespace namespace =  leftChild.getNamespace();\r
165 \r
166             String leftChildPath = Tools.glue(parentPath, "/", leftChildName);\r
167 \r
168             if (foundRepeatingList.indexOf(leftChildPath)>=0){\r
169                 continue;\r
170             }\r
171             List leftlist = select(left, leftChildName, namespace);\r
172             if (leftlist != null && leftlist.size() > 1){\r
173                 //System.out.println("-----------------doRepeating------"+leftChildPath);\r
174                 foundRepeatingList.add(leftChildPath);\r
175                 boolean repeatingIdentical =\r
176                     doRepeatingFieldComparison(leftlist, leftChildPath, leftChildName, left, right, msgList, namespace) ; //todo: deal with foundRightMap in this repeating field block.\r
177                 if ( ! repeatingIdentical ){\r
178                     //System.out.println("\r\n\r\n\r\n*****************************\r\nOne repeating field failed: "+msgList);\r
179                     return false;\r
180                 }\r
181                 foundRightMap.put(leftChildName, "OK");\r
182             } else {\r
183                 Element rightChild  = (Element)selectSingleNode(right,leftChildName, namespace);\r
184                 if (rightChild == null){\r
185                     TreeWalkEntry entry = new TreeWalkEntry();\r
186                     entry.lpath = leftChildPath;                  //this works, but is questionable: selectSingleNode(right, "//*[local-name() = \"objectexit_common\"]")\r
187                     entry.status = TreeWalkEntry.STATUS.R_MISSING;\r
188                     msgList.add(entry);\r
189                     continue;\r
190                 }\r
191                 foundRightMap.put(leftChildName, "OK");\r
192                 String leftChildTextTrim = leftChild.getText().trim();\r
193                 String rightChildTextTrim = rightChild.getText().trim();\r
194                 TreeWalkEntry entry = new TreeWalkEntry();\r
195                 entry.ltextTrimmed = leftChildTextTrim;\r
196                 entry.rtextTrimmed = rightChildTextTrim;\r
197                 entry.lpath = leftChildPath;\r
198                 entry.rpath = leftChildPath; //same\r
199 \r
200                 if (leftChildTextTrim.equals(rightChildTextTrim)){\r
201                     entry.status = TreeWalkEntry.STATUS.MATCHED;\r
202                     msgList.add(entry);\r
203                 } else {\r
204                     entry.status = TreeWalkEntry.STATUS.TEXT_DIFFERENT;\r
205                     msgList.add(entry);\r
206                 }\r
207                 //============ DIVE !! =====================================================\r
208                 result = result && treeWalk( leftChild, rightChild, leftChildPath, msgList);\r
209             }\r
210         }\r
211         for (Object r : right.getChildren()){\r
212             if (!(r instanceof Element)){\r
213                 continue;\r
214             }\r
215             Element rightChild = (Element)r;\r
216             String rname = rightChild.getQualifiedName();\r
217             if (null==foundRightMap.get(rname)){\r
218                 String rightChildPath = Tools.glue(parentPath, "/", rname);\r
219 \r
220                 TreeWalkEntry entry = new TreeWalkEntry();\r
221                 entry.rpath = rightChildPath;\r
222                 entry.status = TreeWalkEntry.STATUS.R_ADDED;\r
223                 msgList.add(entry);\r
224             }\r
225         }\r
226         return true;\r
227     }\r
228 \r
229     private static void dumpXML_OUT(Element el) throws Exception {\r
230         XMLOutputter outputter = new XMLOutputter();\r
231         outputter.output(el, System.out);\r
232     }\r
233     private static String dumpXML(Element el) throws Exception {\r
234         XMLOutputter outputter = new XMLOutputter();\r
235         return outputter.outputString(el);\r
236     }\r
237 \r
238     public static boolean doRepeatingFieldComparison(List leftList, String leftChildPath, String leftChildName, Element left, Element right, TreeWalkResults msgList, Namespace namespace)\r
239     throws Exception {\r
240         //todo: deal with foundRightMap in this repeating field block.\r
241         List rightList = select(right, leftChildName, namespace);\r
242         if (rightList == null || rightList.size() == 0 || rightList.size() < leftList.size()){\r
243             TreeWalkEntry twe = new TreeWalkEntry();\r
244             twe.lpath = leftChildPath;\r
245             twe.status = TreeWalkEntry.STATUS.R_MISSING;\r
246             String rmsg = (rightList == null)\r
247                     ? " Right: 0"\r
248                     : " Right: "+rightList.size();\r
249             twe.message = "Repeating field count not matched. Field: "+leftChildPath+" Left: "+leftList.size()+rmsg;\r
250             msgList.add(twe);\r
251             return false;\r
252         }\r
253         if (rightList.size() > leftList.size()){\r
254             TreeWalkEntry twe = new TreeWalkEntry();\r
255             twe.lpath = leftChildPath;\r
256             twe.status = TreeWalkEntry.STATUS.R_ADDED;\r
257             twe.message = "Repeating field count not matched. Field: "+leftChildPath+" Left: "+leftList.size()+" Right: "+rightList.size();\r
258             msgList.add(twe);\r
259             return false;\r
260         }\r
261 \r
262         for (Object le : leftList){\r
263             boolean found = false;\r
264             Element leftEl = (Element)le;\r
265             //pl("left", leftEl);\r
266             for(Object re : rightList){\r
267                 Element rightEl = (Element)re;\r
268                 //pl("right", rightEl);\r
269                 TreeWalkResults msgListInner = new TreeWalkResults();\r
270                 treeWalk(leftEl, rightEl, leftChildPath, msgListInner);\r
271                 if (msgListInner.isStrictMatch()){\r
272                     found = true;\r
273                     TreeWalkEntry twe = new TreeWalkEntry();\r
274                     twe.lpath = leftChildPath;\r
275                     twe.status = TreeWalkEntry.STATUS.MATCHED;\r
276                     msgList.add(twe);\r
277                     //System.out.println("===========================\r\nfound match for "+leftEl+"\r\n===========================\r\n");\r
278                     rightList.remove(re); //found it, don't need to inspect this element again.  Since we are breaking from loop, removing element won't mess up iterator--we get a new one on the next loop.\r
279                     break;\r
280                 }\r
281             }\r
282             if ( ! found){\r
283                 TreeWalkEntry twe = new TreeWalkEntry();\r
284                 twe.lpath = leftChildPath;\r
285                 twe.status = TreeWalkEntry.STATUS.R_MISSING;\r
286                 twe.message = "Repeating field not matched. Source: {"+dumpXML(leftEl)+"}";\r
287                 msgList.add(twe);\r
288                 return false;\r
289             }\r
290         }\r
291         return true;\r
292     }\r
293 \r
294     private static void pl(String name, Element el) throws Exception {\r
295         Namespace namespace = el.getNamespace();\r
296         Object lobid = selectSingleNode(el, "@ID", namespace);\r
297         String lid = "";\r
298         if (lobid!=null){\r
299             lid = lobid.toString();\r
300         }\r
301 \r
302         System.out.println(name+": "+lid);\r
303         dumpXML_OUT(el);\r
304         System.out.println();\r
305 \r
306     }\r
307 }\r