1 19 package org.netbeans.lib.jmi.xmi; 20 21 import java.io.*; 22 import java.util.*; 23 import java.net.URL ; 24 25 import org.xml.sax.ContentHandler ; 26 import org.xml.sax.SAXException ; 27 import org.xml.sax.helpers.AttributesImpl ; 28 29 import org.netbeans.lib.jmi.util.DebugException; 30 import org.netbeans.api.xmi.*; 31 32 import javax.jmi.reflect.*; 33 import javax.jmi.model.*; 34 import org.netbeans.lib.jmi.util.Logger; 35 36 public class WriterBase extends XMIWriter { 37 38 private static final String XMI_VERSION = "1.2"; 39 public static final String EXPORTER_NAME = "Netbeans XMI Writer"; 40 public static final String EXPORTER_VERSION = "1.0"; 41 42 public static final int ATTR_HREF = 0; 43 public static final int ATTR_XMI_ID = 1; 44 public static final int ATTR_XMI_IDREF = 2; 45 46 public static final char HREF_DELIMITER = '#'; 47 48 50 protected ContentHandler contentHandler; 52 protected OutputConfig configuration; 54 protected XMIHeaderProvider headerProvider = null; 56 protected XMIReferenceProvider provider; 58 protected XMIReferenceProvider defaultProvider = new DefaultProvider (); 60 protected String encoding = null; 62 protected AttributesImpl attributes; 64 protected String thisSystemId = null; 66 protected String elementName; 68 protected boolean elementStarted; 70 71 protected OutputStreamWriter stream; 72 protected OutputStream outputStream = null; 74 75 protected HashMap namespaces; 77 78 protected List lightOutermosts; 80 protected Set writtenComponents; 82 protected Set nonWrittenComponents; 84 protected HashMap xmiIds; 86 protected int instancesCounter = 0; 88 89 93 protected HashSet processedPackages; 94 95 protected HashMap instanceAttributes_cache; 97 protected HashMap classAttributes_cache; 98 protected HashMap references_cache; 99 100 protected HashMap structureFields_cache; 102 protected HashMap labelPrefix_cache; 104 105 protected boolean collectionWriting = false; 107 protected Set objectsToWrite = null; 109 protected List objectsToWriteAsCollection = null; 110 111 113 public WriterBase() { 114 configuration = new OutputConfig (); 115 } 116 117 public WriterBase(XMIOutputConfig config) { 118 configuration = new OutputConfig (); 119 configuration.setReferenceProvider (config.getReferenceProvider ()); 120 if (config instanceof OutputConfig) { 121 configuration.setHeaderProvider (((OutputConfig) config).getHeaderProvider()); 122 configuration.setEncoding (((OutputConfig) config).getEncoding()); 123 } 124 } 125 126 public void init () throws IOException { 127 collectionWriting = false; 128 129 attributes = new AttributesImpl (); 130 131 namespaces = new HashMap (); 132 xmiIds = new HashMap (); 133 nonWrittenComponents = new HashSet (); 134 writtenComponents = new HashSet (); 135 processedPackages = new HashSet (); 136 instancesCounter = 0; 137 instanceAttributes_cache = new HashMap (); 138 classAttributes_cache = new HashMap (); 139 references_cache = new HashMap (); 140 structureFields_cache = new HashMap (); 141 labelPrefix_cache = new HashMap (); 142 143 lightOutermosts = new LinkedList (); 144 if (configuration == null) { 145 provider = defaultProvider; 146 } else { 147 provider = configuration.getReferenceProvider (); 148 if (provider == null) 149 provider = defaultProvider; 150 if (configuration instanceof OutputConfig) { 151 headerProvider = ((OutputConfig) configuration).getHeaderProvider (); 152 encoding = ((OutputConfig) configuration).getEncoding (); 153 } 154 } 155 156 if (outputStream != null) { 157 try { 158 if (encoding == null) { 159 stream = new OutputStreamWriter (outputStream); 160 } else { 161 stream = new OutputStreamWriter (outputStream, encoding); 162 } 163 contentHandler = new DefaultWriter (stream, encoding); 164 outputStream = null; 166 } catch (UnsupportedEncodingException e) { 167 throw new IOException ("Unsupported encoding: " + encoding); 168 } 169 } } 171 172 174 public void write (OutputStream os, RefPackage extent, String xmiVersion) throws IOException { 175 write (os, null, extent, xmiVersion); 176 } 177 178 public void write (OutputStream os, Collection objects, String xmiVersion) throws IOException { 179 write (os, null, objects, xmiVersion); 180 } 181 182 public void write(OutputStream stream, RefPackage extent) { 183 try { 184 write(stream, extent, null); 185 } catch (IOException e) { 186 DebugException ne = new DebugException(e.toString()); 187 Logger.getDefault().annotate(ne, e); 188 throw ne; 189 } 190 } 191 192 194 public XMIOutputConfig getConfiguration() { 195 return configuration; 196 } 197 198 public void write(OutputStream stream, String uri, RefPackage extent, String xmiVersion) throws IOException { 199 thisSystemId = uri; 200 outputStream = stream; 201 write (extent); 202 } 203 204 public void write(OutputStream stream, String uri, Collection objects, String xmiVersion) throws IOException { 205 thisSystemId = uri; 206 outputStream = stream; 207 write (objects); 208 } 209 210 212 public void write(ContentHandler handler, String uri, RefPackage extent, String xmiVersion) throws IOException { 213 thisSystemId = uri; 214 contentHandler = handler; 215 write (extent); 216 } 217 218 public void write(ContentHandler handler, String uri, Collection objects, String xmiVersion) throws IOException { 219 thisSystemId = uri; 220 contentHandler = handler; 221 write (objects); 222 } 223 224 public void write (RefPackage extent) throws IOException { 225 Logger.getDefault().log("XMI writer started"); 226 long time = System.currentTimeMillis (); 227 init (); 228 processedPackages.clear (); 229 findNamespaces (extent); 230 writeDocument (extent); 231 time = System.currentTimeMillis () - time; 232 Logger.getDefault().log("finished, TIME: " + time/1000.0 + "[s]"); 233 } 234 235 public void write (Collection objects) throws IOException { 236 init (); 237 collectionWriting = true; 239 processedPackages.clear (); 241 RefPackage extent; 242 objectsToWrite = new HashSet (); 243 objectsToWriteAsCollection = new LinkedList (); 244 Set tempSet = new HashSet (); 245 if ((objects == null) || (objects.size () == 0)) { 246 extent = null; 247 } else { 248 Iterator iter = objects.iterator (); 249 while (iter.hasNext ()) { 250 Object obj = iter.next (); 251 if (!(obj instanceof RefObject)) 252 throw new DebugException ("Bad object (not instance of RefObject) in input collection: " + obj.getClass ().getName ()); 253 tempSet.add (obj); 254 } iter = objects.iterator (); 256 RefFeatured featured; 257 RefObject container; 258 while (iter.hasNext ()) { 259 RefObject obj = (RefObject) iter.next (); 260 container = obj; 261 boolean found = false; 262 do { 263 featured = container.refImmediateComposite (); 264 container = (featured instanceof RefObject) ? (RefObject) featured : null; 265 if ((container != null) && tempSet.contains (container)) { 266 found = true; 267 break; 268 } 269 } while (container != null); 270 if (!found) { 271 objectsToWrite.add (obj); 272 objectsToWriteAsCollection.add (obj); 273 } 274 } extent = ((RefObject) objectsToWriteAsCollection.get (0)).refOutermostPackage (); 276 findNamespaces (extent); 277 } 278 writeDocument (extent); 279 } 280 281 283 protected void findNamespaces (RefPackage pkg) { 284 String name; 285 Iterator iter; 286 287 if (processedPackages.contains (pkg)) 288 return; 289 290 MofPackage metaPackage = (MofPackage) pkg.refMetaObject (); 291 name = getTagValue (metaPackage, XmiConstants.TAGID_XMI_NAMESPACE); 292 if (name != null) { 293 iter = metaPackage.getQualifiedName ().iterator (); 294 String fqName = (String ) iter.next (); 295 while (iter.hasNext ()) 296 fqName = fqName.concat (XmiConstants.DOT_SEPARATOR).concat ((String ) iter.next ()); 297 namespaces.put (fqName, name); 298 } 299 300 processedPackages.add (pkg); 301 iter = pkg.refAllPackages ().iterator (); 302 while (iter.hasNext ()) { 303 findNamespaces ((RefPackage) iter.next ()); 304 } 305 } 306 307 public static String getTagValue (ModelElement element, String tagId) { 308 Collection tags = ((ModelPackage) element.refImmediatePackage()). 309 getAttachesTo().getTag (element); 310 Tag tag = null; 311 for (Iterator it = tags.iterator(); it.hasNext();) { 312 Object obj = it.next (); 313 if (!(obj instanceof Tag)) 314 continue; 315 Tag temp = (Tag) obj; 316 if (tagId.equals (temp.getTagId ())) { 317 tag = temp; 318 break; 319 } 320 } 321 if (tag == null) 322 return null; 323 Collection values = tag.getValues (); 324 if (values.size () == 0) 325 return null; 326 return (String ) values.iterator ().next (); 327 } 328 329 332 protected void cacheContainedElements (MofClass mofClass) { 333 List temp = new LinkedList (); 334 List superClasses = mofClass.allSupertypes (); 335 Namespace namespace = null; 336 Iterator it = superClasses.iterator (); 337 while (it.hasNext ()) { 338 namespace = (Namespace) it.next (); 339 temp.addAll (namespace.getContents ()); 340 } 341 temp.addAll (mofClass.getContents ()); 342 List instanceAttributes = new LinkedList (); 343 List classAttributes = new LinkedList (); 344 List references = new LinkedList (); 345 Set referencedEnds = new HashSet (); 346 it = temp.iterator (); 347 while (it.hasNext ()) { 348 RefObject refObject = (RefObject) it.next (); 349 if (refObject instanceof Feature) { 350 boolean instanceLevel = ((Feature) refObject).getScope ().equals (ScopeKindEnum.INSTANCE_LEVEL); 351 if ((refObject instanceof Attribute) && (!((Attribute) refObject).isDerived ())) { 352 if (instanceLevel) { 353 instanceAttributes.add (refObject); 354 } else { 355 classAttributes.add (refObject); 356 } 357 } else if (refObject instanceof Reference) { 358 AssociationEnd end = ((Reference) refObject).getReferencedEnd (); 359 Association assoc = (Association) end.getContainer (); 360 if (!assoc.isDerived () && !referencedEnds.contains (end)) { 361 references.add (refObject); 362 referencedEnds.add (end); 363 } 364 } } } instanceAttributes_cache.put (mofClass, instanceAttributes); 368 classAttributes_cache.put (mofClass, classAttributes); 369 references_cache.put (mofClass, references); 370 } 371 372 379 protected List instanceAttributes (MofClass mofClass) { 380 List list = (List) instanceAttributes_cache.get (mofClass); 381 if (list == null) { 382 cacheContainedElements (mofClass); 383 list = (List) instanceAttributes_cache.get (mofClass); 384 } 385 return list; 386 } 387 388 394 protected List classAttributes (MofClass mofClass) { 395 List list = (List) classAttributes_cache.get (mofClass); 396 if (list == null) { 397 cacheContainedElements (mofClass); 398 list = (List) classAttributes_cache.get (mofClass); 399 } 400 return list; 401 } 402 403 409 protected List references (MofClass mofClass) { 410 List list = (List) references_cache.get (mofClass); 411 if (list == null) { 412 cacheContainedElements (mofClass); 413 list = (List) references_cache.get (mofClass); 414 } 415 return list; 416 } 417 418 421 public List structureFields (StructureType type) { 422 List fields = (List) structureFields_cache.get (type); 423 if (fields != null) 424 return fields; 425 fields = new LinkedList (); 427 Iterator content = type.getContents ().iterator (); 428 while (content.hasNext ()) { 429 Object element = content.next (); 430 if (element instanceof StructureField) 431 fields.add (element); 432 } structureFields_cache.put (type, fields); 434 return fields; 435 } 436 437 441 public String labelPrefix (EnumerationType type) { 442 String prefix = (String ) labelPrefix_cache.get (type); 443 if (prefix != null) 444 return prefix; 445 prefix = getTagValue (type, XmiConstants.TAGID_XMI_ENUMERATION_UNPREFIX); 446 if (prefix == null) 447 prefix = ""; 448 labelPrefix_cache.put (type, prefix); 449 return prefix; 450 } 451 452 456 protected void startElement (String name) { 457 if (elementStarted) { 458 writeStartElement (); 459 } 460 elementName = name; 461 elementStarted = true; 462 } 463 464 469 protected void endElement (String name) { 470 if (elementStarted) { 471 writeStartElement (); 472 } 473 try { 474 contentHandler.endElement (null, null, name); 475 } catch (SAXException e) { 476 } 477 } 478 479 485 protected void addAttribute (String name, String value) { 486 attributes.addAttribute(null, null, name, null, value); } 488 489 496 protected void characters (String text) { 497 if (elementStarted) { 498 writeStartElement (); 499 } 500 try { 501 contentHandler.characters (text.toCharArray(), 0, text.length ()); 502 } catch (SAXException e) { 503 } 504 } 505 506 protected void writeStartElement () { 507 try { 508 contentHandler.startElement (null, null, elementName, attributes); 509 } catch (SAXException e) { 510 } 511 elementStarted = false; 512 attributes.clear (); 513 } 514 515 517 521 protected String getXmiId (RefObject obj) { 522 String xmiId = ((String ) xmiIds.get (obj)); 523 if (xmiId == null) { 524 instancesCounter++; 525 xmiId = "a" + instancesCounter; 526 xmiIds.put (obj, xmiId); 527 } 528 return xmiId; 529 } 530 531 534 protected void markWritten (RefObject obj) { 535 writtenComponents.add (obj); 537 nonWrittenComponents.remove (obj); 538 } 539 540 protected void writeDocument (RefPackage pkg) { 541 try { 542 contentHandler.startDocument(); 543 } catch (SAXException e) { 544 } 545 546 startElement (XmiConstants.XMI_ROOT); 547 addAttribute ("xmi.version", XMI_VERSION); 548 writeNamespaces (); 549 addAttribute ("timestamp", new Date ().toString ()); 550 551 writeHeader (); 552 553 startElement (XmiConstants.XMI_CONTENT); 555 if (!collectionWriting) { 556 processedPackages.clear(); 557 writePackage (pkg); 558 559 RefObject obj; 560 while (nonWrittenComponents.size () > 0) { 561 Iterator iter = nonWrittenComponents.iterator (); 562 do { 563 obj = (RefObject) iter.next (); 564 } while (nonWrittenComponents.contains (obj.refImmediateComposite ())); 565 writeInstance (obj, true); 566 while (lightOutermosts.size() > 0) { 567 obj = (RefObject) lightOutermosts.remove(0); 568 writeInstance (obj, true); 569 } } 572 processedPackages.clear(); 573 writeStaticAttributes (pkg); 574 } else { 575 writeObjects (); 576 } 577 processedPackages.clear(); 578 writeAssociations (pkg); 579 endElement (XmiConstants.XMI_CONTENT); 580 endElement (XmiConstants.XMI_ROOT); 582 try { 583 contentHandler.endDocument(); 584 } catch (SAXException e) { 585 } 586 } 587 588 protected void writeHeader () { 589 startElement (XmiConstants.XMI_HEADER); 591 if ((contentHandler instanceof DefaultWriter) && (headerProvider != null)) { 592 writeStartElement (); 593 characters (""); 594 Writer ps = ((DefaultWriter) contentHandler).getWriter (); 595 headerProvider.writeHeader (ps); 596 } else { startElement (XmiConstants.XMI_DOCUMENTATION); 598 startElement ("XMI.exporter"); 600 characters (EXPORTER_NAME); 601 endElement ("XMI.exporter"); 602 startElement ("XMI.exporterVersion"); 604 characters (EXPORTER_VERSION); 605 endElement ("XMI.exporterVersion"); 606 endElement (XmiConstants.XMI_DOCUMENTATION); 607 } 608 endElement (XmiConstants.XMI_HEADER); 609 } 611 612 protected void writeNamespaces () { 613 HashMap temp = new HashMap (); 614 Iterator iter = namespaces.entrySet ().iterator (); 615 while (iter.hasNext ()) { 616 String name = (String ) ((Map.Entry) iter.next ()).getValue (); 617 if (temp.get (name) == null) { 618 temp.put (name, name); 619 addAttribute ("xmlns:" + name, XmiConstants.TAGID_XMI_NAMESPACE + "." + name); 620 } } } 623 624 627 protected void writePackage (RefPackage pkg) { 628 629 if (processedPackages.contains (pkg)) 630 return; 631 632 Iterator classes = pkg.refAllClasses ().iterator (); 633 while (classes.hasNext ()) { 634 RefClass proxy = (RefClass) classes.next (); 635 Iterator instances = proxy.refAllOfClass ().iterator (); 636 while (instances.hasNext ()) { 637 RefObject obj = (RefObject) instances.next (); 638 if (obj == null) { 639 continue; 640 } 641 if (obj.equals (obj.refOutermostComposite ())) { 642 writeInstance (obj, true); 645 while (lightOutermosts.size() > 0) { 646 obj = (RefObject) lightOutermosts.remove(0); 647 writeInstance (obj, true); 648 } } else { 650 if (!writtenComponents.contains (obj)) { 651 nonWrittenComponents.add (obj); 652 } 653 } 654 } } 657 processedPackages.add (pkg); 658 Iterator containedPackages = pkg.refAllPackages ().iterator (); 659 while (containedPackages.hasNext ()) 660 writePackage ((RefPackage) containedPackages.next ()); 661 } 662 663 protected void writeObjects () { 664 Iterator iter = objectsToWriteAsCollection.iterator (); 665 while (iter.hasNext ()) { 666 writeInstance ((RefObject) iter.next (), true); 667 } 668 } 669 670 676 protected void writeInstance (RefObject obj, boolean isTop) { 677 RefClass proxy = obj.refClass (); 678 ModelElement element = (ModelElement) obj.refMetaObject (); 679 String name = qualifiedName (element); 680 XMIReferenceProvider.XMIReference xmiRef = provider.getReference (obj); 681 String xmiId = xmiRef.getXmiId (); 682 String systemId = xmiRef.getSystemId (); 683 if ((systemId != null) && (thisSystemId != null) && (thisSystemId.equals (systemId))) 684 systemId = null; 685 686 markWritten (obj); 687 if (systemId != null) { if (!isTop) { startElement (name); 690 addAttribute (XmiConstants.XMI_HREF, systemId + HREF_DELIMITER + xmiId); 691 endElement (name); 692 } 693 collectLightOutermosts (obj, proxy); 694 return; 695 } 696 697 startElement (name); 698 addAttribute (XmiConstants.XMI_ID, xmiId); 699 Iterator attrs = instanceAttributes ((MofClass) proxy.refMetaObject ()).iterator (); 700 List attrsInContent = new LinkedList (); 701 while (attrs.hasNext ()) { 702 Attribute attr = (Attribute) attrs.next (); 703 if (!VisibilityKindEnum.PUBLIC_VIS.equals(attr.getVisibility())) 704 continue; 705 boolean isMultivalued = isMultivalued (attr); 706 Object value; 707 try { 708 value = obj.refGetValue (attr); 709 } catch (Exception e) { 710 Logger.getDefault().annotate(e, ((ModelElement) obj.refMetaObject ()).getName () + " " + attr.getName ()); 711 Logger.getDefault().notify(e); 712 value = Boolean.FALSE; } 714 Object valueToWrite = value; 715 if (value == null) 716 continue; if (isMultivalued) { 718 Collection col = (Collection) value; 719 if (col.size () > 0) { 720 attrsInContent.add (attr); 721 } 722 continue; 723 733 } Classifier type = getType (attr); 735 if (!(type instanceof PrimitiveType) && !(type instanceof EnumerationType)) { 736 attrsInContent.add (attr); 738 } else 739 writeValueInAttr (attr, valueToWrite); 740 } Iterator iter = attrsInContent.iterator (); 742 while (iter.hasNext ()) { 743 Attribute attr = (Attribute) iter.next (); 744 writeValueInContent (attr, obj.refGetValue (attr)); 745 } Iterator refs = references ((MofClass) proxy.refMetaObject ()).iterator (); 747 while (refs.hasNext ()) { 748 Reference ref = (Reference) refs.next (); 749 writeReference (obj, ref); 750 } 751 endElement (name); 752 } 753 754 protected void collectLightOutermosts (RefObject obj, RefClass proxy) { 755 Iterator iter; 756 Iterator attrs = instanceAttributes ((MofClass) proxy.refMetaObject ()).iterator (); 757 while (attrs.hasNext ()) { 758 Attribute attr = (Attribute) attrs.next (); 759 Classifier type = getType (attr); 760 if ((type instanceof PrimitiveType) || (type instanceof EnumerationType)) 761 continue; 762 boolean isMultivalued = isMultivalued (attr); 763 Object value = obj.refGetValue (attr); 764 Collection values; 765 if (value == null) 766 continue; if (isMultivalued) { 768 values = (Collection) value; 769 } else { 770 values = new LinkedList (); 771 values.add (value); 772 } 773 iter = values.iterator (); 774 if (type instanceof MofClass) { 775 while (iter.hasNext ()) { 776 addLightOutermost ((RefObject) iter.next ()); 777 } 778 } else if (type instanceof StructureType) { 779 while (iter.hasNext ()) { 780 collectStructure ((StructureType) type, (RefStruct) iter.next ()); 781 } 782 } else if (type instanceof CollectionType) { 783 while (iter.hasNext ()) { 784 collectCollection ((CollectionType) type, (Collection) iter.next ()); 785 } 786 } 787 } 789 Iterator refs = references ((MofClass) proxy.refMetaObject ()).iterator (); 790 while (refs.hasNext ()) { 791 Reference ref = (Reference) refs.next (); 792 797 AggregationKind kind = ref.getExposedEnd ().getAggregation (); 798 if (AggregationKindEnum.COMPOSITE.equals (kind)) { 799 Object temp = obj.refGetValue (ref); 800 if (temp == null) 801 continue; 802 Collection values; 803 if (isMultivalued (ref)) 804 values = (Collection) temp; 805 else { 806 values = new LinkedList (); 807 values.add (temp); 808 } 809 iter = values.iterator (); 810 while (iter.hasNext ()) { 811 addLightOutermost ((RefObject) iter.next ()); 812 } } } } 816 817 protected void collectStructure (StructureType type, RefStruct value) { 818 Iterator iter = structureFields (type).iterator (); 819 while (iter.hasNext ()) { 820 StructureField field = (StructureField) iter.next (); 821 Classifier fieldType = getType (field); 822 if (fieldType instanceof StructureType) { 823 collectStructure ((StructureType) fieldType, (RefStruct) value.refGetValue (field.getName())); 824 } else if (fieldType instanceof MofClass) { 825 addLightOutermost ((RefObject) value.refGetValue (field.getName())); 826 } else if (fieldType instanceof CollectionType) { 827 collectCollection ((CollectionType) fieldType, (Collection) value.refGetValue (field.getName())); 828 } 829 } } 831 832 protected void collectCollection (CollectionType collType, Collection col) { 833 Classifier type = collType.getType (); 834 Iterator iter = col.iterator (); 835 if (type instanceof StructureType) { 836 while (iter.hasNext ()) 837 collectStructure ((StructureType) type, (RefStruct) iter.next ()); 838 } else if (type instanceof CollectionType) { 839 while (iter.hasNext ()) 840 collectCollection ((CollectionType) type, (Collection) iter.next ()); 841 } else if (type instanceof MofClass) { 842 while (iter.hasNext ()) 843 addLightOutermost ((RefObject) iter.next ()); 844 } 845 } 846 847 protected void addLightOutermost (RefObject obj) { 848 lightOutermosts.add (obj); 849 } 850 851 857 protected void writeInstanceRef (RefObject obj, boolean externalOnly, boolean hrefForced) { 858 String name = qualifiedName ((ModelElement) obj.refMetaObject ()); 859 XMIReferenceProvider.XMIReference xmiRef = provider.getReference (obj); 860 String xmiId = xmiRef.getXmiId (); 861 String systemId = xmiRef.getSystemId (); 862 if ((systemId != null) && (thisSystemId != null) && (thisSystemId.equals (systemId))) 863 systemId = null; 864 startElement (name); 865 if (systemId == null) { 866 addAttribute (XmiConstants.XMI_IDREF, xmiId); 867 } else { 868 addAttribute (XmiConstants.XMI_HREF, systemId + HREF_DELIMITER + xmiId); 869 } 870 endElement (name); 871 } 872 873 877 protected void writeValueInAttr (TypedElement attr, Object value) { 878 String name = elementName (attr); 879 String asText; 880 Classifier type = attr.getType (); 881 if (type instanceof EnumerationType) { 882 String prefix = labelPrefix ((EnumerationType) type); 883 asText = value.toString ().substring (prefix.length ()); 885 } else 886 asText = value.toString (); 887 addAttribute (name, asText); 888 } 889 890 893 protected void writeValueInContent (TypedElement attr, Object value) { 894 if (value == null) 895 return; 896 String name = qualifiedName (attr); 897 Classifier type = getType (attr); 898 Collection values; 899 boolean isMultivalued = false; 900 if (attr instanceof StructuralFeature) 901 isMultivalued = isMultivalued ((StructuralFeature) attr); 902 if (isMultivalued) 903 values = (Collection) value; 904 else { 905 values = new LinkedList (); 906 values.add (value); 907 } 908 Iterator iter = values.iterator (); 909 if (type instanceof StructureType) { 910 startElement (name); 911 while (iter.hasNext ()) { 912 writeStructure ((StructureType) type , (RefStruct) iter.next ()); 913 } 914 endElement (name); 915 } else if (type instanceof MofClass) { 916 startElement (name); 917 while (iter.hasNext ()) { 918 RefObject obj = (RefObject) iter.next (); 919 writeInstance (obj, false); 920 } 921 endElement (name); 922 } else if (type instanceof PrimitiveType) { 923 while (iter.hasNext ()) { 924 Object obj = iter.next (); 925 startElement (name); 926 characters (obj.toString ()); 927 endElement (name); 928 } 929 } else if (type instanceof EnumerationType) { 930 while (iter.hasNext ()) { 931 Object obj = iter.next (); 932 startElement (name); 933 String prefix = labelPrefix ((EnumerationType) type); 934 String label = obj.toString ().substring (prefix.length ()); 936 addAttribute (XmiConstants.XMI_VALUE, label); 937 endElement (name); 938 } 939 } else if (type instanceof CollectionType) { 940 startElement (name); 941 while (iter.hasNext ()) { 942 writeCollection ((CollectionType) type , (Collection) iter.next ()); 943 } 944 endElement (name); 945 } else { 946 throw new DebugException ("Unsupported type: " + type.getName ()); 947 } } 949 950 953 987 988 protected void writeStructure (StructureType type, RefStruct value) { 990 Iterator iter = structureFields (type).iterator (); 991 while (iter.hasNext ()) { 992 StructureField field = (StructureField) iter.next (); 993 Classifier fieldType = getType (field); 994 String fieldName = qualifiedName (field); 995 Object fieldValue = value.refGetValue (((ModelElement) field).getName ()); 996 startElement (XmiConstants.XMI_FIELD); 997 if (fieldType instanceof MofClass) 998 writeInstanceRef ((RefObject) fieldValue, false, false); 999 else if (fieldType instanceof StructureType) 1000 writeStructure ((StructureType) fieldType, (RefStruct) fieldValue); 1001 else if (fieldType instanceof CollectionType) 1002 writeCollection ((CollectionType) fieldType, (Collection) fieldValue); 1003 else if (fieldType instanceof PrimitiveType) { 1004 characters (fieldValue.toString ()); 1005 } 1006 endElement (XmiConstants.XMI_FIELD); 1007 } } 1009 1010 protected void writeCollection (CollectionType collType, Collection value) { 1011 String collTypeName = qualifiedName (collType); 1012 startElement (collTypeName); 1013 Iterator iter = value.iterator (); 1014 Classifier type = collType.getType (); 1015 String typeName = qualifiedName (type); 1016 if (type instanceof MofClass) { 1017 while (iter.hasNext ()) { 1018 writeInstanceRef ((RefObject) iter.next (), false, false); 1019 } 1020 } else if (type instanceof StructureType) { 1021 while (iter.hasNext ()) { 1022 startElement (typeName); 1023 Object o = iter.next (); 1024 writeStructure ((StructureType) type, (RefStruct) o); 1025 endElement (typeName); 1026 } 1027 } else if (type instanceof CollectionType) { 1028 while (iter.hasNext ()) { 1029 writeCollection ((CollectionType) type, (Collection) iter.next ()); 1031 } 1033 } else if (type instanceof PrimitiveType) { 1034 while (iter.hasNext ()) { 1035 startElement (typeName); 1036 characters (iter.next ().toString ()); 1037 endElement (typeName); 1038 } 1039 } endElement (collTypeName); 1041 } 1042 1043 1046 protected void writeReference (RefObject obj, Reference ref) { 1047 AggregationKind kind = ref.getReferencedEnd ().getAggregation (); 1048 if (AggregationKindEnum.COMPOSITE.equals (kind)) 1049 return; kind = ref.getExposedEnd ().getAggregation (); 1051 boolean isComposite = AggregationKindEnum.COMPOSITE.equals (kind); 1052 Object temp = obj.refGetValue (ref); 1053 if (temp == null) 1054 return; 1055 Collection values; 1056 if (isMultivalued (ref)) 1057 values = (Collection) temp; 1058 else { 1059 values = new LinkedList (); 1060 values.add (temp); 1061 } 1062 Iterator iter; 1063 1064 if (collectionWriting) { 1065 Collection cValues = new LinkedList (); 1067 iter = values.iterator (); 1068 while (iter.hasNext ()) { 1069 RefObject referencedObject = (RefObject) iter.next (); 1070 if (isInClosure (referencedObject)) { 1071 cValues.add (referencedObject); 1072 } } values = cValues; 1075 } 1077 if (values.isEmpty ()) 1078 return; 1079 1080 String name = qualifiedName (ref); 1081 startElement (name); 1082 iter = values.iterator (); 1083 while (iter.hasNext ()) { 1084 RefObject endValue = (RefObject) iter.next (); 1085 if (isComposite) 1086 writeInstance (endValue, false); 1087 else 1088 writeInstanceRef (endValue, false, false); 1089 } endElement (name); 1091 } 1092 1093 1097 protected void writeStaticAttributes (RefPackage pkg) { 1098 if (processedPackages.contains (pkg)) 1099 return; 1100 Iterator iter = pkg.refAllClasses ().iterator (); 1101 while (iter.hasNext ()) { 1102 RefClass proxy = (RefClass) iter.next (); 1103 Iterator attrs = classAttributes ((MofClass) proxy.refMetaObject ()).iterator (); 1104 while (attrs.hasNext ()) { 1105 Attribute attr = (Attribute) attrs.next (); 1106 writeValueInContent (attr, proxy.refGetValue (attr)); 1107 } } processedPackages.add (pkg); 1110 Iterator containedPackages = pkg.refAllPackages ().iterator (); 1112 while (containedPackages.hasNext ()) 1113 writeStaticAttributes ((RefPackage) containedPackages.next ()); 1114 } 1115 1116 1120 protected void writeAssociations (RefPackage pkg) { 1121 if (processedPackages.contains (pkg)) 1122 return; 1123 Iterator iter = pkg.refAllAssociations ().iterator (); 1124 while (iter.hasNext ()) { 1125 RefAssociation proxy = (RefAssociation) iter.next (); 1126 Association assoc = (Association) proxy.refMetaObject (); 1127 if (assoc.isDerived ()) 1128 continue; 1129 boolean aLinkWritten = false; 1131 String name = qualifiedName (assoc); 1132 AssociationEnd end1 = null, end2 = null; 1133 1134 Iterator content = assoc.getContents ().iterator (); 1135 while (content.hasNext ()) { 1136 Object obj = content.next (); 1137 if (obj instanceof AssociationEnd) { 1138 if (end1 == null) 1139 end1 = (AssociationEnd) obj; 1140 else { 1141 end2 = (AssociationEnd) obj; 1142 break; 1143 } 1144 } } MofClass type1 = (MofClass) end1.getType (); 1147 MofClass type2 = (MofClass) end2.getType (); 1148 boolean isComposite1 = AggregationKindEnum.COMPOSITE.equals(end1.getAggregation ()); 1149 boolean isComposite2 = AggregationKindEnum.COMPOSITE.equals(end2.getAggregation ()); 1150 boolean ref_1_exists = referenceExists (type1, end2); 1151 boolean ref_2_exists = referenceExists (type2, end1); 1152 1153 if ((ref_1_exists && ref_2_exists) || 1154 (ref_1_exists && !isComposite2) || 1155 (ref_2_exists && !isComposite1)) 1156 continue; 1158 boolean isNavigable1 = end1.isNavigable (); 1159 boolean isNavigable2 = end2.isNavigable (); 1160 1161 HashMap cache_1 = new HashMap (); 1164 HashMap cache_2 = new HashMap (); 1165 Iterator links = proxy.refAllLinks ().iterator (); 1166 1167 while (links.hasNext ()) { 1168 RefAssociationLink link = (RefAssociationLink) links.next (); 1169 RefObject value_1 = link.refFirstEnd (); 1170 RefObject value_2 = link.refSecondEnd (); 1171 1172 if (collectionWriting && !(isInClosure (value_1) && isInClosure (value_2))) 1173 continue; 1174 1175 Boolean flag_1 = Boolean.FALSE, flag_2 = Boolean.FALSE; 1176 if (isNavigable1) { 1177 type1 = (MofClass) value_1.refMetaObject (); 1178 flag_1 = (Boolean ) cache_1.get (type1); 1179 if (flag_1 == null) { 1180 if (referenceExists (type1, end2)) 1181 flag_1 = Boolean.TRUE; 1182 else 1183 flag_1 = Boolean.FALSE; 1184 cache_1.put (type1, flag_1); 1185 } } if (isNavigable2) { 1188 type2 = (MofClass) value_2.refMetaObject (); 1189 flag_2 = (Boolean ) cache_2.get (type2); 1190 if (flag_2 == null) { 1191 if (referenceExists (type2, end1)) 1192 flag_2 = Boolean.TRUE; 1193 else 1194 flag_2 = Boolean.FALSE; 1195 cache_2.put (type2, flag_2); 1196 } } 1199 ref_1_exists = flag_1.booleanValue(); 1200 ref_2_exists = flag_2.booleanValue(); 1201 1202 if ((ref_1_exists && ref_2_exists) || 1203 (ref_1_exists && !isComposite2) || 1204 (ref_2_exists && !isComposite1)) 1205 continue; 1206 1207 if (!aLinkWritten) { 1209 startElement (name); 1211 aLinkWritten = true; 1212 } 1213 writeInstanceRef (value_1, false, false); writeInstanceRef (value_2, false, false); } if (aLinkWritten) 1217 endElement (name); 1218 } 1220 processedPackages.add (pkg); 1221 Iterator containedPackages = pkg.refAllPackages ().iterator (); 1222 while (containedPackages.hasNext ()) 1223 writeAssociations ((RefPackage) containedPackages.next ()); 1224 } 1225 1226 1227 1230 protected boolean referenceExists (MofClass mofClass, AssociationEnd assocEnd) { 1231 if (!assocEnd.isNavigable ()) { 1232 return false; 1233 } 1234 Iterator references = references (mofClass).iterator (); 1235 while (references.hasNext ()) { 1236 Reference ref = (Reference) references.next (); 1237 AssociationEnd end = ref.getReferencedEnd (); 1238 if (end.equals (assocEnd)) 1239 return true; 1240 } 1241 return false; 1242 } 1243 1244 1247 protected boolean isInClosure (RefObject obj) { 1248 RefObject container = obj; 1249 RefFeatured featured; 1250 while (container != null) { 1251 if (objectsToWrite.contains (container)) 1252 return true; 1253 featured = container.refImmediateComposite (); 1254 container = ((featured instanceof RefObject) && (featured != obj))? (RefObject) featured : null; 1255 } 1256 return false; 1257 } 1258 1259 1262 protected String qualifiedName (ModelElement element) { 1263 Iterator iter = element.getQualifiedName ().iterator (); 1264 String name = (String ) iter.next (); 1265 while (iter.hasNext ()) 1266 name = name.concat (XmiConstants.DOT_SEPARATOR).concat ((String ) iter.next ()); 1267 1268 int index = name.lastIndexOf ('.'); 1269 String pName = name.substring (0, index); 1270 String sName = name.substring (index + 1, name.length ()); 1271 if (!(element instanceof MofClass) && !(element instanceof Association)) { 1272 index = pName.lastIndexOf ('.'); 1273 if (index > -1) { 1274 pName = pName.substring (0, index); 1275 sName = name.substring (index + 1, name.length ()); 1276 } 1277 } 1278 1279 String namespace = (String ) namespaces.get (pName); 1280 1281 if (namespace != null) 1282 return namespace + ":" + sName; 1283 return name; 1284 } 1285 1286 protected String elementName (ModelElement elem) { 1287 return elem.getName (); 1288 } 1289 1290 1293 protected static boolean isMultivalued (StructuralFeature feature) { 1294 MultiplicityType multType = feature.getMultiplicity (); 1295 return multType.getUpper () != 1; 1296 } 1297 1298 protected static Classifier getType (TypedElement elem) { 1299 Classifier type = elem.getType (); 1300 while (type instanceof AliasType) 1301 type = ((AliasType) type).getType (); 1302 return type; 1303 } 1304 1305 1307 class DefaultProvider implements XMIReferenceProvider { 1308 1309 public XMIReferenceProvider.XMIReference getReference (RefObject obj) { 1310 return new XMIReferenceProvider.XMIReference (null, getXmiId(obj)); 1311 } 1312 1313 } 1314 1315} 1316 | Popular Tags |