KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > tax > XMLCloneTest


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.tax;
20
21 import java.lang.reflect.Constructor JavaDoc;
22 import java.lang.reflect.Field JavaDoc;
23 import java.lang.reflect.Modifier JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27 import junit.textui.TestRunner;
28 import org.netbeans.modules.xml.core.XMLDataObject;
29 import org.netbeans.modules.xml.tax.cookies.TreeEditorCookie;
30 import org.netbeans.tax.TreeNamedObjectMap.KeyListener;
31 import org.netbeans.tax.TreeDocumentType.DTDIdentity;
32 import org.netbeans.tax.event.TreeEventChangeSupport;
33 import org.netbeans.tax.event.TreeEventManager;
34 import org.netbeans.tests.xml.XTest;
35
36
37 /**
38  * <P>
39  * <P>
40  * <FONT COLOR="#CC3333" FACE="Courier New, Monospaced" SIZE="+1">
41  * <B>
42  * <BR> XML Module API Test: XMLCloneTest
43  * </B>
44  * </FONT>
45  * <BR><BR><B>What it tests:</B><BR>
46  *
47  * This test clones all nodes in tested document and checks whether the clone is properly created.
48  *
49  * <BR><BR><B>How it works:</B><BR>
50  *
51  * The test pass trough the document's tree and for each node makes its clone.
52  * On clones checks his nonstatic fields.
53  *
54  * <BR><BR><B>Settings:</B><BR>
55  * none<BR>
56  *
57  * <BR><BR><B>Output (Golden file):</B><BR>
58  * For each node one line with test result.<BR>
59  *
60  * <BR><B>To Do:</B><BR>
61  * none<BR>
62  *
63  * <P>Created on April 9, 2001, 12:33 PM
64  * <P>
65  */

