|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.lib.jmi.xmi; import java.io.*; import java.util.*; import javax.jmi.reflect.*; import javax.jmi.model.*; import org.netbeans.lib.jmi.util.DebugException; import org.netbeans.lib.jmi.util.Logger; public class XmiDtdProducer extends org.netbeans.api.mdr.DTDProducer { public static String TAG_ELEMENT = "!ELEMENT"; public static String TAG_ATTLIST = "!ATTLIST"; public static String TAG_REQUIRED = "#REQUIRED"; public static String TAG_PCDATA = "#PCDATA"; public static String TAG_CDATA = "CDATA"; public static String TAG_IMPLIED = "#IMPLIED"; public static String TAG_IDREFS = "IDREFS"; public static String TAG_EMPTY = "EMPTY"; public static String TAG_XMI_REFERENCE = "XMI.reference"; public static String TAG_XMI_EXTENSION = "XMI.extension"; public static String TAG_XMI_VALUE = "xmi.value"; public static String TAG_XMI_FIXED_ATTRIBS = "%XMI.element.att; %XMI.link.att;"; // String used in DTD fixed file to mark end of the licence part. private static String END_OF_LICENCE_MARKER = ""; // Fixed DTD file name. private static String FIXED_DTD_FILE = "resources/fixed.dtd"; // treshold (number of chars) for line breaking when writing !ELEMENT private static int LINE_BOUND = 60; // output stream to which the produced DTD is written private PrintStream stream; // main package extent private RefPackage extent; // elements cache used to obtain classes' attributes, references, etc. private ElementsCache elementsCache; // stored already processed packages private Set trackedPackages; // stores mapping class -> set of all direct subtypes private Map classHierarchy; // cache for mapping class -> all subtypes (direct and non-direct) private Map allSubtypes_cache; // mapping MofPackage -> namespace name private Map namespaces; // flag indicating, if first item in !ELEMENT is to be written private boolean isFirstItem; // counter of characters in currently writen line (used when writing !ELEMENT) private int charsCounter; // init ..................................................................... public void init () { elementsCache = new ElementsCache (extent); trackedPackages = new HashSet (); classHierarchy = new HashMap (); allSubtypes_cache = new HashMap (); namespaces = new HashMap (); elementsCache = new ElementsCache (extent); findNamespaces (extent); trackedPackages.clear (); } // methods .................................................................. public void startElement (String name) { stream.println (); isFirstItem = true; stream.print ("<" + TAG_ELEMENT + " "); stream.print (name); charsCounter = TAG_ELEMENT.length () + 2 + name.length (); } public void addEmptyElement () { stream.println (" " + TAG_EMPTY + ">"); } public void addElementItem (String name) { if (!isFirstItem) { stream.print (" | "); charsCounter += 3; } else { isFirstItem = false; stream.print (" ("); charsCounter += 2; } charsCounter += name.length (); if (charsCounter > LINE_BOUND) { stream.println (); stream.print (" "); charsCounter = 4; } stream.print (name); } public void endElement () { stream.println (")* >"); } public void startAttlist (String text) { stream.print ("<" + TAG_ATTLIST + " "); stream.print (text); } public void addAttlistItem (String text) { stream.println (); stream.print (" " + text); } public void endAttlist () { stream.println (">"); } // .......................................................................... /** Generates DTD based on outermost package. * * @param outermost package */ public void generate (OutputStream stream, RefPackage extent) { this.stream = new PrintStream (stream); this.extent = extent; init (); writeFixedContent (); writeNamespaces (); writePackageDTD (extent); try { stream.flush (); stream.close (); } catch (IOException e) { e.printStackTrace (); } } public void writePackageDTD (RefPackage pkg) { if (trackedPackages.contains (pkg)) { return; } else { trackedPackages.add (pkg); } Iterator iter = pkg.refAllPackages ().iterator (); while (iter.hasNext ()) { writePackageDTD ((RefPackage) iter.next ()); } iter = pkg.refAllClasses ().iterator (); while (iter.hasNext ()) { writeClassDTD ((RefClass) iter.next ()); } iter = pkg.refAllClasses ().iterator (); while (iter.hasNext ()) { writeStaticAttributesDTD ((RefClass) iter.next ()); } iter = getFreeAssociations (pkg).iterator (); while (iter.hasNext ()) { writeAssociationDTD ((Association) iter.next ()); } writePackageElementDef (pkg); } public void writeClassDTD (RefClass proxy) { Iterator iter; String text; StringBuffer buffer = new StringBuffer (); MofClass meta = (MofClass) proxy.refMetaObject (); String className = objectName (meta); List instAttrs, references; instAttrs = elementsCache.instanceAttributes (meta); references = elementsCache.references (meta); // attribute element definitions iter = instAttrs.iterator (); while (iter.hasNext ()) { Attribute attr = (Attribute) iter.next (); if (attr.getContainer () == meta) { writeAttributeElemDef (attr); } } // while // reference element definitions iter = references.iterator (); while (iter.hasNext ()) { Reference ref = (Reference) iter.next (); if (ref.getContainer () != meta) continue; startElement (elementName (ref)); MofClass type = (MofClass) ref.getType (); Iterator it = elementsCache.getAllSubtypes ((MofClass) type).iterator (); while (it.hasNext ()) { addElementItem (objectName ((MofClass) it.next ())); } // while endElement (); } // while // class element definition startElement (className); Iterator it; for (it = instAttrs.iterator (); it.hasNext ();) { addElementItem (elementName ((Attribute) it.next ())); } for (it = references.iterator (); it.hasNext ();) { addElementItem (elementName ((Reference) it.next ())); } for (it = getComposites (meta).iterator (); it.hasNext ();) { addElementItem (objectName ((MofClass) it.next ())); } addElementItem (TAG_XMI_EXTENSION); endElement (); buffer.delete(0, buffer.length ()); startAttlist (className); for (it = references.iterator (); it.hasNext ();) { // ? [PENDING] non-composite reference, multiplicity 1 allowed ... buffer.append (((Reference) it.next ()).getName ()); buffer.append (" " + TAG_IDREFS + " " + TAG_IMPLIED); addAttlistItem (buffer.toString ()); buffer.delete(0, buffer.length ()); } for (it = instAttrs.iterator (); it.hasNext ();) { Attribute attr = (Attribute) it.next (); buffer.append (attr.getName ()); Classifier type = getType (attr); if (type instanceof EnumerationType) { int prefixLength = labelPrefix ((EnumerationType) type).length (); buffer.append (" ("); for (Iterator it_2 = ((EnumerationType) type).getLabels ().iterator (); it_2.hasNext ();) { buffer.append (((String) it_2.next ()).substring (prefixLength)); if (it_2.hasNext ()) buffer.append ("|"); } buffer.append (") " + TAG_IMPLIED); } else if (type instanceof MofClass) { buffer.append (" " + TAG_IDREFS + " " + TAG_IMPLIED); } else { buffer.append (" " + TAG_CDATA + " " + TAG_IMPLIED); } addAttlistItem (buffer.toString ()); buffer.delete(0, buffer.length ()); } addAttlistItem (TAG_XMI_FIXED_ATTRIBS); endAttlist (); } public void writeStaticAttributesDTD (RefClass proxy) { MofClass meta = (MofClass) proxy.refMetaObject (); for (Iterator iter = elementsCache.classAttributes (meta).iterator (); iter.hasNext ();) { Attribute attr = (Attribute) iter.next (); if (attr.getContainer () == meta) writeAttributeElemDef (attr); } } public void writeAssociationDTD (Association assoc) { String name; Set subtypes = new HashSet (); for (Iterator iter = assoc.getContents ().iterator (); iter.hasNext ();) { Object elem = iter.next (); if (elem instanceof AssociationEnd) { subtypes.addAll (elementsCache.getAllSubtypes ((MofClass) ((AssociationEnd) elem).getType ())); } // if } // for name = objectName (assoc); startElement (name); for (Iterator iter = subtypes.iterator (); iter.hasNext ();) { addElementItem (objectName ((MofClass) iter.next ())); } addElementItem (TAG_XMI_EXTENSION); endElement (); startAttlist (name); addAttlistItem (TAG_XMI_FIXED_ATTRIBS); endAttlist (); /* String name; String end_name [] = new String [2]; int num = 0; for (Iterator iter = assoc.getContents ().iterator (); iter.hasNext ();) { Object elem = iter.next (); if (elem instanceof AssociationEnd) { AssociationEnd end = (AssociationEnd) elem; name = elementName (end); end_name [num++] = name; startElement (name); addEmptyElement (); startAttlist (name); addAttlistItem (TAG_XMI_FIXED_ATTRIBS); endAttlist (); } // if } // for name = objectName (assoc); startElement (name); addElementItem (end_name [0]); addElementItem (end_name [1]); addElementItem (TAG_XMI_EXTENSION); endElement (); startAttlist (name); addAttlistItem (TAG_XMI_FIXED_ATTRIBS); endAttlist (); */ } public void writeAttributeElemDef (Attribute attr) { StringBuffer buffer = new StringBuffer (); Classifier type = getType (attr); boolean isEnum = type instanceof EnumerationType; startElement (elementName (attr)); if (isEnum) { // AttribEnum addEmptyElement (); } else if (type instanceof MofClass) { // AttribMofClass Iterator it = elementsCache.getAllSubtypes ((MofClass) type).iterator (); addElementItem (objectName ((MofClass) it.next ())); while (it.hasNext ()) { MofClass clazz = (MofClass) it.next (); addElementItem (objectName (clazz)); } // while endElement (); } else if (type instanceof StructureType) { // StructureType addElementItem ("XMI.field"); endElement (); } else { // AttribData addElementItem (TAG_PCDATA); addElementItem (TAG_XMI_REFERENCE); endElement (); } if (isEnum) { int prefixLength = labelPrefix ((EnumerationType) type).length (); buffer = new StringBuffer (); startAttlist (elementName (attr)); buffer.append (TAG_XMI_VALUE + " ("); Iterator it = ((EnumerationType) type).getLabels ().iterator (); while (it.hasNext ()) { buffer.append (((String) it.next ()).substring (prefixLength)); if (it.hasNext ()) buffer.append ("|"); } buffer.append (") " + TAG_REQUIRED); addAttlistItem (buffer.toString ()); endAttlist (); } } /** * Writes fixed part of XMI DTD content. */ public void writeFixedContent () { java.net.URL fixedDTD = getClass().getResource(FIXED_DTD_FILE); if (fixedDTD == null) { throw new DebugException("Resource not found: " + FIXED_DTD_FILE); } try { InputStream in = fixedDTD.openStream (); BufferedReader reader = new BufferedReader (new InputStreamReader(in)); String line; // skip licence do { line = reader.readLine (); } while (!line.equals (END_OF_LICENCE_MARKER)); // copy fixed DTD elements line = reader.readLine (); while (line != null) { stream.println (line); line = reader.readLine(); } } catch (IOException e) { Logger.getDefault().log("Unable to open " + FIXED_DTD_FILE + ": " + e.getMessage()); throw new DebugException (e.getMessage ()); } } public void writeNamespaces () { Set names = new HashSet (); if (namespaces.size () > 0) { startAttlist ("XMI"); for (Iterator iter = namespaces.entrySet ().iterator (); iter.hasNext ();) { Object name = ((Map.Entry) iter.next ()).getValue (); if (!names.contains (name)) { addAttlistItem ("xmlns:" + name + " " + TAG_CDATA + " " + TAG_IMPLIED); names.add (name); } } // for endAttlist (); } // if } public void writePackageElementDef (RefPackage pkg) { MofPackage meta = (MofPackage) pkg.refMetaObject (); String packageName = packageName (meta); Set classes = new HashSet (); StringBuffer buffer = new StringBuffer (); for (Iterator iter = pkg.refAllClasses ().iterator (); iter.hasNext ();) { classes.addAll (elementsCache.getAllSubtypes ((MofClass) ((RefClass) iter.next ()).refMetaObject ())); } startElement (packageName); // owned classes for (Iterator iter = classes.iterator (); iter.hasNext ();) { addElementItem (objectName ((MofClass) iter.next ())); } // owned associations that are not accessible via any reference for (Iterator iter = getFreeAssociations (pkg).iterator (); iter.hasNext ();) { addElementItem (objectName ((Association) iter.next ())); } // nested packages (imported are excluded, is it correct ? [PENDING]) for (Iterator iter = pkg.refAllPackages ().iterator (); iter.hasNext ();) { RefPackage refPkg = (RefPackage) iter.next (); MofPackage metaPkg = (MofPackage) refPkg.refMetaObject (); if (metaPkg.getContainer () == meta) { addElementItem (packageName (metaPkg)); } } // XMI.extension addElementItem (TAG_XMI_EXTENSION); endElement (); // attributes startAttlist (packageName); addAttlistItem (TAG_XMI_FIXED_ATTRIBS); endAttlist (); } // helper methods ........................................................... /** * Finds and caches namespace declarations. */ private void findNamespaces (RefPackage pkg) { String name; Iterator iter; if (trackedPackages.contains (pkg)) return; else trackedPackages.add (pkg); MofPackage metaPackage = (MofPackage) pkg.refMetaObject (); name = WriterBase.getTagValue (metaPackage, XmiConstants.TAGID_XMI_NAMESPACE); if (name != null) { namespaces.put (metaPackage, name); } iter = pkg.refAllPackages ().iterator (); while (iter.hasNext ()) { findNamespaces ((RefPackage) iter.next ()); } } public String elementName (ModelElement element) { ModelElement container = element.getContainer (); return objectName (container) + '.' + element.getName (); } public String objectName (ModelElement element) { String namespace = (String) namespaces.get (element.getContainer ()); if (namespace != null) { return namespace + ":" + element.getName (); } else { return qualifiedName (element); } } public String packageName (MofPackage pkg) { String namespace = (String) namespaces.get (pkg); if (namespace != null) { return namespace + ":" + pkg.getName (); } else { return qualifiedName (pkg); } } public String qualifiedName (ModelElement element) { Iterator iter = element.getQualifiedName ().iterator (); String name = (String) iter.next (); while (iter.hasNext ()) { name = name.concat (XmiConstants.DOT_SEPARATOR).concat ((String) iter.next ()); } return name; } /** * Returns labels prefix given by "unprefix" tag attached to EnumerationType or * the empty String if no such tag is present. */ public String labelPrefix (EnumerationType type) { String prefix = WriterBase.getTagValue (type, XmiConstants.TAGID_XMI_ENUMERATION_UNPREFIX); if (prefix == null) prefix = ""; return prefix; } /** * Returns type of the typed element. Aliases are substituted by proper types. */ public Classifier getType (TypedElement elem) { Classifier type = elem.getType (); while (type instanceof AliasType) type = ((AliasType) type).getType (); return type; } public Set getComposites (MofClass meta) { return new HashSet (); /* Set set = new HashSet (); Iterator iter = elementsCache.instanceAttributes (meta).iterator (); while (iter.hasNext ()) { Attribute attr = (Attribute) iter.next (); Classifier type = attr.getType (); if (type instanceof MofClass) set.add (type); } iter = elementsCache.references (meta).iterator (); while (iter.hasNext ()) { Reference ref = (Reference) iter.next (); if (AggregationKindEnum.COMPOSITE.equals (ref.getReferencedEnd ().getAggregation ())) set.add (ref.getType ()); } Set result = new HashSet (); iter = set.iterator (); while (iter.hasNext ()) { Set temp = elementsCache.getAllSubtypes ((MofClass) iter.next ()); result.addAll(temp); } return result; */ } /** * Returns associations in the package that are not accessible via any reference. */ public Set getFreeAssociations (RefPackage pkg) { ModelPackage model = (ModelPackage) pkg.refMetaObject ().refImmediatePackage (); RefersTo refersTo = model.getRefersTo (); Set set = new HashSet (); for (Iterator iter = pkg.refAllAssociations ().iterator (); iter.hasNext ();) { Association assoc = (Association) ((RefAssociation) iter.next ()).refMetaObject (); boolean found = false; for (Iterator it = assoc.getContents ().iterator (); it.hasNext ();) { Object elem = it.next (); if (elem instanceof AssociationEnd) { Collection col = refersTo.getReferent ((AssociationEnd) elem); if ((col != null) && (col.size () > 0)) { found = true; break; } } } // for if (!found) { set.add (assoc); } } // for return set; } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.