|
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.