66 public class XMLCloneTest extends XTest {
67     /** Creates new CoreSettingsTest */
68     public XMLCloneTest(String JavaDoc testName) {
69         super(testName);
70     }
71     
72     // Debug variables
73
private int maxCalls = 10000;
74     private int listCount = 0;
75     private int mapCount = 0;
76     private Class JavaDoc testedLevel;
77     
78     // fields' patterns
79
private Pattern[] patterns = new Pattern[] {
80         // clazz, name, isCloneRoot, checker
81
new Pattern(TreeParentNode.class, null, Boolean.TRUE, NullChecker.class),
82         new Pattern(TreeElement.class, "ownerElement", Boolean.TRUE, NullChecker.class),
83         new Pattern(KeyListener.class, "mapKeyListener", null, DifferentOrNullChecker.class),//???
84
new Pattern(TreeEventChangeSupport.class, null, null, DifferentOrNullChecker.class),
85         new Pattern(TreeEventManager.class, null, null, DifferentChecker.class),
86         new Pattern(String JavaDoc.class, null, null, ImmutableChecker.class),
87         new Pattern(TreeName.class, null, null, ImmutableChecker.class),
88         new Pattern(DTDIdentity.class, null, null, ImmutableChecker.class),
89     };
90     
91     public void testClone() throws Exception JavaDoc {
92         TreeEditorCookie cake = (TreeEditorCookie) TestUtil.THIS.findData("Bookss.xml").getCookie(TreeEditorCookie.class);
93         TreeDocument document = (TreeDocument) cake.openDocumentRoot();
94         nodeTest(document);
95     }
96     
97     private void nodeTest(TreeNode node) {
98         treeCloneTest(node);
99         // child test
100
if (node instanceof TreeParentNode) {
101             TreeChild child = ((TreeParentNode) node).getFirstChild();
102             while (child != null) {
103                 nodeTest(child);
104                 child = child.getNextSibling();
105             }
106         }
107         
108         // attribute test
109
if (node instanceof TreeElement && ((TreeElement) node).hasAttributes()) {
110             Iterator JavaDoc attributes = ((TreeElement) node).getAttributes().iterator();
111             while (attributes.hasNext()) {
112                 TreeNode attribute = (TreeNode) attributes.next();
113                 treeCloneTest(attribute);
114             }
115         }
116     }
117     
118     private void treeCloneTest(TreeNode treeNode) {
119         dbg.println("\n\n========> Creating clone of: " + treeNode + "::\n" + TestUtil.nodeToString(treeNode) + "\n\n");
120         
121         TreeNode treeClone = (TreeNode) treeNode.clone();
122         nodeCloneTest(treeNode, treeClone, true);
123     }
124     
125     private void nodeCloneTest(Object JavaDoc node, Object JavaDoc clone, boolean isCloneRoot) {
126         dbg.println("\nNode: " + node + "\n<<<\n" + TestUtil.nodeToString(node) + "\n>>>");
127         Class JavaDoc clazz = node.getClass();
128         do {
129             cloneLevelCheck(clazz, node, clone, isCloneRoot);
130             clazz = clazz.getSuperclass();
131         } while (clazz != null);
132         
133         // child test
134
if (node instanceof TreeParentNode) {
135             TreeChild childNode = ((TreeParentNode) node).getFirstChild();
136             TreeChild childClone = ((TreeParentNode) clone).getFirstChild();
137             while (childNode != null) {
138                 if (childClone == null) {
139                     err("Missing clone child: " + TestUtil.nodeToString(childNode)
140                     + "\nIn clone: " + TestUtil.nodeToString(clone), node);
141                     break;
142                 }
143                 nodeCloneTest(childNode, childClone, false);
144                 childNode = childNode.getNextSibling();
145                 childClone = childClone.getNextSibling();
146             }
147         }
148         
149         // attribute test
150
if (node instanceof TreeElement && ((TreeElement) node).hasAttributes()) {
151             Iterator JavaDoc nodeAtrs = ((TreeElement) node).getAttributes().iterator();
152             Iterator JavaDoc cloneAtrs = ((TreeElement) clone).getAttributes().iterator();
153             while (nodeAtrs.hasNext()) {
154                 TreeNode nodeAtr = (TreeNode) nodeAtrs.next();
155                 TreeNode cloneAtr = (TreeNode) cloneAtrs.next();
156                 nodeCloneTest(nodeAtr, cloneAtr, false);
157             }
158         }
159     }
160     
161     private void cloneLevelCheck(Class JavaDoc clazz, Object JavaDoc node, Object JavaDoc clone, boolean isCloneRoot) {
162         if (maxCalls-- < 0) {//!!!
163
System.exit(1);
164         }
165         
166         dbg.println("Level: " + clazz);
167         testedLevel = clazz;
168         Field JavaDoc[] fields = clazz.getDeclaredFields();
169         Class JavaDoc checker;
170         String JavaDoc name;
171         
172         for (int i = 0; i < fields.length; i++) {
173             if (Modifier.isStatic(fields[i].getModifiers())) {
174                 continue;
175             }
176             
177             // Checks TreeObjectList
178
if (fields[i].getType() == TreeObjectList.class) {
179                 dbg.println("\n#" + listCount++ + ") CHECKING TREE_OBJECT_LIST: " + fields[i].getName());
180                 try {
181                     // Get lists.
182
Field JavaDoc listField = TreeObjectList.class.getDeclaredField("list");
183                     listField.setAccessible(true);
184                     fields[i].setAccessible(true);
185                     List JavaDoc nodeList = (List JavaDoc) listField.get(fields[i].get(node));
186                     List JavaDoc cloneList = (List JavaDoc) listField.get(fields[i].get(clone));
187                     
188                     // Test lists' elements
189
if (isComparable(nodeList, cloneList, node)) {
190                         for (int j = 0; j < nodeList.size(); j++) {
191                             nodeCloneTest((TreeNode) nodeList.get(j), (TreeNode) cloneList.get(j), false);
192                         }
193                     }
194                 } catch (Exception JavaDoc ex) {
195                     err("In TreeObjectList Check", node);
196                     ex.printStackTrace(dbg);
197                 } finally {
198                     dbg.println("/#" + --listCount + ") END CHECK\n");
199                 }
200             }
201             
202             // Checks TreeNamedObjectMap
203
if (fields[i].getType() == TreeNamedObjectMap.class) {
204                 Object JavaDoc key = null;
205                 
206                 dbg.println("\n@" + mapCount++ + ") CHECKING TREE_NAMED_OBJECT_MAP: " + fields[i].getName());
207                 try {
208                     // Get maps
209
Field JavaDoc mapField = TreeNamedObjectMap.class.getDeclaredField("map");
210                     mapField.setAccessible(true);
211                     fields[i].setAccessible(true);
212                     Map JavaDoc nodeMap = (Map JavaDoc) mapField.get(fields[i].get(node));
213                     Map JavaDoc cloneMap = (Map JavaDoc) mapField.get(fields[i].get(clone));
214                     
215                     // Test maps' elements
216
if (isComparable(nodeMap, cloneMap, node)) {
217                         
218                         Object JavaDoc[] keys = nodeMap.keySet().toArray();
219                         for (int j = 0; j < keys.length; j++) {
220                             key = keys[j];
221                             nodeCloneTest(nodeMap.get(key), cloneMap.get(key), false);
222                         }
223                     }
224                 } catch (Exception JavaDoc ex) {
225                     err("In TreeNamedObjectMap Check: key = \"" + key + "\"", node);
226                     ex.printStackTrace(dbg);
227                 } finally {
228                     dbg.println("/@" + --mapCount + ") END CHECK\n");
229                 }
230             }
231             
232             // find checker and check
233
checker = DefaultChecker.class;
234             for (int j = 0; j < patterns.length; j++) {
235                 if (patterns[j].compare(fields[i].getType(), fields[i].getName(), isCloneRoot)) {
236                     checker = patterns[j].getChecker();
237                     break;
238                 }
239             }
240             newCheckerInstace(checker, fields[i], node, clone).check();
241         }
242     }
243     
244     private boolean isComparable(List JavaDoc nodeList, List JavaDoc cloneList, Object JavaDoc node) {
245         if (cloneList == null && nodeList == null) {
246             return false;
247             
248         } else if (cloneList == null || nodeList == null) {
249             err("List is Null:"
250             + "\nnodeList = " + nodeList
251             + "\ncloneList = " + cloneList, node);
252             return false;
253             
254         } else if (nodeList.size() != cloneList.size()) {
255             err("Lists have different size:"
256             + "\nnodeList.size() = " + nodeList.size()
257             + "\ncloneList.size() = " + cloneList.size(), node);
258             return false;
259         }
260         
261         return true;
262     }
263     
264     private boolean isComparable(Map JavaDoc nodeMap, Map JavaDoc cloneMap, Object JavaDoc node) {
265         if (cloneMap == null && nodeMap == null) {
266             return false;
267             
268         } else if (nodeMap != null && nodeMap.size() == 0 && cloneMap == null) {
269             return false;
270             
271         } else if (cloneMap == null || nodeMap == null) {
272             err("Map is Null:"
273             + "\nnodeMap = " + nodeMap
274             + "\ncloneMap = " + cloneMap, node);
275             return false;
276             
277         } else if (nodeMap.size() != cloneMap.size()) {
278             err("Maps have different size:"
279             + "\nnodeMap.size() = " + nodeMap.size()
280             + "\ncloneMap.size() = " + cloneMap.size(), node);
281             return false;
282         }
283         
284         return true;
285     }
286     
287     private FieldChecker newCheckerInstace(Class JavaDoc clazz, Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
288         try {
289             Constructor JavaDoc constructor = clazz.getDeclaredConstructor(new Class JavaDoc[] {XMLCloneTest.class, Field JavaDoc.class, Object JavaDoc.class, Object JavaDoc.class});
290             return (FieldChecker) constructor.newInstance(new Object JavaDoc[] {this, field, node, clone});
291         } catch (Exception JavaDoc e) {
292             e.printStackTrace(dbg);
293             return null;
294         }
295     }
296     
297     private String JavaDoc toStr(Object JavaDoc obj) {
298         String JavaDoc str = null;
299         if (obj instanceof TreeNode) {
300             try {
301                 str = TestUtil.nodeToString((TreeNode) obj);
302             } catch (Exception JavaDoc e) {};
303         } else {
304             str = "" + obj;
305         }
306         return str;
307     }
308     
309     protected void err(String JavaDoc message, Object JavaDoc node) {
310         message =
311         "\n!!! ERROR:" + message
312         + "======================================================>"
313         + "Node: " + TestUtil.nodeToString(node)
314         + "Level: " + testedLevel;
315         
316         fail(message);
317     }
318     
319     protected String JavaDoc xmlTestName() {
320         return "XML-Clone-Test";
321     }
322     
323     /**
324      * Performs this testsuite.
325      * @param args the command line arguments
326      */

327     public static void main(String JavaDoc args[]) {
328         DEBUG = true;
329         TestRunner.run(XMLCloneTest.class);
330     }
331     
332     //@@@@
333

334     private class Pattern {
335         private Class JavaDoc _clazz;
336         private String JavaDoc _name;
337         private Boolean JavaDoc _isCloneRoot;
338         private Class JavaDoc _checker;
339         
340         public Pattern(Class JavaDoc clazz, String JavaDoc name, Boolean JavaDoc isCloneRoot, Class JavaDoc checker) {
341             _clazz = clazz;
342             _name = name;
343             _isCloneRoot = isCloneRoot;
344             _checker = checker;
345         }
346         
347         public boolean compare(Class JavaDoc clazz, String JavaDoc name, boolean isCloneRoot) {
348             return
349             ((_clazz == null) || (_clazz == clazz))
350             && ((_isCloneRoot == null) || (_isCloneRoot.booleanValue() == isCloneRoot))
351             && ((_name == null) || (_name.indexOf(name) != -1));
352         }
353         
354         public Class JavaDoc getChecker() {
355             return _checker;
356         }
357     }
358     
359     private abstract class FieldChecker {
360         protected Field JavaDoc field;
361         protected Object JavaDoc node;
362         protected Object JavaDoc clone;
363         
364         public FieldChecker(Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
365             this.field = field;
366             this.node = node;
367             this.clone = clone;
368             this.field.setAccessible(true);
369         }
370         
371         public boolean check() {
372             if (test()) {
373                 dbg.println(prefix() + "Field \"" + field.getType().getName() + "::" + field.getName() + "\" is OK");
374                 return true;
375             } else {
376                 reportErr();
377                 return false;
378             }
379         }
380         
381         protected boolean isBothNull() {
382             return (fieldFrom(node) == null) && (fieldFrom(clone) == null);
383         }
384         
385         protected boolean hasDifferentID() {
386             return fieldFrom(node) != fieldFrom(clone);
387         }
388         
389         protected boolean hasSameValue() {
390             if (field.getClass().isPrimitive())
391                 return fieldFrom(node).equals(fieldFrom(clone));
392             else if ((fieldFrom(node) != null) && (fieldFrom(clone) == null)) {//!!!
393
return false;
394             }
395             return true;
396         }
397         
398         protected Object JavaDoc fieldFrom(Object JavaDoc obj) {
399             Object JavaDoc result = null;
400             try {
401                 result = field.get(obj);
402             } catch (Exception JavaDoc e) {
403                 e.printStackTrace(dbg);
404             }
405             return result;
406         }
407         
408         private void reportErr() {
409             String JavaDoc clazz;
410             
411             if (fieldFrom(node) != null) {
412                 clazz = fieldFrom(node).getClass().getName();
413             } else {
414                 clazz = "Null.clazz";
415             }
416             
417             err(prefix()
418             + "\nClone error in field: \"" + field.getType().getName() + "::" + field.getName() + "\"."
419             + "\nclazz : " + clazz
420             + "\noriginal value: " + toStr(fieldFrom(node))
421             + "\nclone value : " + toStr(fieldFrom(clone))
422             + "\noriginal ID : " + System.identityHashCode(fieldFrom(node))
423             + "\nclone ID : " + System.identityHashCode(fieldFrom(clone))
424             + "\nhasDifferentID: " + hasDifferentID()
425             + "\nhasSameValue : " + hasSameValue()
426             + "\nisBoothNull : " + isBothNull()
427             , node
428             );
429         }
430         
431         protected abstract boolean test();
432         
433         protected abstract String JavaDoc prefix();
434     }
435     
436     /**
437      * Check whether the fields have (different identity and identical value)
438      * or are both Null.
439      */

440     private class DefaultChecker extends FieldChecker {
441         
442         public DefaultChecker(Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
443             super(field, node, clone);
444         }
445         
446         protected boolean test() {
447             /*
448             if (field.getName().equals("parentNode")) {
449                 System.out.println("parentNode on Node:" + fieldFrom(node));
450                 System.out.println("parentNode on Clone:" + fieldFrom(clone));
451                 return false;
452             }
453              */

454             return (hasDifferentID() && hasSameValue()) || isBothNull();
455         }
456         
457         protected String JavaDoc prefix() {
458             return "DEFAULT : ";
459         }
460     }
461     
462     /**
463      * Check nothing, check() always return true.
464      */

465     private class EmptyChecker extends FieldChecker {
466         
467         public EmptyChecker(Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
468             super(field, node, clone);
469         }
470         
471         protected boolean test() {
472             return true;
473         }
474         
475         protected String JavaDoc prefix() {
476             return "EMPTY : ";
477         }
478     }
479     
480     /**
481      * Check whether the clone's field is Null without reference to original filed.
482      */

483     private class NullChecker extends FieldChecker {
484         
485         public NullChecker(Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
486             super(field, node, clone);
487         }
488         
489         protected boolean test() {
490             return fieldFrom(clone) == null;
491         }
492         
493         protected String JavaDoc prefix() {
494             return "NULL : ";
495         }
496     }
497     
498     /**
499      * Check whether the fields have same identity.
500      */

501     private class ImmutableChecker extends FieldChecker {
502         
503         public ImmutableChecker(Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
504             super(field, node, clone);
505         }
506         
507         protected boolean test() {
508             return fieldFrom(clone) == fieldFrom(node);
509         }
510         
511         protected String JavaDoc prefix() {
512             return "IMMUTABLE: ";
513         }
514     }
515     
516     /**
517      * Check whether the fields have different identity.
518      */

519     private class DifferentOrNullChecker extends FieldChecker {
520         
521         public DifferentOrNullChecker(Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
522             super(field, node, clone);
523         }
524         
525         protected boolean test() {
526             return (fieldFrom(clone) != fieldFrom(node) || (fieldFrom(clone) == null && fieldFrom(node) == null));
527         }
528         
529         protected String JavaDoc prefix() {
530             return "DIFFERENT_OR_NULL: ";
531         }
532     }
533     
534     /**
535      * Check whether the fields have different identity.
536      */

537     private class DifferentChecker extends FieldChecker {
538         
539         public DifferentChecker(Field JavaDoc field, Object JavaDoc node, Object JavaDoc clone) {
540             super(field, node, clone);
541         }
542         
543         protected boolean test() {
544             return fieldFrom(clone) != fieldFrom(node);
545         }
546         
547         protected String JavaDoc prefix() {
548             return "DIFFERENT: ";
549         }
550     }
551 }
552
Popular Tags