|
|
What this is
This file is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn
Java by Example" TM.
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 XMI20Writer extends WriterBase {
private static final String XMI_VERSION = "2.0";
private static final String XMI_NAMESPACE = "";
private Map nsPrefixToURI;
// init .....................................................................
public XMI20Writer() {
super ();
}
public XMI20Writer(XMIOutputConfig config) {
super (config);
}
public void init () throws IOException {
super.init ();
nsPrefixToURI = new HashMap ();
}
// methods ..................................................................
protected void findNamespaces(RefPackage pkg) {
String name, uri;
Iterator iter;
if (processedPackages.contains (pkg))
return;
MofPackage metaPackage = (MofPackage) pkg.refMetaObject ();
name = getNsPrefixTag (metaPackage);
if (name == null) {
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);
uri = getNsURITag (metaPackage);
if (uri == null) {
uri = "unknown_uri"; // NOI18N
}
nsPrefixToURI.put (name, uri);
}
processedPackages.add (pkg);
iter = pkg.refAllPackages ().iterator ();
while (iter.hasNext ()) {
findNamespaces ((RefPackage) iter.next ());
}
}
protected void writeDocument(RefPackage pkg) {
try {
contentHandler.startDocument();
} catch (SAXException e) {
}
startElement (XMI_NAMESPACE + XmiConstants.XMI_ROOT);
addAttribute (XMI_NAMESPACE + "version", XMI_VERSION);
writeNamespaces ();
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 (XMI_NAMESPACE + XmiConstants.XMI_ROOT);
try {
contentHandler.endDocument();
} catch (SAXException e) {
}
}
protected void writeNamespaces() {
String xmiNamespace = (XMI_NAMESPACE.length () == 0) ? "xmlns" : "xmlns:" + XMI_NAMESPACE.substring (XMI_NAMESPACE.length () - 1);
addAttribute (xmiNamespace, XmiConstants.XMI_NAMESPACE_URI);
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, (String) nsPrefixToURI.get (name));
} // if
} // while
}
/**
* 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 )
*/
protected void writeInstance(RefObject obj, boolean isTop) {
RefClass proxy = obj.refClass ();
ModelElement element = (ModelElement) obj.refMetaObject ();
String name = qualifiedName (element);
XMIReferenceProvider.XMIReference xmiRef = provider.getReference (obj);
String xmiId = xmiRef.getXmiId ();
String systemId = xmiRef.getSystemId ();
if ((systemId != null) && (thisSystemId != null) && (thisSystemId.equals (systemId)))
systemId = null;
markWritten (obj);
if (systemId != null) { // object from an external document
if (!isTop) { // serialize href
startElement (name);
addAttribute (XMI_NAMESPACE + "href", systemId + HREF_DELIMITER + xmiId);
endElement (name);
}
collectLightOutermosts (obj, proxy);
return;
}
startElement (name);
addAttribute (XMI_NAMESPACE + "id", xmiId);
Iterator attrs = instanceAttributes ((MofClass) proxy.refMetaObject ()).iterator ();
List attrsInContent = new LinkedList ();
while (attrs.hasNext ()) {
Attribute attr = (Attribute) attrs.next ();
if (!isSerializeTag (attr)) {
continue;
} else if (isElementTag (attr)) {
attrsInContent.add (attr);
continue;
}
boolean isMultivalued = isMultivalued (attr);
Object value;
try {
value = obj.refGetValue (attr);
} catch (Exception e) {
Logger.getDefault().annotate(e, ((ModelElement) obj.refMetaObject ()).getName () + " " + attr.getName ());
Logger.getDefault().notify(e);
value = Boolean.FALSE;
}
Object valueToWrite = value;
if (value == null) {
continue; // optional attribute of no value
}
if (isMultivalued) {
Collection col = (Collection) value;
if (col.isEmpty ())
continue;
if (col.size () > 1) {
// values have to be serialized in content
attrsInContent.add (attr);
continue;
} else
valueToWrite = col.iterator ().next ();
} // if
Classifier type = getType (attr);
if (!(type instanceof PrimitiveType) && !(type instanceof EnumerationType)) {
// values have to be serialized in content
attrsInContent.add (attr);
} else
writeValueInAttr (attr, valueToWrite);
} // while
Iterator iter = attrsInContent.iterator ();
while (iter.hasNext ()) {
Attribute attr = (Attribute) iter.next ();
writeValueInContent (attr, obj.refGetValue (attr));
} // while
Iterator refs = references ((MofClass) proxy.refMetaObject ()).iterator ();
while (refs.hasNext ()) {
Reference ref = (Reference) refs.next ();
writeReference (obj, ref);
}
endElement (name);
}
/**
* Writes reference to an instance (e.g. ).
*
* @param obj an instance the reference points to
* @param externalOnly if true, the reference is written only if it points to an external document
* @param hrefForced if true, href reference is always used
*/
protected void writeInstanceRef (RefObject obj, boolean externalOnly, boolean hrefForced) {
String name = qualifiedName ((ModelElement) obj.refMetaObject ());
XMIReferenceProvider.XMIReference xmiRef = provider.getReference (obj);
String xmiId = xmiRef.getXmiId ();
String systemId = xmiRef.getSystemId ();
if (externalOnly && systemId == null)
return;
if ((systemId != null) && (thisSystemId != null) && (thisSystemId.equals (systemId)) && !hrefForced) {
systemId = null;
} else if ((systemId == null) && hrefForced) {
systemId = thisSystemId;
}
startElement (name);
if (systemId == null) {
addAttribute (XMI_NAMESPACE + "idref", xmiId);
} else {
addAttribute (XMI_NAMESPACE + "href", systemId + HREF_DELIMITER + xmiId);
}
endElement (name);
}
/**
* Serializes structure.
*/
protected void writeStructure (StructureType type, RefStruct value) {
String name = qualifiedName (type);
startElement (name);
Iterator content = structureFields (type).iterator ();
List fields = new LinkedList ();
while (content.hasNext ()) {
StructureField field = (StructureField) content.next ();
if (!isSerializeTag (field)) {
continue;
} else if (isElementTag (field)) {
fields.add (field); // serialize value of the field as a sub-element
continue;
}
Classifier fieldType = getType ((StructureField) field);
if ((fieldType instanceof PrimitiveType) ||
(fieldType instanceof EnumerationType)) {
writeValueInAttr (
(StructureField) field,
value.refGetValue (((ModelElement) field).getName ())
);
} else
fields.add (field);
} // while
Iterator iter = fields.iterator ();
while (iter.hasNext ()) {
StructureField field = (StructureField) iter.next ();
Object fieldValue = value.refGetValue (((ModelElement) field).getName ());
writeValueInContent (field, fieldValue);
} // while
endElement (name);
}
/**
* Serializes Reference.
*/
protected void writeReference(RefObject obj, Reference ref) {
AggregationKind kind = ref.getReferencedEnd ().getAggregation ();
if (AggregationKindEnum.COMPOSITE.equals (kind))
return; // do not serialize reference to immediate composite object
kind = ref.getExposedEnd ().getAggregation ();
boolean isComposite = AggregationKindEnum.COMPOSITE.equals (kind);
Object temp = obj.refGetValue (ref);
if (temp == null)
return;
Collection values;
if (isMultivalued (ref))
values = (Collection) temp;
else {
values = new LinkedList ();
values.add (temp);
}
Iterator iter;
if (collectionWriting) {
// exclude all referenced instances that are not in the transitive closure generated by input collection
Collection cValues = new LinkedList ();
iter = values.iterator ();
while (iter.hasNext ()) {
RefObject referencedObject = (RefObject) iter.next ();
if (isInClosure (referencedObject)) {
cValues.add (referencedObject);
} // if
} // while
values = cValues;
} // if
if (values.isEmpty ())
return;
String name = qualifiedName (ref);
startElement (name);
iter = values.iterator ();
while (iter.hasNext ()) {
RefObject endValue = (RefObject) iter.next ();
if (isComposite)
writeInstance (endValue, false);
else {
writeInstanceRef (endValue, isRemoteOnlyTag (ref), isHrefTag (ref));
}
} // while
endElement (name);
}
public String labelPrefix (EnumerationType type) {
return "";
}
/**
* Returns fully qualified name of an model element.
*/
protected 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 ());
int index = name.lastIndexOf ('.');
String pName = name.substring (0, index);
String sName = name.substring (index + 1, name.length ());
if (!(element instanceof MofClass)) {
index = pName.lastIndexOf ('.');
if (index != -1) {
pName = pName.substring (0, index);
sName = name.substring (index + 1, name.length ());
}
}
String xmiName = getXmiNameTag (element);
if (xmiName != null)
sName = xmiName;
String namespace = (String) namespaces.get (pName);
if (namespace != null)
return namespace + ":" + sName;
return pName + '.' + sName;
}
protected String elementName (ModelElement elem) {
String name = getXmiNameTag (elem);
return name != null ? name : elem.getName ();
}
// tag values getters .......................................................
public String getContentScopedTagValue (ModelElement elem, String tagId) {
String value = null;
while ((value == null) && (elem != null)) {
value = getTagValue (elem, tagId);
elem = elem.getContainer ();
}
if (value != null)
value = value.trim ();
return value;
}
public boolean isElementTag (ModelElement elem) {
String value = getContentScopedTagValue (elem, XmiConstants.TAG_ELEMENT);
return (value != null) && value.equals ("true");
}
public boolean isHrefTag (ModelElement elem) {
String value = getContentScopedTagValue (elem, XmiConstants.TAG_HREF);
return (value != null) && value.equals ("true");
}
public String getXmiNameTag (ModelElement elem) {
return getTagValue (elem, XmiConstants.TAG_XMI_NAME);
}
public boolean isSerializeTag (ModelElement elem) {
String value = getTagValue (elem, XmiConstants.TAG_SERIALIZE);
return (value == null) || value.equals ("true");
}
public boolean isRemoteOnlyTag (ModelElement elem) {
String value = getTagValue (elem, XmiConstants.TAG_REMOTE_ONLY);
return (value != null) && value.equals ("true");
}
public String getNsPrefixTag (ModelElement elem) {
return getContentScopedTagValue (elem, XmiConstants.TAG_NS_PREFIX);
}
public String getNsURITag (ModelElement elem) {
return getContentScopedTagValue (elem, XmiConstants.TAG_NS_URI);
}
}
|