1 19 package org.netbeans.lib.jmi.xmi; 20 21 import java.io.*; 22 import java.util.*; 23 24 import javax.jmi.reflect.*; 25 import javax.jmi.model.*; 26 27 import org.netbeans.lib.jmi.util.DebugException; 28 import org.netbeans.lib.jmi.util.Logger; 29 30 public class XmiDtdProducer extends org.netbeans.api.mdr.DTDProducer { 31 32 public static String TAG_ELEMENT = "!ELEMENT"; 33 public static String TAG_ATTLIST = "!ATTLIST"; 34 public static String TAG_REQUIRED = "#REQUIRED"; 35 public static String TAG_PCDATA = "#PCDATA"; 36 public static String TAG_CDATA = "CDATA"; 37 public static String TAG_IMPLIED = "#IMPLIED"; 38 public static String TAG_IDREFS = "IDREFS"; 39 public static String TAG_EMPTY = "EMPTY"; 40 public static String TAG_XMI_REFERENCE = "XMI.reference"; 41 public static String TAG_XMI_EXTENSION = "XMI.extension"; 42 public static String TAG_XMI_VALUE = "xmi.value"; 43 public static String TAG_XMI_FIXED_ATTRIBS = "%XMI.element.att; %XMI.link.att;"; 44 45 private static String END_OF_LICENCE_MARKER = "<!-- -->"; 47 private static String FIXED_DTD_FILE = "resources/fixed.dtd"; 49 private static int LINE_BOUND = 60; 51 52 private PrintStream stream; 54 private RefPackage extent; 56 private ElementsCache elementsCache; 58 private Set trackedPackages; 60 private Map classHierarchy; 62 private Map allSubtypes_cache; 64 private Map namespaces; 66 private boolean isFirstItem; 68 private int charsCounter; 70 71 73 public void init () { 74 elementsCache = new ElementsCache (extent); 75 trackedPackages = new HashSet (); 76 classHierarchy = new HashMap (); 77 allSubtypes_cache = new HashMap (); 78 namespaces = new HashMap (); 79 80 elementsCache = new ElementsCache (extent); 81 findNamespaces (extent); 82 trackedPackages.clear (); 83 } 84 85 87 public void startElement (String name) { 88 stream.println (); 89 isFirstItem = true; 90 stream.print ("<" + TAG_ELEMENT + " "); 91 stream.print (name); 92 charsCounter = TAG_ELEMENT.length () + 2 + name.length (); 93 } 94 95 public void addEmptyElement () { 96 stream.println (" " + TAG_EMPTY + ">"); 97 } 98 99 public void addElementItem (String name) { 100 if (!isFirstItem) { 101 stream.print (" | "); 102 charsCounter += 3; 103 } else { 104 isFirstItem = false; 105 stream.print (" ("); 106 charsCounter += 2; 107 } 108 charsCounter += name.length (); 109 if (charsCounter > LINE_BOUND) { 110 stream.println (); 111 stream.print (" "); 112 charsCounter = 4; 113 } 114 stream.print (name); 115 } 116 117 public void endElement () { 118 stream.println (")* >"); 119 } 120 121 public void startAttlist (String text) { 122 stream.print ("<" + TAG_ATTLIST + " "); 123 stream.print (text); 124 } 125 126 public void addAttlistItem (String text) { 127 stream.println (); 128 stream.print (" " + text); 129 } 130 131 public void endAttlist () { 132 stream.println (">"); 133 } 134 135 137 141 public void generate (OutputStream stream, RefPackage extent) { 142 this.stream = new PrintStream (stream); 143 this.extent = extent; 144 init (); 145 writeFixedContent (); 146 writeNamespaces (); 147 writePackageDTD (extent); 148 149 try { 150 stream.flush (); 151 stream.close (); 152 } catch (IOException e) { 153 e.printStackTrace (); 154 } 155 } 156 157 public void writePackageDTD (RefPackage pkg) { 158 if (trackedPackages.contains (pkg)) { 159 return; 160 } else { 161 trackedPackages.add (pkg); 162 } 163 Iterator iter = pkg.refAllPackages ().iterator (); 164 while (iter.hasNext ()) { 165 writePackageDTD ((RefPackage) iter.next ()); 166 } 167 iter = pkg.refAllClasses ().iterator (); 168 while (iter.hasNext ()) { 169 writeClassDTD ((RefClass) iter.next ()); 170 } 171 iter = pkg.refAllClasses ().iterator (); 172 while (iter.hasNext ()) { 173 writeStaticAttributesDTD ((RefClass) iter.next ()); 174 } 175 iter = getFreeAssociations (pkg).iterator (); 176 while (iter.hasNext ()) { 177 writeAssociationDTD ((Association) iter.next ()); 178 } 179 180 writePackageElementDef (pkg); 181 } 182 183 public void writeClassDTD (RefClass proxy) { 184 Iterator iter; 185 String text; 186 StringBuffer buffer = new StringBuffer (); 187 MofClass meta = (MofClass) proxy.refMetaObject (); 188 String className = objectName (meta); 189 List instAttrs, references; 190 191 instAttrs = elementsCache.instanceAttributes (meta); 192 references = elementsCache.references (meta); 193 194 iter = instAttrs.iterator (); 196 while (iter.hasNext ()) { 197 Attribute attr = (Attribute) iter.next (); 198 if (attr.getContainer () == meta) { 199 writeAttributeElemDef (attr); 200 } 201 } 203 iter = references.iterator (); 205 while (iter.hasNext ()) { 206 Reference ref = (Reference) iter.next (); 207 if (ref.getContainer () != meta) 208 continue; 209 startElement (elementName (ref)); 210 MofClass type = (MofClass) ref.getType (); 211 Iterator it = elementsCache.getAllSubtypes ((MofClass) type).iterator (); 212 while (it.hasNext ()) { 213 addElementItem (objectName ((MofClass) it.next ())); 214 } endElement (); 216 } 218 startElement (className); 220 Iterator it; 221 for (it = instAttrs.iterator (); it.hasNext ();) { 222 addElementItem (elementName ((Attribute) it.next ())); 223 } 224 for (it = references.iterator (); it.hasNext ();) { 225 addElementItem (elementName ((Reference) it.next ())); 226 } 227 for (it = getComposites (meta).iterator (); it.hasNext ();) { 228 addElementItem (objectName ((MofClass) it.next ())); 229 } 230 addElementItem (TAG_XMI_EXTENSION); 231 endElement (); 232 233 buffer.delete(0, buffer.length ()); 234 startAttlist (className); 235 for (it = references.iterator (); it.hasNext ();) { buffer.append (((Reference) it.next ()).getName ()); 237 buffer.append (" " + TAG_IDREFS + " " + TAG_IMPLIED); 238 addAttlistItem (buffer.toString ()); 239 buffer.delete(0, buffer.length ()); 240 } 241 for (it = instAttrs.iterator (); it.hasNext ();) { 242 Attribute attr = (Attribute) it.next (); 243 buffer.append (attr.getName ()); 244 Classifier type = getType (attr); 245 if (type instanceof EnumerationType) { 246 int prefixLength = labelPrefix ((EnumerationType) type).length (); 247 buffer.append (" ("); 248 for (Iterator it_2 = ((EnumerationType) type).getLabels ().iterator (); it_2.hasNext ();) { 249 buffer.append (((String ) it_2.next ()).substring (prefixLength)); 250 if (it_2.hasNext ()) 251 buffer.append ("|"); 252 } 253 buffer.append (") " + TAG_IMPLIED); 254 } else if (type instanceof MofClass) { 255 buffer.append (" " + TAG_IDREFS + " " + TAG_IMPLIED); 256 } else { 257 buffer.append (" " + TAG_CDATA + " " + TAG_IMPLIED); 258 } 259 addAttlistItem (buffer.toString ()); 260 buffer.delete(0, buffer.length ()); 261 } 262 addAttlistItem (TAG_XMI_FIXED_ATTRIBS); 263 endAttlist (); 264 } 265 266 public void writeStaticAttributesDTD (RefClass proxy) { 267 MofClass meta = (MofClass) proxy.refMetaObject (); 268 for (Iterator iter = elementsCache.classAttributes (meta).iterator (); iter.hasNext ();) { 269 Attribute attr = (Attribute) iter.next (); 270 if (attr.getContainer () == meta) 271 writeAttributeElemDef (attr); 272 } 273 } 274 275 public void writeAssociationDTD (Association assoc) { 276 String name; 277 Set subtypes = new HashSet (); 278 for (Iterator iter = assoc.getContents ().iterator (); iter.hasNext ();) { 279 Object elem = iter.next (); 280 if (elem instanceof AssociationEnd) { 281 subtypes.addAll (elementsCache.getAllSubtypes ((MofClass) ((AssociationEnd) elem).getType ())); 282 } } name = objectName (assoc); 285 startElement (name); 286 for (Iterator iter = subtypes.iterator (); iter.hasNext ();) { 287 addElementItem (objectName ((MofClass) iter.next ())); 288 } 289 addElementItem (TAG_XMI_EXTENSION); 290 endElement (); 291 292 startAttlist (name); 293 addAttlistItem (TAG_XMI_FIXED_ATTRIBS); 294 endAttlist (); 295 324 } 325 326 public void writeAttributeElemDef (Attribute attr) { 327 StringBuffer buffer = new StringBuffer (); 328 Classifier type = getType (attr); 329 boolean isEnum = type instanceof EnumerationType; 330 startElement (elementName (attr)); 331 332 if (isEnum) { addEmptyElement (); 334 } else if (type instanceof MofClass) { Iterator it = elementsCache.getAllSubtypes ((MofClass) type).iterator (); 336 addElementItem (objectName ((MofClass) it.next ())); 337 while (it.hasNext ()) { 338 MofClass clazz = (MofClass) it.next (); 339 addElementItem (objectName (clazz)); 340 } endElement (); 342 } else if (type instanceof StructureType) { addElementItem ("XMI.field"); 344 endElement (); 345 } else { addElementItem (TAG_PCDATA); 347 addElementItem (TAG_XMI_REFERENCE); 348 endElement (); 349 } 350 351 if (isEnum) { 352 int prefixLength = labelPrefix ((EnumerationType) type).length (); 353 buffer = new StringBuffer (); 354 startAttlist (elementName (attr)); 355 buffer.append (TAG_XMI_VALUE + " ("); 356 Iterator it = ((EnumerationType) type).getLabels ().iterator (); 357 while (it.hasNext ()) { 358 buffer.append (((String ) it.next ()).substring (prefixLength)); 359 if (it.hasNext ()) 360 buffer.append ("|"); 361 } 362 buffer.append (") " + TAG_REQUIRED); 363 addAttlistItem (buffer.toString ()); 364 endAttlist (); 365 } 366 } 367 368 371 public void writeFixedContent () { 372 java.net.URL fixedDTD = getClass().getResource(FIXED_DTD_FILE); 373 if (fixedDTD == null) { 374 throw new DebugException("Resource not found: " + FIXED_DTD_FILE); 375 } 376 try { 377 InputStream in = fixedDTD.openStream (); 378 BufferedReader reader = new BufferedReader (new InputStreamReader(in)); 379 String line; 380 do { 382 line = reader.readLine (); 383 } while (!line.equals (END_OF_LICENCE_MARKER)); 384 line = reader.readLine (); 386 while (line != null) { 387 stream.println (line); 388 line = reader.readLine(); 389 } 390 } catch (IOException e) { 391 Logger.getDefault().log("Unable to open " + FIXED_DTD_FILE + ": " + e.getMessage()); 392 throw new DebugException (e.getMessage ()); 393 } 394 } 395 396 public void writeNamespaces () { 397 Set names = new HashSet (); 398 if (namespaces.size () > 0) { 399 startAttlist ("XMI"); 400 for (Iterator iter = namespaces.entrySet ().iterator (); iter.hasNext ();) { 401 Object name = ((Map.Entry) iter.next ()).getValue (); 402 if (!names.contains (name)) { 403 addAttlistItem ("xmlns:" + name + " " + TAG_CDATA + " " + TAG_IMPLIED); 404 names.add (name); 405 } 406 } endAttlist (); 408 } } 410 411 public void writePackageElementDef (RefPackage pkg) { 412 MofPackage meta = (MofPackage) pkg.refMetaObject (); 413 String packageName = packageName (meta); 414 Set classes = new HashSet (); 415 StringBuffer buffer = new StringBuffer (); 416 for (Iterator iter = pkg.refAllClasses ().iterator (); iter.hasNext ();) { 417 classes.addAll (elementsCache.getAllSubtypes ((MofClass) ((RefClass) iter.next ()).refMetaObject ())); 418 } 419 startElement (packageName); 420 for (Iterator iter = classes.iterator (); iter.hasNext ();) { 422 addElementItem (objectName ((MofClass) iter.next ())); 423 } 424 for (Iterator iter = getFreeAssociations (pkg).iterator (); iter.hasNext ();) { 426 addElementItem (objectName ((Association) iter.next ())); 427 } 428 for (Iterator iter = pkg.refAllPackages ().iterator (); iter.hasNext ();) { 430 RefPackage refPkg = (RefPackage) iter.next (); 431 MofPackage metaPkg = (MofPackage) refPkg.refMetaObject (); 432 if (metaPkg.getContainer () == meta) { 433 addElementItem (packageName (metaPkg)); 434 } 435 } 436 addElementItem (TAG_XMI_EXTENSION); 438 endElement (); 439 440 startAttlist (packageName); 442 addAttlistItem (TAG_XMI_FIXED_ATTRIBS); 443 endAttlist (); 444 } 445 446 448 451 private void findNamespaces (RefPackage pkg) { 452 String name; 453 Iterator iter; 454 455 if (trackedPackages.contains (pkg)) 456 return; 457 else 458 trackedPackages.add (pkg); 459 460 MofPackage metaPackage = (MofPackage) pkg.refMetaObject (); 461 name = WriterBase.getTagValue (metaPackage, XmiConstants.TAGID_XMI_NAMESPACE); 462 if (name != null) { 463 namespaces.put (metaPackage, name); 464 } 465 466 iter = pkg.refAllPackages ().iterator (); 467 while (iter.hasNext ()) { 468 findNamespaces ((RefPackage) iter.next ()); 469 } 470 } 471 472 public String elementName (ModelElement element) { 473 ModelElement container = element.getContainer (); 474 return objectName (container) + '.' + element.getName (); 475 } 476 477 public String objectName (ModelElement element) { 478 String namespace = (String ) namespaces.get (element.getContainer ()); 479 if (namespace != null) { 480 return namespace + ":" + element.getName (); 481 } else { 482 return qualifiedName (element); 483 } 484 } 485 486 public String packageName (MofPackage pkg) { 487 String namespace = (String ) namespaces.get (pkg); 488 if (namespace != null) { 489 return namespace + ":" + pkg.getName (); 490 } else { 491 return qualifiedName (pkg); 492 } 493 } 494 495 public String qualifiedName (ModelElement element) { 496 Iterator iter = element.getQualifiedName ().iterator (); 497 String name = (String ) iter.next (); 498 while (iter.hasNext ()) { 499 name = name.concat (XmiConstants.DOT_SEPARATOR).concat ((String ) iter.next ()); 500 } 501 return name; 502 } 503 504 508 public String labelPrefix (EnumerationType type) { 509 String prefix = WriterBase.getTagValue (type, XmiConstants.TAGID_XMI_ENUMERATION_UNPREFIX); 510 if (prefix == null) 511 prefix = ""; 512 return prefix; 513 } 514 515 518 public Classifier getType (TypedElement elem) { 519 Classifier type = elem.getType (); 520 while (type instanceof AliasType) 521 type = ((AliasType) type).getType (); 522 return type; 523 } 524 525 public Set getComposites (MofClass meta) { 526 return new HashSet (); 527 550 } 551 552 555 public Set getFreeAssociations (RefPackage pkg) { 556 ModelPackage model = (ModelPackage) pkg.refMetaObject ().refImmediatePackage (); 557 RefersTo refersTo = model.getRefersTo (); 558 Set set = new HashSet (); 559 for (Iterator iter = pkg.refAllAssociations ().iterator (); iter.hasNext ();) { 560 Association assoc = (Association) ((RefAssociation) iter.next ()).refMetaObject (); 561 boolean found = false; 562 for (Iterator it = assoc.getContents ().iterator (); it.hasNext ();) { 563 Object elem = it.next (); 564 if (elem instanceof AssociationEnd) { 565 Collection col = refersTo.getReferent ((AssociationEnd) elem); 566 if ((col != null) && (col.size () > 0)) { 567 found = true; 568 break; 569 } 570 } 571 } if (!found) { 573 set.add (assoc); 574 } 575 } return set; 577 } 578 579 } 580 | Popular Tags |