|
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 java.net.URL;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.netbeans.lib.jmi.util.DebugException;
import org.netbeans.api.xmi.*;
import javax.jmi.reflect.*;
import javax.jmi.model.*;
import org.netbeans.lib.jmi.util.Logger;
public class WriterBase extends XMIWriter {
private static final String XMI_VERSION = "1.2";
public static final String EXPORTER_NAME = "Netbeans XMI Writer";
public static final String EXPORTER_VERSION = "1.0";
public static final int ATTR_HREF = 0;
public static final int ATTR_XMI_ID = 1;
public static final int ATTR_XMI_IDREF = 2;
public static final char HREF_DELIMITER = '#';
// variables ................................................................
// content handler used to produce XMI
protected ContentHandler contentHandler;
// output config
protected OutputConfig configuration;
// header provider
protected XMIHeaderProvider headerProvider = null;
// xmi reference provider
protected XMIReferenceProvider provider;
// default xmi reference provider
protected XMIReferenceProvider defaultProvider = new DefaultProvider ();
// encoding to be used
protected String encoding = null;
// attributes added for currently processed element
protected AttributesImpl attributes;
// system id of the document the writer writes in or null if it is not known
protected String thisSystemId = null;
// name of the currently processed element
protected String elementName;
// indicates if some element is being currently processed
protected boolean elementStarted;
protected OutputStreamWriter stream;
// temp variable storing passed OutputStream parameter to be used by init () method
protected OutputStream outputStream = null;
// known namespaces
protected HashMap namespaces;
// stores objects to be written having immediate composite serialized in some external document
protected List lightOutermosts;
// stores all currently written components
protected Set writtenComponents;
// used to detect components that stay unwritten because of presence of composite associations with ends that are not visible via references
protected Set nonWrittenComponents;
// stores all instances having already generated xmi id (RefObject - key, String - value)
protected HashMap xmiIds;
// counts the number of all serialized instances
protected int instancesCounter = 0;
/* Serves to record already processed packages (when contents of packages are processed
* recursive - see writePackage, writeAssociations, writeStaticAttributes and findNamespaces
* methods) to avoid multiple searching trough a package.
*/
protected HashSet processedPackages;
// caches storing instance-scoped and class-scoped attributes and references
protected HashMap instanceAttributes_cache;
protected HashMap classAttributes_cache;
protected HashMap references_cache;
// cache storing structures' fields
protected HashMap structureFields_cache;
// cache storing enum prefixes specified by a tag attached to EnumerationType
protected HashMap labelPrefix_cache;
// indicates if the method writing Collection of RefObjects is called or not
protected boolean collectionWriting = false;
// set and list of outermost composite objects to be write by write(Collection) method
protected Set objectsToWrite = null;
protected List objectsToWriteAsCollection = null;
// init .....................................................................
public WriterBase() {
configuration = new OutputConfig ();
}
public WriterBase(XMIOutputConfig config) {
configuration = new OutputConfig ();
configuration.setReferenceProvider (config.getReferenceProvider ());
if (config instanceof OutputConfig) {
configuration.setHeaderProvider (((OutputConfig) config).getHeaderProvider());
configuration.setEncoding (((OutputConfig) config).getEncoding());
}
}
public void init () throws IOException {
collectionWriting = false;
attributes = new AttributesImpl ();
namespaces = new HashMap ();
xmiIds = new HashMap ();
nonWrittenComponents = new HashSet ();
writtenComponents = new HashSet ();
processedPackages = new HashSet ();
instancesCounter = 0;
instanceAttributes_cache = new HashMap ();
classAttributes_cache = new HashMap ();
references_cache = new HashMap ();
structureFields_cache = new HashMap ();
labelPrefix_cache = new HashMap ();
lightOutermosts = new LinkedList ();
if (configuration == null) {
provider = defaultProvider;
} else {
provider = configuration.getReferenceProvider ();
if (provider == null)
provider = defaultProvider;
if (configuration instanceof OutputConfig) {
headerProvider = ((OutputConfig) configuration).getHeaderProvider ();
encoding = ((OutputConfig) configuration).getEncoding ();
}
}
if (outputStream != null) {
try {
if (encoding == null) {
stream = new OutputStreamWriter (outputStream);
} else {
stream = new OutputStreamWriter (outputStream, encoding);
}
contentHandler = new DefaultWriter (stream, encoding);
// clear outputStream variable
outputStream = null;
} catch (UnsupportedEncodingException e) {
throw new IOException ("Unsupported encoding: " + encoding);
}
} // if
}
// javax.jmi.xmi.XmiWriter interface implementation .........................
public void write (OutputStream os, RefPackage extent, String xmiVersion) throws IOException {
write (os, null, extent, xmiVersion);
}
public void write (OutputStream os, Collection objects, String xmiVersion) throws IOException {
write (os, null, objects, xmiVersion);
}
public void write(OutputStream stream, RefPackage extent) {
try {
write(stream, extent, null);
} catch (IOException e) {
DebugException ne = new DebugException(e.toString());
Logger.getDefault().annotate(ne, e);
throw ne;
}
}
// org.netbeans.api.xmi.XMIWriter implmentation .............................
public XMIOutputConfig getConfiguration() {
return configuration;
}
public void write(OutputStream stream, String uri, RefPackage extent, String xmiVersion) throws IOException {
thisSystemId = uri;
outputStream = stream;
write (extent);
}
public void write(OutputStream stream, String uri, Collection objects, String xmiVersion) throws IOException {
thisSystemId = uri;
outputStream = stream;
write (objects);
}
// ..........................................................................
public void write(ContentHandler handler, String uri, RefPackage extent, String xmiVersion) throws IOException {
thisSystemId = uri;
contentHandler = handler;
write (extent);
}
public void write(ContentHandler handler, String uri, Collection objects, String xmiVersion) throws IOException {
thisSystemId = uri;
contentHandler = handler;
write (objects);
}
public void write (RefPackage extent) throws IOException {
Logger.getDefault().log("XMI writer started");
long time = System.currentTimeMillis ();
init ();
processedPackages.clear ();
findNamespaces (extent);
writeDocument (extent);
time = System.currentTimeMillis () - time;
Logger.getDefault().log("finished, TIME: " + time/1000.0 + "[s]");
}
public void write (Collection objects) throws IOException {
init ();
//
collectionWriting = true;
//
processedPackages.clear ();
RefPackage extent;
objectsToWrite = new HashSet ();
objectsToWriteAsCollection = new LinkedList ();
Set tempSet = new HashSet ();
if ((objects == null) || (objects.size () == 0)) {
extent = null;
} else {
Iterator iter = objects.iterator ();
while (iter.hasNext ()) {
Object obj = iter.next ();
if (!(obj instanceof RefObject))
throw new DebugException ("Bad object (not instance of RefObject) in input collection: " + obj.getClass ().getName ());
tempSet.add (obj);
} // while
iter = objects.iterator ();
RefFeatured featured;
RefObject container;
while (iter.hasNext ()) {
RefObject obj = (RefObject) iter.next ();
container = obj;
boolean found = false;
do {
featured = container.refImmediateComposite ();
container = (featured instanceof RefObject) ? (RefObject) featured : null;
if ((container != null) && tempSet.contains (container)) {
found = true;
break;
}
} while (container != null);
if (!found) {
objectsToWrite.add (obj);
objectsToWriteAsCollection.add (obj);
}
} // while
extent = ((RefObject) objectsToWriteAsCollection.get (0)).refOutermostPackage ();
findNamespaces (extent);
}
writeDocument (extent);
}
// methods ..................................................................
protected void findNamespaces (RefPackage pkg) {
String name;
Iterator iter;
if (processedPackages.contains (pkg))
return;
MofPackage metaPackage = (MofPackage) pkg.refMetaObject ();
name = getTagValue (metaPackage, XmiConstants.TAGID_XMI_NAMESPACE);
if (name != null) {
iter = metaPackage.getQualifiedName ().iterator ();
String fqName = (String) iter.next ();
while (iter.hasNext ())
fqName = fqName.concat (XmiConstants.DOT_SEPARATOR).concat ((String) iter.next ());
namespaces.put (fqName, name);
}
processedPackages.add (pkg);
iter = pkg.refAllPackages ().iterator ();
while (iter.hasNext ()) {
findNamespaces ((RefPackage) iter.next ());
}
}
public static String getTagValue (ModelElement element, String tagId) {
Collection tags = ((ModelPackage) element.refImmediatePackage()).
getAttachesTo().getTag (element);
Tag tag = null;
for (Iterator it = tags.iterator(); it.hasNext();) {
Object obj = it.next ();
if (!(obj instanceof Tag))
continue;
Tag temp = (Tag) obj;
if (tagId.equals (temp.getTagId ())) {
tag = temp;
break;
}
}
if (tag == null)
return null;
Collection values = tag.getValues ();
if (values.size () == 0)
return null;
return (String) values.iterator ().next ();
}
/**
* Finds all attributes and references belonging to a mof class and caches them.
*/
protected void cacheContainedElements (MofClass mofClass) {
List temp = new LinkedList ();
List superClasses = mofClass.allSupertypes ();
Namespace namespace = null;
Iterator it = superClasses.iterator ();
while (it.hasNext ()) {
namespace = (Namespace) it.next ();
temp.addAll (namespace.getContents ());
}
temp.addAll (mofClass.getContents ());
List instanceAttributes = new LinkedList ();
List classAttributes = new LinkedList ();
List references = new LinkedList ();
Set referencedEnds = new HashSet ();
it = temp.iterator ();
while (it.hasNext ()) {
RefObject refObject = (RefObject) it.next ();
if (refObject instanceof Feature) {
boolean instanceLevel = ((Feature) refObject).getScope ().equals (ScopeKindEnum.INSTANCE_LEVEL);
if ((refObject instanceof Attribute) && (!((Attribute) refObject).isDerived ())) {
if (instanceLevel) {
instanceAttributes.add (refObject);
} else {
classAttributes.add (refObject);
}
} else if (refObject instanceof Reference) {
AssociationEnd end = ((Reference) refObject).getReferencedEnd ();
Association assoc = (Association) end.getContainer ();
if (!assoc.isDerived () && !referencedEnds.contains (end)) {
references.add (refObject);
referencedEnds.add (end);
}
} // else
} // if (refObject instanceof Feature)
} // while
instanceAttributes_cache.put (mofClass, instanceAttributes);
classAttributes_cache.put (mofClass, classAttributes);
references_cache.put (mofClass, references);
}
/**
* For a given mof class, returns list of all instance-scoped attributes
* (references are not included).
*
* @param mofClass
* @return list of all non-derived instance-scoped attributes (including inherited ones)
*/
protected List instanceAttributes (MofClass mofClass) {
List list = (List) instanceAttributes_cache.get (mofClass);
if (list == null) {
cacheContainedElements (mofClass);
list = (List) instanceAttributes_cache.get (mofClass);
}
return list;
}
/**
* For a given mof class, returns list of all class-scoped attributes.
*
* @param mofClass
* @return list of all non-derived class-scoped attributes (including inherited ones)
*/
protected List classAttributes (MofClass mofClass) {
List list = (List) classAttributes_cache.get (mofClass);
if (list == null) {
cacheContainedElements (mofClass);
list = (List) classAttributes_cache.get (mofClass);
}
return list;
}
/**
* For a given mof class, returns list of all references.
*
* @param mofClass
* @return list of all non-derived references (including inherited ones)
*/
protected List references (MofClass mofClass) {
List list = (List) references_cache.get (mofClass);
if (list == null) {
cacheContainedElements (mofClass);
list = (List) references_cache.get (mofClass);
}
return list;
}
/**
* Returns list of all fields belonging to the given StructureType.
*/
public List structureFields (StructureType type) {
List fields = (List) structureFields_cache.get (type);
if (fields != null)
return fields;
// find fields and cache them
fields = new LinkedList ();
Iterator content = type.getContents ().iterator ();
while (content.hasNext ()) {
Object element = content.next ();
if (element instanceof StructureField)
fields.add (element);
} // while
structureFields_cache.put (type, fields);
return fields;
}
/**
* 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 = (String) labelPrefix_cache.get (type);
if (prefix != null)
return prefix;
prefix = getTagValue (type, XmiConstants.TAGID_XMI_ENUMERATION_UNPREFIX);
if (prefix == null)
prefix = "";
labelPrefix_cache.put (type, prefix);
return prefix;
}
// **************************************************************************
// Methods related to writing to content handler.
// **************************************************************************
protected void startElement (String name) {
if (elementStarted) {
writeStartElement ();
}
elementName = name;
elementStarted = true;
}
/**
* Writes end of an XML element to the output stream.
*
* @param name name of the XML element to be written
*/
protected void endElement (String name) {
if (elementStarted) {
writeStartElement ();
}
try {
contentHandler.endElement (null, null, name);
} catch (SAXException e) {
}
}
/**
* Writes an attribute of the currenly written XML elemnt to the output stream.
*
* @param name attribute name
* @param value value of the attribute
*/
protected void addAttribute (String name, String value) {
attributes.addAttribute(null, null, name, null, value); // uri, localName, qName, type, value
}
/**
* Writes characters into body of the currenly written XML elemnt.
* Before the string is written, @link #replaceSpecialChars is called
* on it to replace special XML characters.
*
* @param text string to be written
*/
protected void characters (String text) {
if (elementStarted) {
writeStartElement ();
}
try {
contentHandler.characters (text.toCharArray(), 0, text.length ());
} catch (SAXException e) {
}
}
protected void writeStartElement () {
try {
contentHandler.startElement (null, null, elementName, attributes);
} catch (SAXException e) {
}
elementStarted = false;
attributes.clear ();
}
// **************************************************************************
/**
* Checks if a given instance is already cached. In not, generates an xmi.id for it,
* stores it in cache and returns the generated id, otherwise returns already stored id.
*/
protected String getXmiId (RefObject obj) {
String xmiId = ((String) xmiIds.get (obj));
if (xmiId == null) {
instancesCounter++;
xmiId = "a" + instancesCounter;
xmiIds.put (obj, xmiId);
}
return xmiId;
}
/**
* Called when an istances has been written.
*/
protected void markWritten (RefObject obj) {
// used to handle written status of components only
writtenComponents.add (obj);
nonWrittenComponents.remove (obj);
}
protected void writeDocument (RefPackage pkg) {
try {
contentHandler.startDocument();
} catch (SAXException e) {
}
startElement (XmiConstants.XMI_ROOT);
addAttribute ("xmi.version", XMI_VERSION);
writeNamespaces ();
addAttribute ("timestamp", new Date ().toString ());
writeHeader ();
// content
startElement (XmiConstants.XMI_CONTENT);
if (!collectionWriting) {
processedPackages.clear();
writePackage (pkg);
RefObject obj;
while (nonWrittenComponents.size () > 0) {
Iterator iter = nonWrittenComponents.iterator ();
do {
obj = (RefObject) iter.next ();
} while (nonWrittenComponents.contains (obj.refImmediateComposite ()));
writeInstance (obj, true);
while (lightOutermosts.size() > 0) {
obj = (RefObject) lightOutermosts.remove(0);
writeInstance (obj, true);
} // while
} // while
processedPackages.clear();
writeStaticAttributes (pkg);
} else {
writeObjects ();
}
processedPackages.clear();
writeAssociations (pkg);
endElement (XmiConstants.XMI_CONTENT);
// end of content
endElement (XmiConstants.XMI_ROOT);
try {
contentHandler.endDocument();
} catch (SAXException e) {
}
}
protected void writeHeader () {
// header
startElement (XmiConstants.XMI_HEADER);
if ((contentHandler instanceof DefaultWriter) && (headerProvider != null)) {
writeStartElement ();
characters ("");
Writer ps = ((DefaultWriter) contentHandler).getWriter ();
headerProvider.writeHeader (ps);
} else { // write default header
startElement (XmiConstants.XMI_DOCUMENTATION);
// exporter
startElement ("XMI.exporter");
characters (EXPORTER_NAME);
endElement ("XMI.exporter");
// exporter version
startElement ("XMI.exporterVersion");
characters (EXPORTER_VERSION);
endElement ("XMI.exporterVersion");
endElement (XmiConstants.XMI_DOCUMENTATION);
}
endElement (XmiConstants.XMI_HEADER);
// ... end of header
}
protected void writeNamespaces () {
HashMap temp = new HashMap ();
Iterator iter = namespaces.entrySet ().iterator ();
while (iter.hasNext ()) {
String name = (String) ((Map.Entry) iter.next ()).getValue ();
if (temp.get (name) == null) {
temp.put (name, name);
addAttribute ("xmlns:" + name, XmiConstants.TAGID_XMI_NAMESPACE + "." + name);
} // if
} // while
}
/**
* Serializes instances contained in a package and in all its sub-packages.
*/
protected void writePackage (RefPackage pkg) {
if (processedPackages.contains (pkg))
return;
Iterator classes = pkg.refAllClasses ().iterator ();
while (classes.hasNext ()) {
RefClass proxy = (RefClass) classes.next ();
Iterator instances = proxy.refAllOfClass ().iterator ();
while (instances.hasNext ()) {
RefObject obj = (RefObject) instances.next ();
if (obj == null) {
continue;
}
if (obj.equals (obj.refOutermostComposite ())) {
// non-outermost instance is serialized as a part of content
// of an outermost instance
writeInstance (obj, true);
while (lightOutermosts.size() > 0) {
obj = (RefObject) lightOutermosts.remove(0);
writeInstance (obj, true);
} // while
} else {
if (!writtenComponents.contains (obj)) {
nonWrittenComponents.add (obj);
}
}
} // while
} // while
processedPackages.add (pkg);
Iterator containedPackages = pkg.refAllPackages ().iterator ();
while (containedPackages.hasNext ())
writePackage ((RefPackage) containedPackages.next ());
}
protected void writeObjects () {
Iterator iter = objectsToWriteAsCollection.iterator ();
while (iter.hasNext ()) {
writeInstance ((RefObject) iter.next (), true);
}
}
/**
* Serializes an instance.
*
* @param obj object to be serialized
* @param isTop true if the instance is serialized as a top-element (i.e. direct sub-element of
|
| ... 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.