1 19 20 package org.netbeans.mdr.test; 21 22 import java.util.*; 23 import java.io.*; 24 import java.net.URL ; 25 26 import org.xml.sax.*; 27 import org.w3c.dom.*; 28 29 import javax.xml.parsers.*; 30 31 import org.netbeans.lib.jmi.util.*; 32 33 import javax.jmi.reflect.*; 34 import javax.jmi.model.*; 35 36 public class XMIComparator extends Object { 37 38 private static final char ELEMENT_START = '['; 40 private static final char ELEMENT_END = ']'; 42 private static final char LEFT_SEPARATOR = '('; 44 private static final char RIGHT_SEPARATOR = ')'; 46 private static final char COMMENT_MARKER = '#'; 48 49 private CodeComparator codeComparator = new CodeComparator (); 50 51 53 public XMIComparator() { 54 } 55 56 58 71 public String compareDocuments (InputSource streamOne, InputSource streamTwo) { 72 try { 73 Document docOne = parse (streamOne, null); 74 Document docTwo = parse (streamTwo, null); 75 Node xmiNode = findSubnodeByName (docOne, "XMI"); 76 Node contentNode = findSubnodeByName (xmiNode, "XMI.content"); 77 String codeOne = treeCode (contentNode); 78 79 xmiNode = findSubnodeByName (docTwo, "XMI"); 80 contentNode = findSubnodeByName (xmiNode, "XMI.content"); 81 String codeTwo = treeCode (contentNode); 82 83 if (removeComments (codeOne).equals (removeComments (codeTwo))) 84 return null; 85 String el = findDifference (codeOne, codeTwo); 86 return "Trees are not identical, element: " + el; 87 } catch (Exception e) { 88 e.printStackTrace (); 89 return "Cannot parse documnet"; 90 } 91 } 92 93 97 private String findDifference (String c1, String c2) { 98 int x = 0; 99 int length = Math.min (c1.length (), c2.length ()); 100 for (x = 0; x < c1.length (); x++) 101 if (c1.charAt (x) != c2.charAt (x)) 102 break; 103 while (c1.charAt (x) != ELEMENT_START) 104 x--; 105 String name = ""; 106 x++; 107 while (c1.charAt (x) != ELEMENT_END) { 108 name = name + c1.charAt (x); 109 x++; 110 } 111 return name; 112 } 113 114 117 private Node findSubnodeByName (Node node, String name) { 118 NodeList subNodes = node.getChildNodes (); 119 for (int x = 0; x < subNodes.getLength (); x++) { 120 Node temp = subNodes.item (x); 121 if (temp.getNodeName ().equals (name)) 122 return temp; 123 } return null; 125 } 126 127 130 private String treeCode (Node node) { 131 if (node.getNodeType () == Node.TEXT_NODE) { 132 String text = node.getNodeValue (); 133 String res = ""; 134 for (int x = 0; x < text.length (); x++) 135 if (!Character.isWhitespace (text.charAt (x))) 136 res = res + text.charAt (x); 137 return res; 138 } 139 if (node.getNodeType () != Node.ELEMENT_NODE) 140 return ""; List list = new LinkedList (); 142 String nodeName = node.getNodeName (); 143 NamedNodeMap attrs = node.getAttributes (); 144 String xmiId = null; 145 for (int x = 0; x < attrs.getLength (); x++) { 146 Node attr = attrs.item (x); 147 String name = attr.getNodeName (); 148 if (name.equals ("xmi.id")) 149 xmiId = attr.getNodeValue (); 150 String value = attr.getNodeValue (); 151 if (value.startsWith ("xmi.")) { 152 value = "xmi."; 153 } list.add (name); } String attributesCode = listToString (list); 157 list = new LinkedList (); 158 NodeList subNodes = node.getChildNodes (); 159 for (int x = 0; x < subNodes.getLength (); x++) { 160 String s = treeCode (subNodes.item (x)); 161 if (s.length () > 0) 162 list.add (s); 163 } String subNodesCode = listToString (list); 165 String comment = ""; 166 if (xmiId != null) 167 comment = " " + COMMENT_MARKER + xmiId + COMMENT_MARKER; 168 return LEFT_SEPARATOR + " " + ELEMENT_START + nodeName + comment + ELEMENT_END + attributesCode + 169 " " + subNodesCode + RIGHT_SEPARATOR; 170 } 171 172 175 private String listToString (List list) { 176 Collections.sort (list, codeComparator); 177 String res = ""; 178 Iterator iter = list.iterator (); 179 while (iter.hasNext ()) { 180 res = res + " " + (String ) iter.next (); 181 } 182 return res; 183 } 184 185 188 private Document parse (InputSource is, String encoding) throws IOException, SAXException, ParserConfigurationException { 189 Document result = null; 190 DocumentBuilderFactory bfact = DocumentBuilderFactory.newInstance(); 191 bfact.setValidating(false); 192 DocumentBuilder docBuilder = bfact.newDocumentBuilder(); 193 docBuilder.setEntityResolver(DummyER.getInstance()); 194 if (encoding != null) is.setEncoding(encoding); 195 result = docBuilder.parse(is); 196 return result; 197 } 198 199 private static String removeComments (String code) { 200 StringBuffer res = new StringBuffer (code.length ()); 201 boolean inComment = false; 202 for (int x = 0; x < code.length (); x++) { 203 char c = code.charAt (x); 204 if (c == COMMENT_MARKER) 205 inComment = !inComment; 206 else if (!inComment) 207 res.append(c); 208 } return res.toString (); 210 } 211 212 private static class DummyER implements EntityResolver { 214 private static EntityResolver instance = new DummyER(); 215 216 public static EntityResolver getInstance() { 217 return instance; 218 } 219 220 public InputSource resolveEntity(String publicID, String systemID) { 221 return new InputSource(new StringReader("")); 222 } 223 } 224 225 private static class CodeComparator implements Comparator { 226 227 public int compare(Object obj1, Object obj2) { 228 String s1 = removeComments ((String ) obj1); 229 String s2 = removeComments ((String ) obj2); 230 return s1.compareTo(s2); 231 } 232 233 } 234 235 } 236 | Popular Tags |