alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

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);
    }
    
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 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.