1 package org.objectweb.modfact.jmi.xmi; 2 3 import javax.xml.parsers.*; 4 5 import org.objectweb.modfact.jmi.reflect.ReflectHelper; 6 import org.w3c.dom.*; 7 8 import org.objectweb.modfact.jmi.xmi.PropertyTypeManager.TypeInfo; 9 import javax.jmi.reflect.*; 10 import java.util.*; 11 import java.io.*; 12 13 14 15 public class XmiParser { 16 17 static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 18 static DocumentBuilder builder; 19 static { 20 try { 21 builder = documentBuilderFactory.newDocumentBuilder(); 22 } catch(Exception e) { 23 System.err.println("Couldnot initialize DOM Parser"); 24 throw new RuntimeException (e); 25 } 26 } 27 28 29 Document document; 30 Node rootNode; 31 32 Hashtable id_object = new Hashtable(); 34 List unresolvedProps = new Vector(); 35 36 RefPackage extent; 37 ObjectFactoryManager factManager; 38 39 XmiReaderImpl caller; 40 41 static Object lock = ""; 42 XmiParser(XmiReaderImpl owner, RefPackage p, InputStream in) { 43 this.caller = owner; 44 this.extent = p; 45 try { 46 synchronized(lock) { 47 document = builder.parse(in); 48 rootNode = document.getDocumentElement().getElementsByTagName("XMI.content").item(0); 49 } 50 } catch(Exception e) { 51 throw new RuntimeException (e); 52 } 53 } 54 55 private Set createdObjects = new HashSet() { 56 public boolean add(Object o) { 57 if(o==null) { 58 throw new RuntimeException ("cannot add null"); 59 } 60 return super.add(o); 61 } 62 }; 63 64 void run() { 65 extent = extent.refOutermostPackage(); 66 factManager = new ObjectFactoryManager(extent); 67 68 Node xmi_content = document.getElementsByTagName("XMI.content").item(0); 69 NodeList children = xmi_content.getChildNodes(); 70 for (int i=0; i < children.getLength(); i++) { 71 Node node = children.item(i); 72 if(node instanceof Element) { 73 process1((Element) node); 74 } 75 } 76 77 Iterator it = elements.iterator(); 78 while(it.hasNext()) { 79 process2((Element)it.next()); 80 } 81 } 82 83 Collection getOuterMostObjects() { 84 Collection r = new HashSet(); 85 Iterator it = createdObjects.iterator(); 86 while(it.hasNext()) { 87 RefObject o = (RefObject) it.next(); 88 RefBaseObject outer = o.refOutermostComposite(); 89 90 if(outer instanceof RefObject) r.add(outer); 91 } 92 return r; 93 } 94 95 96 97 98 99 100 List elements = new Vector(); 102 103 void process1(Element elem) { 106 107 String xmi_id = elem.getAttribute("xmi.id"); 108 String elemName = ReflectHelper.unqualifiedName(elem.getTagName()); 109 RefObject o; 110 111 if(!"".equals(xmi_id)) { 112 o = doCorbaType(xmi_id, elemName, elem); 114 if(o==null) { 115 if(caller.verbose) System.err.println("creating object '" +elem.getTagName() +"' xmi.id=" +xmi_id ); 116 o = createObject(elem); 117 if(o!=null) { 118 id_object.put(xmi_id, o); 119 elements.add(elem); } 121 } 122 } 123 124 NodeList children = elem.getChildNodes(); 125 for (int i=0; i < children.getLength(); i++) { 126 Node child = children.item(i); 127 if(child instanceof Element) { 128 try { 129 process1((Element) child); 130 } catch(RuntimeException e) { 131 if(!caller.ignoreError) throw e; 132 } 133 } 134 } 135 } 136 137 138 RefObject createObject(Element elem) { 139 String xmi_id = elem.getAttribute("xmi.id"); 140 141 RefObject o = factManager.createObject(elem.getTagName()); 142 if(o == null) { 143 System.out.println("warning: cannot create " +elem.getTagName() ); 144 } else { 145 createdObjects.add(o); 146 } 147 148 return o; 149 } 150 151 void process2(Element elem) { 153 154 String xmi_id = elem.getAttribute("xmi.id"); 155 RefObject o = (RefObject) id_object.get(xmi_id); 156 157 if(caller.verbose) 158 System.err.println("setting properties for object '" 159 +elem.getNodeName() +"' xmi.id=" +xmi_id 160 ); 161 try { 162 setProperties(elem ,o); 163 } catch(RuntimeException e) { 164 RuntimeException e2 = new RuntimeException ("at xmi.id="+xmi_id, e); 165 throw e2; 166 } 167 168 } 169 170 void setProperties(Element elem, RefObject o) { 171 172 NamedNodeMap attrs = elem.getAttributes(); 173 174 NodeList children = elem.getChildNodes(); 175 for (int i=0; i < children.getLength(); i++) { 176 Node child = children.item(i); 177 if(child instanceof Element) 178 setValue(o, child ); 179 } 180 181 for (int i=0; i < attrs.getLength(); i++) { 182 Attr attr = (Attr) attrs.item(i); 183 if(!attr.getName().equals("xmi.id")) 184 setValue(o, attr ); 185 } 186 187 } 188 189 190 PropertyTypeManager typeManager = new PropertyTypeManager(); 191 192 193 void setValue(RefObject owner, Node propNode) { 194 RefObject metaObject = owner.refMetaObject(); 195 String propName = propNode.getNodeName(); 196 197 if( propName.toLowerCase().indexOf("xmi.")>=0) { 199 if(caller.verbose) 200 System.err.println("\t\t\t*** ignore node '" +propName +"'"); 201 return; 202 } 203 204 String unqPropName = ReflectHelper.unqualifiedName(propNode.getNodeName()); 205 TypeInfo type; 206 try { 207 type = typeManager.findTypeFor(metaObject, unqPropName); 208 } catch(Exception e) { 209 210 String err = "property '" +propName +"' undefined in '" +metaObject.refGetValue("qualifiedName") +"'"; 211 if(caller.ignoreError) { 212 if(caller.verbose) System.err.println("***" +err); 213 return; 214 } else { 215 throw new RuntimeException ( err ,e ); 216 } 217 } 218 try { 219 if(type.isMultiValued) { 220 Collection values = (propNode instanceof Attr)? 221 createValuesFrmAttr(type, (Attr) propNode) 222 : createValuesFrmElement(type, (Element)propNode); 223 if(caller.verbose) System.err.println(" set property '" 224 +propName +"' =" +values 225 ); 226 ((Collection)owner.refGetValue(unqPropName)).addAll(values); 227 } else { 228 Object value = (propNode instanceof Attr)? 229 createValueFrmAttr(type, (Attr)propNode) 230 : createValueFrmElement(type, (Element)propNode); 231 if(caller.verbose) 232 System.err.println(" set property '" 233 +propName +"' =" +value 234 ); 235 if(value!=null) { 236 owner.refSetValue(unqPropName, value ); 237 } 238 } 239 } catch(RuntimeException e) { 240 String err = "Could not set property '" +propName +"' from Node "+ propNode; 241 if(caller.ignoreError) { 242 if(caller.verbose) System.err.println("***" +err); 243 } else { 244 throw new RuntimeException (err, e); 245 } 246 } 247 } 248 249 250 251 Object createValueFrmAttr(TypeInfo type, Attr propNode) { 252 return createValue(type, propNode.getNodeValue()); 253 } 254 255 Object createValueFrmElement(TypeInfo type, Element propNode) { 256 if(type.isStruct) { 257 return createStruct(type, propNode); 258 } 259 260 if(propNode.hasAttribute("xmi.value")) { 261 return createValue(type, propNode.getAttribute("xmi.value")); 262 } 263 264 String xmi_idref = null; 265 NodeList children = ((Element)propNode).getChildNodes(); 266 for(int i=0; i<children.getLength(); i++) { 267 Node child = children.item(i); 268 if(child instanceof Element) { 269 Element childElem = (Element)child; 270 if(childElem.hasAttribute("xmi.id")) { 271 return createValue(type, childElem.getAttribute("xmi.id")); 272 273 } else if(childElem.hasAttribute("xmi.idref")) { 274 return createValue(type, childElem.getAttribute("xmi.idref")); 275 276 } else if(childElem.getTagName().equalsIgnoreCase("XMI.any")) { 277 return createValue(type, childElem.getFirstChild().getNodeValue()); 278 279 } else if( !type.isEnum && !type.isPrimitive 280 && factManager.canCreateObject( childElem.getTagName() ) 281 ) { RefObject o = factManager.createObject(childElem.getTagName()); 284 setProperties(childElem, o); 285 return o; 286 } 287 System.err.println("\t\t\t*** ignore element '" +childElem +"'"); 289 } else if(child instanceof Text) { 290 if(child.getNodeValue().trim().length() > 0) 292 return createValue( type, child.getNodeValue() ); 293 294 } else if(child instanceof Comment) { 295 296 } else { 297 System.err.println("\t\t\t*** ignore node '" +child +"'"); 299 } 300 } 301 return createValue(type ,""); 302 } 303 304 Collection createValuesFrmAttr(TypeInfo type, Attr propNode) { 305 List r = new Vector(); 306 StringTokenizer t = new StringTokenizer(propNode.getNodeValue()); 308 while(t.hasMoreTokens()) { 309 String vs = t.nextToken(); 310 Object vo = createValue(type,vs); 311 if(vo!=null) r.add(vo); 312 } 313 return r; 314 } 315 316 Collection createValuesFrmElement(TypeInfo type, Element propNode) { 317 List r = new Vector(); 318 if(type.isStruct) { 319 Object v = createStruct(type, propNode); 320 if(v!=null) r.add(v); 321 return r; 322 } 323 if(propNode.hasAttribute("xmi.value")) { 324 Object v = createValue(type, propNode.getAttribute("xmi.value")); 325 if(v!=null) r.add(v); 326 return r; 327 } 328 NodeList list = ((Element)propNode).getChildNodes(); 329 for(int i=0; i<list.getLength(); i++) { 330 Node child = list.item(i); 331 if(child instanceof Element) { 332 Element childElem = (Element) child; 333 if(childElem.hasAttribute("xmi.id")) { 334 Object v = createValue(type, childElem.getAttribute("xmi.id")); 335 if(v!=null) r.add(v); 336 337 } else if(childElem.hasAttribute("xmi.idref")) { 338 Object v = createValue(type, childElem.getAttribute("xmi.idref")); 339 if(v!=null) r.add(v); 340 341 } else if(childElem.getTagName().equalsIgnoreCase("XMI.any")) { 342 Object v = createValue(type, childElem.getFirstChild().getNodeValue()); 343 if(v!=null) r.add(v); 344 345 346 } else if( !type.isEnum && !type.isPrimitive 347 && factManager.canCreateObject( childElem.getTagName() ) 348 ) { RefObject v = factManager.createObject(childElem.getTagName()); 351 setProperties(childElem, v); 352 if(v!=null) r.add(v); 353 354 } else { 355 System.err.println("\t\t\t*** ignore element '" +childElem +"'"); 357 } 358 359 } else if(child instanceof Text) { 360 if(child.getNodeValue().trim().length() > 0) { 362 Object v = createValue(type, child.getNodeValue()); 363 if(v!=null) r.add(v); 364 } 365 } else if(child instanceof Comment) { 366 367 } else { 368 System.err.println("\t\t\t*** ignore node '" +child +"'"); 370 } 371 } 372 return r; 373 } 374 375 Object createValue(TypeInfo type, String value) { 376 if(type.isPrimitive) { 377 return parsePrimitiveValue(type.name, value); 378 } 379 if(type.isEnum) { 380 return getEnum(type, value); 381 } 382 if(type.isStruct) { 383 throw new RuntimeException ("Struct value should not be encoded as attribute"); 384 } 385 String xmi_idref = value; Object r = id_object.get(xmi_idref); 388 if(r==null) { 389 throw new RuntimeException ("unresolved xmi.idref '" +xmi_idref +"'"); 390 } 391 return r; 392 } 393 394 Object parsePrimitiveValue(String type, String value) { 395 if(type.equalsIgnoreCase("string")) { 396 return value; 397 } else if(type.equalsIgnoreCase("long") 398 || type.equalsIgnoreCase("integer") ) { 399 return new Integer (Integer.parseInt(value)); 400 } else if(type.equalsIgnoreCase("double") 401 || type.equalsIgnoreCase("float") ) { 402 return new Double (Double.parseDouble(value)); 403 } else if(type.equalsIgnoreCase("boolean")) { 404 return Boolean.valueOf(value); 405 } 406 throw new RuntimeException ("unknown primitive type '" + type +"'"); 407 } 408 409 410 RefEnum getEnum(TypeInfo type, String label) { 411 String prefixLabel = label; 412 if(type.enumUnprefix!=null) { 413 if(!label.startsWith(type.enumUnprefix)) { 414 prefixLabel = type.enumUnprefix + label; 415 } 416 } 417 return factManager.getEnum(type.qname, prefixLabel); 418 } 419 420 435 RefStruct createStruct(TypeInfo type, Element elem) { 436 if(isStructFormat1(elem)) { 437 return createStruct_Format1(type, elem); 438 } 439 return createStruct_Format2(type, elem); 440 } 441 442 boolean isStructFormat1(Element elem) { 443 return getChildFromLocalName(elem, "XMI.field")!=null; 444 } 445 446 Element getChildFromLocalName(Element elem, String name) { 447 NodeList list = elem.getChildNodes(); 448 for(int i=0; i<list.getLength() ; i++) { 449 Node child = list.item(i); 450 if((child instanceof Element) && child.getNodeName().endsWith(name) ) 451 return (Element)child; 452 } 453 return null; 454 } 455 456 RefStruct createStruct_Format1(TypeInfo type, Element elem) { 457 List args = new Vector(); 458 NodeList list = elem.getChildNodes(); 459 int j = 0; 460 for(int i=0; i<list.getLength(); i++) { 461 Node child = list.item(i); 462 String nodeName = child.getNodeName(); 463 if((child instanceof Element) && nodeName.endsWith("XMI.field")) { 464 args.add( createValueFrmElement(type.structFieldTypes[j], (Element)child) ); 465 j++; 466 } 467 } 468 return factManager.createStruct(type.qname, args); 469 } 470 471 RefStruct createStruct_Format2(TypeInfo type, Element elem) { 472 Element inner = getChildFromLocalName(elem, type.name); 473 List args = new Vector(); 474 for(int i=0; i<type.structFieldTypes.length; i++) { 475 try { 476 String value = inner.getAttribute(type.structFieldNames[i]); 477 args.add( 478 createValue(type.structFieldTypes[i], value ) 479 ); 480 } catch(RuntimeException e) { 481 System.err.println("CreateStruct: Error at att[" +i +"] " 482 +type.structFieldNames[i] 483 ); 484 throw e; 485 } 486 } 487 return factManager.createStruct(type.qname, args); 488 } 489 490 491 492 Map sharedPrimitiveTypes = new Hashtable(); 493 494 RefObject doCorbaType(String xmi_id, String elemName, Element elem) { 498 499 if(!elemName.equals("DataType")) { 500 return null; 501 } 502 Element tc = findTypeCodeInDataType(elem); 503 if(tc==null) return null; 504 505 506 while(tc.getNodeName().equalsIgnoreCase("XMI.CorbaTcAlias")) { 508 tc = findTypeCodeInDataType(tc); 509 } 510 511 String name = null; 512 RefObject type; 514 if(tc.getNodeName().equalsIgnoreCase("XMI.CorbaTcEnum")) { 515 if(caller.verbose) System.err.println( 516 "creating EnumerationType '" +name +"' xmi.id=" +xmi_id 517 ); 518 type = extent.refClass("EnumerationType").refCreateInstance(null); 519 name = tc.getAttribute("xmi.tcName"); 520 if(name.length()==0) { 521 throw new RuntimeException ("Expecting xmi.tcName in " +tc.getNodeName()); 522 } 523 type.refSetValue("name", name); 524 NodeList labels = tc.getElementsByTagName("XMI.CorbaTcEnumLabel"); 525 List type_labels = (List)type.refGetValue("labels"); 526 for(int i=0; i<labels.getLength() ; i++) { 527 Element label = (Element) labels.item(i); 528 type_labels.add(label.getAttribute("xmi.tcName")); 529 } 530 type.refSetValue("name", name); 531 532 } else { 533 name = getTcName(tc); 537 char firstChar = name.charAt(0); 538 name = Character.toUpperCase(firstChar) + name.substring(1); 539 type = (RefObject) sharedPrimitiveTypes.get(name); 540 if(type==null) { 541 if(caller.verbose) System.err.println( 542 "creating PrimitiveType '" +name +"' xmi.id=" +xmi_id 543 ); 544 type = extent.refClass("PrimitiveType").refCreateInstance(null); 545 type.refSetValue("name", name); 546 } 547 } 548 id_object.put(xmi_id, type); 549 createdObjects.add(type); 550 return type; 551 } 552 553 554 Element findTypeCodeInDataType(Element dataType) { 557 NodeList typeCode = dataType.getElementsByTagName("XMI.CorbaTypeCode"); 558 if(typeCode.getLength()==0) { 559 return null; 560 } 561 Element tcElem = (Element) typeCode.item(0); 562 NodeList tcContentList = tcElem.getChildNodes(); 563 for(int i = 0; i<tcContentList.getLength(); i++) { 564 Node n = tcContentList.item(i); 565 if(n instanceof Element) { 566 Element tcContent = (Element)n; 567 String s = tcContent.getNodeName().toLowerCase(); 568 if(s.indexOf("xmi.corbatc")>=0) { 569 return tcContent; 570 } 571 } 572 } 573 throw new RuntimeException ("Cannot handle CorbaTypeCode " + tcElem); 574 } 575 576 String getTcName(Element tc) { 577 String n = tc.getNodeName().toLowerCase(); 578 return n.replaceAll("xmi.corbatc",""); 579 } 580 581 582 583 584 585 586 587 588 } 589 | Popular Tags |