All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openmdx.application.mof.mapping.xmi.Uml1ModelMapper Maven / Gradle / Ivy

There is a newer version: 2.18.10
Show newest version
/*
 * ====================================================================
 * Project:     openmdx, http://www.openmdx.org/
 * Description: write XML schema (XSD)
 * Owner:       OMEX AG, Switzerland, http://www.omex.ch
 * ====================================================================
 *
 * This software is published under the BSD license
 * as listed below.
 * 
 * Copyright (c) 2004-2005, OMEX AG, Switzerland
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 * 
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 * 
 * * Neither the name of the openMDX team nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * ------------------
 * 
 * This product includes software developed by the Apache Software
 * Foundation (http://www.apache.org/).
 */

package org.openmdx.application.mof.mapping.xmi;

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.omg.mof.cci.VisibilityKind;
import org.openmdx.base.exception.ServiceException;
import org.openmdx.base.mof.cci.AggregationKind;
import org.openmdx.base.mof.cci.ModelElement_1_0;
import org.openmdx.base.mof.cci.Multiplicity;
import org.openmdx.base.mof.cci.Stereotypes;
import org.openmdx.base.text.conversion.XMLEncoder;

/**
 * This class writes MOF model elements to a given PrintStream using the OMG's
 * XML Metadata Interchange (XMI) format. The XMI format is based on the UML
 * mapping and follows the UML Profile for MOF as closely as possible for the
 * openMDX project. 
 */
@SuppressWarnings({"rawtypes","unchecked"})
public class Uml1ModelMapper {
  
  //---------------------------------------------------------------------------
  /**
   * Creates a new instance of a XMIUmlModelInterchangeWriter.
   * @param printWriter output is written to this printWriter
   * @param writePoseidonXMI defines whether the XMI/UML output is Poseidon 
   * specific (qualifiers in association end name, exceptions an operation can
   * throw as tagged value)
   */
  public Uml1ModelMapper(
    PrintWriter printWriter,
    byte xmiDialect
  ) {
    this.pw = new PrintWriter(printWriter);
    this.xmiDialect = xmiDialect; 
    this.stereotypeIds = new HashMap();
    this.datatypeIds = new HashMap();
    this.classIds = new HashMap();
    this.generalizationIds = new HashMap();
    this.tagDefinitionIds = new HashMap();
  }

  //---------------------------------------------------------------------------
  public void writeExceptionHeader(
    ModelElement_1_0 exceptionDef
  ) throws ServiceException {
    String name = exceptionDef.getName();
    
    pw.write(indent, 0, nTabs); pw.write("\n");

    // annotation
    String annotation = (String)exceptionDef.objGetValue("annotation");
    if(annotation != null) {
      this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }   
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    nTabs = nTabs + 2;
  }
  
  //---------------------------------------------------------------------------
  public void writeExceptionFooter(
    ModelElement_1_0 exceptionDef
  ) {
    nTabs = nTabs - 2;
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writeOperationHeader(
    ModelElement_1_0 operationDef,
    List exceptions
  ) throws ServiceException {
    String name = operationDef.getName();
    boolean isQuery = ((Boolean)operationDef.objGetValue("isQuery")).booleanValue();
    String visibility = this.toXMIVisibility((String)operationDef.objGetValue("visibility"));

    pw.write(indent, 0, nTabs); pw.write("\n");

    // annotation
    String annotation = (String)operationDef.objGetValue("annotation");
    if (annotation != null) {
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    
    // Due to the limited support of Poseidon to enter the exceptions an 
    // operation can throw, a tagged value "exceptions" is used to enter
    // them.
    if (!exceptions.isEmpty())
    {
      StringBuffer sb = new StringBuffer();
      int nExceptions = exceptions.size();
      for(
        int index = 0;
        index < nExceptions;
        index++
      ) {
        sb.append(this.toMOFSyntax(((ModelElement_1_0)exceptions.get(index)).getQualifiedName()));
        if (index < nExceptions-1)
        {
          sb.append("; ");
        }
      }
      
      this.writeTaggedValue(
        "exceptions",
        sb.toString()
      );
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    nTabs = nTabs + 2;
  }

  //---------------------------------------------------------------------------
  public void writeOperationFooter(
    ModelElement_1_0 operationDef
  ) {
    nTabs = nTabs - 2;
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writeParameter(
    ModelElement_1_0 parameterDef,
    ModelElement_1_0 parameterTypeDef,
    boolean parameterTypeIsPrimitive
  ) throws ServiceException {
    String name = parameterDef.getName();
    String typeQualifiedName = parameterTypeDef.getQualifiedName();
    String direction = this.toXMIParameterKind((String)parameterDef.objGetValue("direction"));
    String multiplicity = parameterDef.getMultiplicity();

    pw.write(indent, 0, nTabs); pw.write("\n");

    // annotation
    String annotation = (String)parameterDef.objGetValue("annotation");
    if (annotation != null){
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }    
    if (!Multiplicity.SINGLE_VALUE.code().equals(multiplicity))
    {
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    if (parameterTypeIsPrimitive)
    {
      // type is DataType
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    else
    {
      // type is Class
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writeAssociationHeader(
    ModelElement_1_0 associationDef
  ) throws ServiceException {
    String name = associationDef.getName();
    boolean isAbstract = associationDef.isAbstract().booleanValue();
    boolean isDerived = associationDef.isDerived().booleanValue();
    
    pw.write(indent, 0, nTabs); pw.write("\n");

    // annotation
    String annotation = (String)associationDef.objGetValue("annotation");
    if (annotation != null){
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    
    if (isDerived)
    {
      this.writeTaggedValue("derived", "true");
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    nTabs = nTabs + 2;
  }
  
  //---------------------------------------------------------------------------
  public void writeAssociationFooter(
    ModelElement_1_0 associationDef
  ) {
    nTabs = nTabs - 2;
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writeAssociationEnds(
    ModelElement_1_0 associationEnd1Def,
    ModelElement_1_0 associationEnd1TypeDef,
    List associationEnd1QualifierTypes,
    ModelElement_1_0 associationEnd2Def,
    ModelElement_1_0 associationEnd2TypeDef,
    List associationEnd2QualifierTypes
  ) throws ServiceException {
    boolean assEnd1IsNavigable = ((Boolean)associationEnd1Def.objGetValue("isNavigable")).booleanValue();
    boolean assEnd1IsChangeable = associationEnd1Def.isChangeable().booleanValue();
    String assEnd1TypeQualifiedName = associationEnd1TypeDef.getQualifiedName();
    String assEnd1Aggregation = associationEnd1Def.getAggregation();

    boolean assEnd2IsNavigable = ((Boolean)associationEnd2Def.objGetValue("isNavigable")).booleanValue();
    boolean assEnd2IsChangeable = associationEnd2Def.isChangeable().booleanValue();
    String assEnd2TypeQualifiedName = associationEnd2TypeDef.getQualifiedName();
    String assEnd2Aggregation = associationEnd2Def.getAggregation();
    
    // Note:
    // Aggregation and qualifier assignments must be changed to comply.
    
    String assEnd1Name;
    if (POSEIDON_XMI_DIALECT == this.xmiDialect)
    {
      // use Poseidon specific association end name (not XMI/UML compliant)
      // which includes qualfiers beside the association end name
      assEnd1Name = this.toPoseidonAssociationEndName(
        associationEnd1Def.getName(),
        associationEnd2Def.objGetList("qualifierName"),
        associationEnd2QualifierTypes
      );
    }
    else
    {
      // use XMI/UML compliant association end name
      assEnd1Name = associationEnd1Def.getName();
    }
    pw.write(indent, 0, nTabs); pw.write("\n");

    {
        // annotation
        String annotation = (String)associationEnd1Def.objGetValue("annotation");
        if (annotation != null) {
        this.writeTaggedValue(
            "documentation",
            this.toHTMLString(
              annotation
            )
          );
        }
    }
    
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    nTabs = nTabs + 2;
    this.writeAssociationEndMultiplicity(associationEnd1Def.getMultiplicity());
    nTabs = nTabs - 2;
    pw.write(indent, 0, nTabs); pw.write("\t\n");

    int nAssEnd1Qualifiers = associationEnd1Def.objGetList("qualifierName").size();
    if (MAGICDRAW_XMI_DIALECT == this.xmiDialect && nAssEnd1Qualifiers > 0)
    {
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      for(
        int index = 0;
        index < nAssEnd1Qualifiers;
        index++
      ) {
        String qualifierName = (String)associationEnd1Def.objGetList("qualifierName").get(index);
        String qualifierTypeName = ((ModelElement_1_0)associationEnd1QualifierTypes.get(index)).getQualifiedName();
        pw.write(indent, 0, nTabs); pw.write("\t\t\n");
        pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
        if (((ModelElement_1_0)associationEnd1QualifierTypes.get(index)).isPrimitiveType())
        {
          // type is DataType
          pw.write(indent, 0, nTabs); pw.write("\t\t\t\t\n");
        }
        else
        {
          // type is Class
          pw.write(indent, 0, nTabs); pw.write("\t\t\t\t\n");
        }
        pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
        pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      }
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }

    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");

    String assEnd2Name;
    if (POSEIDON_XMI_DIALECT == this.xmiDialect)
    {
      // use Poseidon specific association end name (not XMI/UML compliant)
      // which includes qualfiers beside the association end name
      assEnd2Name = this.toPoseidonAssociationEndName(
        associationEnd2Def.getName(),
        associationEnd1Def.objGetList("qualifierName"),
        associationEnd1QualifierTypes
      );
    }
    else
    {
      // use XMI/UML compliant association end name
      assEnd2Name = associationEnd2Def.getName();
    }
    pw.write(indent, 0, nTabs); pw.write("\n");

    {
        // annotation
        String annotation = (String)associationEnd2Def.objGetValue("annotation");
        if (annotation != null) {
        this.writeTaggedValue(
            "documentation",
            this.toHTMLString(
              annotation
            )
          );
        }
    }
    
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    nTabs = nTabs + 2;
    this.writeAssociationEndMultiplicity(associationEnd2Def.getMultiplicity());
    nTabs = nTabs - 2;
    pw.write(indent, 0, nTabs); pw.write("\t\n");

    int nAssEnd2Qualifiers = associationEnd2Def.objGetList("qualifierName").size();
    if (MAGICDRAW_XMI_DIALECT == this.xmiDialect && nAssEnd2Qualifiers > 0)
    {
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      for(
        int index = 0;
        index < nAssEnd2Qualifiers;
        index++
      ) {
        String qualifierName = (String)associationEnd2Def.objGetList("qualifierName").get(index);
        String qualifierTypeName = ((ModelElement_1_0)associationEnd2QualifierTypes.get(index)).getQualifiedName();
        pw.write(indent, 0, nTabs); pw.write("\t\t\n");
        pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
        if (((ModelElement_1_0)associationEnd2QualifierTypes.get(index)).isPrimitiveType())
        {
          // type is DataType
          pw.write(indent, 0, nTabs); pw.write("\t\t\t\t\n");
        }
        else
        {
          // type is Class
          pw.write(indent, 0, nTabs); pw.write("\t\t\t\t\n");
        }
        pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
        pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      }
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }

    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writePrimitiveType(
    ModelElement_1_0 primitiveTypeDef
  ) throws ServiceException {
    String name = primitiveTypeDef.getName();
    String visibility = this.toXMIVisibility((String)primitiveTypeDef.objGetValue("visibility"));
    boolean isAbstract = primitiveTypeDef.isAbstract().booleanValue();
    String typeId = this.getDataTypeId(primitiveTypeDef.getQualifiedName());

    pw.write(indent, 0, nTabs); pw.write("\n");

    // annotation
    String annotation = (String)primitiveTypeDef.objGetValue("annotation");
    if (annotation != null){
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    String primitiveStereotypeId = this.getStereotypeId(Stereotypes.PRIMITIVE, "DataType");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }

  //---------------------------------------------------------------------------
  public void writeAttribute(
    ModelElement_1_0 attributeDef,
    boolean isDerived,
    boolean isChangeable,
    ModelElement_1_0 typeDef,
    boolean referencedTypeIsPrimitive
  ) throws ServiceException {
    String name = attributeDef.getName();
    String typeQualifiedName = typeDef.getQualifiedName();
    String visibility = this.toXMIVisibility((String)attributeDef.objGetValue("visibility"));
    String changeability = this.toXMIChangeability(isChangeable);
    String multiplicity = attributeDef.getMultiplicity();
    int maxLength = ((Number)attributeDef.objGetValue("maxLength")).intValue();
    
    pw.write(indent, 0, nTabs); pw.write("\n");
    
    // annotation
    String annotation = (String)attributeDef.objGetValue("annotation");
    if (annotation != null){
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    
    this.writeTaggedValue(
      "maxLength",
      String.valueOf(maxLength)
    );

    if (isDerived)
    {    
      this.writeTaggedValue("derived", "true");
    }
    if (!Multiplicity.SINGLE_VALUE.code().equals(multiplicity))
    {
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    if (referencedTypeIsPrimitive)
    {
      // type is DataType
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    else
    {
      // type is Class
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writeAliasType(
    ModelElement_1_0 aliasTypeDef,
    ModelElement_1_0 typeDef,
    boolean referencedTypeIsPrimitive
  ) throws ServiceException {
    String name = aliasTypeDef.getName();
    String qualifiedName = aliasTypeDef.getQualifiedName();
    String visibility = this.toXMIVisibility((String)aliasTypeDef.objGetValue("visibility"));
    boolean isAbstract = aliasTypeDef.isAbstract().booleanValue();
    String typeQualifiedName = typeDef.getQualifiedName();
    String classId = this.getClassId(qualifiedName);

    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    String aliasStereotypeId = this.getStereotypeId(Stereotypes.ALIAS, "Class");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");

    // annotation
    String annotation = (String)aliasTypeDef.objGetValue("annotation");
    if (annotation != null) {
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
    if (referencedTypeIsPrimitive)
    {
      // type is DataType
      pw.write(indent, 0, nTabs); pw.write("\t\t\t\t\n");
    }
    else
    {
      // type is Class
      pw.write(indent, 0, nTabs); pw.write("\t\t\t\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }

  //---------------------------------------------------------------------------
  public void writePackageHeader(
    ModelElement_1_0 packageDef
  ) throws ServiceException {
    pw.write(indent, 0, nTabs); pw.write("\n");   
    pw.write(indent, 0, nTabs); pw.write("\t\n");

    // annotation
    final String annotation = (String)packageDef.objGetValue("annotation");
    if (annotation != null) {
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    
    nTabs = nTabs + 2;
  }
  
  //---------------------------------------------------------------------------
  public void writePackageFooter(
    ModelElement_1_0 packageDef
  ) {
    nTabs = nTabs - 2;
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }

  //---------------------------------------------------------------------------
  public void writeGeneralization(
    ModelElement_1_0 classDef,
    List subtypeDefs
  ) throws ServiceException {
    String parentTypeId = this.getClassId(classDef.getQualifiedName());
    for(
      Iterator it = subtypeDefs.iterator();
      it.hasNext();
    ) {
      ModelElement_1_0 childDef = (ModelElement_1_0)it.next();
      String childTypeId = this.getClassId(childDef.getQualifiedName());
      String generalizationId = this.getGeneralizationId(
        classDef.getQualifiedName(),
        childDef.getQualifiedName()
      );
      pw.write(indent, 0, nTabs); pw.write("\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\n");
    }
  }
  
  //---------------------------------------------------------------------------
  public void writeStructureTypeHeader(
    ModelElement_1_0 structureTypeDef,
    boolean hasStructureFields
  ) throws ServiceException {
    String name = structureTypeDef.getName();
    String classId = this.getClassId(structureTypeDef.getQualifiedName());
    String visibility = this.toXMIVisibility((String)structureTypeDef.objGetValue("visibility"));
    boolean isAbstract = structureTypeDef.isAbstract().booleanValue();
    
    pw.write(indent, 0, nTabs); pw.write("\n");

    // annotation
    String annotation = (String)structureTypeDef.objGetValue("annotation");
    if (annotation != null) {
      this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    String structStereotypeId = this.getStereotypeId(Stereotypes.STRUCT, "Class");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs);
    
    // write an opening 'UML:Classifier.feature' tag only if the structure type
    // has structure fields, otherwise the Poseidon XMI import will crash
    // CR0002222
    if (hasStructureFields)
    {
      pw.write("\t\n");
    }
    else
    {
      pw.write("\t\n");
    }
    nTabs = nTabs + 2;
  }
  
  //---------------------------------------------------------------------------
  public void writeStructureTypeFooter(
    ModelElement_1_0 structureTypeDef,
    boolean hasStructureFields
  ) {
    nTabs = nTabs - 2;
    if (hasStructureFields)
    {
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writeStructureField(
    ModelElement_1_0 attributeDef,
    ModelElement_1_0 typeDef,
    boolean referencedTypeIsPrimitive
  ) throws ServiceException {
    this.writeAttribute(attributeDef, false, false, typeDef, referencedTypeIsPrimitive);
  }
  
  //---------------------------------------------------------------------------
  public void writeClassHeader(
    ModelElement_1_0 classDef,
    List supertypeDefs,
    boolean hasStructuralFeatures
  ) throws ServiceException {
    String name = classDef.getName();
    String classId = this.getClassId(classDef.getQualifiedName());
    String visibility = this.toXMIVisibility((String)classDef.objGetValue("visibility"));
    boolean isAbstract = classDef.isAbstract().booleanValue();

    pw.write(indent, 0, nTabs); pw.write("\n");

    // annotation
    String annotation = (String)classDef.objGetValue("annotation");
    if (annotation != null){
    this.writeTaggedValue(
        "documentation",
        this.toHTMLString(
          annotation
        )
      );
    }
    
    for(
      Iterator it = classDef.objGetList("stereotype").iterator();
      it.hasNext();
    )
    {
      String stereotypeId = this.getStereotypeId((String)it.next(), "Class");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }

    for(
      Iterator it = supertypeDefs.iterator();
      it.hasNext();
    ) {
      ModelElement_1_0 parentDef = (ModelElement_1_0)it.next();
      String generalizationId = this.getGeneralizationId(
        parentDef.getQualifiedName(),
        classDef.getQualifiedName()
      );
      pw.write(indent, 0, nTabs); pw.write("\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }
    pw.write(indent, 0, nTabs);
    
    // write an opening 'UML:Classifier.feature' tag only if the class has 
    // structural features, otherwise the Poseidon XMI import will crash
    // CR0002222
    if (hasStructuralFeatures)
    {
      pw.write("\t\n");
    }
    else
    {
      pw.write("\t\n");
    }
    nTabs = nTabs + 2;
  }
  
  //---------------------------------------------------------------------------
  public void writeClassFooter(
    ModelElement_1_0 classDef,
    boolean hasStructuralFeatures
  ) {
    nTabs = nTabs - 2;
    if (hasStructuralFeatures)
    {
      pw.write(indent, 0, nTabs); pw.write("\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.flush();      
  }
  
  //---------------------------------------------------------------------------
  public void writeHeader(
  ) {
    pw.write("\n");
    pw.write("\n");
    pw.write("\n");
    pw.write("\n");
    pw.write("\t\n");
    pw.write("\t\t\n");
    pw.write("\t\t\topenMDX XMI UML Model Interchange Writer\n");
    pw.write("\t\t\t1.0\n");
    pw.write("\t\t\n");
    pw.write("\t\n");
    pw.write("\t\n");
    pw.write("\t\t\n");
    pw.write("\t\t\t\n");
    this.writeStereotype(Multiplicity.OPTIONAL.code(), "Attribute");
    this.writeStereotype(Multiplicity.SINGLE_VALUE.code(), "Attribute");
    this.writeStereotype(Multiplicity.UNBOUNDED, "Attribute");
    this.writeStereotype(Multiplicity.LIST.code(), "Attribute");
    this.writeStereotype(Multiplicity.SET.code(), "Attribute");
    this.writeStereotype(Multiplicity.SPARSEARRAY.code(), "Attribute");
    this.writeStereotype(Multiplicity.STREAM.code(), "Attribute");
    this.writeStereotype(Multiplicity.MAP.code(), "Attribute");
    this.writeStereotype(Multiplicity.OPTIONAL.code(), "Parameter");
    this.writeStereotype(Multiplicity.SINGLE_VALUE.code(), "Parameter");
    this.writeStereotype(Multiplicity.UNBOUNDED, "Parameter");
    this.writeStereotype(Multiplicity.LIST.code(), "Parameter");
    this.writeStereotype(Multiplicity.SET.code(), "Parameter");
    this.writeStereotype(Multiplicity.SPARSEARRAY.code(), "Parameter");
    this.writeStereotype(Multiplicity.STREAM.code(), "Parameter");
    this.writeStereotype(Multiplicity.MAP.code(), "Parameter");
    this.writeStereotype(Stereotypes.PRIMITIVE, "DataType");
    this.writeStereotype(Stereotypes.STRUCT, "Class");
    this.writeStereotype(Stereotypes.ALIAS, "Class");
    this.writeStereotype(Stereotypes.ROOT, "Class");
    this.writeStereotype(Stereotypes.ROLE, "Class");
    this.writeStereotype(Stereotypes.EXCEPTION, "Operation");
    this.writeTagDefinition("derived");
    this.writeTagDefinition("maxLength");
    this.writeTagDefinition("exceptions");
    this.writeTagDefinition("documentation");
  }
  
  //---------------------------------------------------------------------------
  public void writeFooter(
  ) {
    pw.write("\t\t\t\n");
    pw.write("\t\t\n");
    pw.write("\t\n");
    pw.write("\n");
    pw.flush();
  }

  //---------------------------------------------------------------------------
  private void writeStereotype(
    String stereotype,
    String baseClass
  ) {
    String id = this.getStereotypeId(stereotype, baseClass);
    pw.write("\t\t\t\t\n");
    pw.write("\t\t\t\t\t"); pw.write(baseClass); pw.write("\n");
    pw.write("\t\t\t\t\n");
  }

  //---------------------------------------------------------------------------
  private void writeTagDefinition(
    String tag
  ) {
    pw.write("\t\t\t\t\n");
    pw.write("\t\t\t\t\t\n");
    pw.write("\t\t\t\t\t\t\n");
    pw.write("\t\t\t\t\t\t\t\n");
    pw.write("\t\t\t\t\t\t\t\t\n");
    pw.write("\t\t\t\t\t\t\t\n");
    pw.write("\t\t\t\t\t\t\n");
    pw.write("\t\t\t\t\t\n");
    pw.write("\t\t\t\t\n");
  }

  //---------------------------------------------------------------------------
  private void writeTaggedValue(
    String tag,
    String dataValue
  ) {
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\t"); pw.write(dataValue); pw.write("\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
  }
  
  //---------------------------------------------------------------------------
  private String toPoseidonAssociationEndName(
    String associationEndName,
    List qualifierNames,
    List qualifierTypes
  ) throws ServiceException {
    StringBuffer sb = new StringBuffer(associationEndName);
    if (!qualifierNames.isEmpty())
    {
      int nQualifiers = qualifierNames.size();
      sb.append(POSEIDON_LF);
      sb.append("[");
      for(
        int index = 0;
        index < nQualifiers;
        index++
      ) {
        String qualifierTypeName = ((ModelElement_1_0)qualifierTypes.get(index)).getQualifiedName();
        sb.append(qualifierNames.get(index));
        sb.append(":");
        sb.append(this.toMOFSyntax(qualifierTypeName));
        if (index < nQualifiers-1)
        {
          sb.append("; ");
        }
      }
      sb.append("]");
    }
    return sb.toString();  
  }
  
  //---------------------------------------------------------------------------
  private String toMOFSyntax(
    String qualifiedName
  ) {
    if(qualifiedName.length() == 0) {
      return new String();
    } else {
      StringBuffer sb = new StringBuffer();
      for(int i = 0; i < qualifiedName.length(); i++)
      {
        char ch = qualifiedName.charAt(i);
        if(':' == ch) { sb.append("::"); }
        else { sb.append(ch); }
      }
      return sb.toString();
    }
  }

  //---------------------------------------------------------------------------
  private void writeAssociationEndMultiplicity(
    String multiplicity
  ) {
    pw.write(indent, 0, nTabs); pw.write("\n");
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    if ("0..1".equals(multiplicity))
    {
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    else if ("1..1".equals(multiplicity))
    {
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    else if ("1..n".equals(multiplicity))
    {
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    else
    {
      // 0..n
      pw.write(indent, 0, nTabs); pw.write("\t\t\n");
    }
    pw.write(indent, 0, nTabs); pw.write("\t\n");
    pw.write(indent, 0, nTabs); pw.write("\n");
  }
  
  //---------------------------------------------------------------------------
  private String toHTMLString(
    String input
  ) {
      return XMLEncoder.encode(input);
  }

  //---------------------------------------------------------------------------
  private String toXMIVisibility(
    String mofVisibility
  ) {
    if (VisibilityKind.PRIVATE_VIS.equals(mofVisibility))
    {
      return "private";
    }
    else
    {
      return "public";
    }
  }

  //---------------------------------------------------------------------------
  private String toXMIAggregation(
    String mofAggregation
  ) {
    if (AggregationKind.COMPOSITE.equals(mofAggregation))
    {
      return "composite";
    }
    else if (AggregationKind.SHARED.equals(mofAggregation))
    {
      return "aggregate";
    }
    else
    {
      return "none";
    }
  }

  //---------------------------------------------------------------------------
  private String toXMIChangeability(
    boolean isChangeable
  ) {
    return (isChangeable ? "changeable" : "frozen"); 
  }
  
  //---------------------------------------------------------------------------
  private String toXMIParameterKind(
    String direction
  ) {
    if ("return_dir".equals(direction))
    {
      return "return";
    }
    else if ("out_dir".equals(direction))
    {
      return "out";
    }
    else if ("inout_dir".equals(direction))
    {
      return "inout";
    }
    else
    {
      return "in";
    }
  }
  
  //---------------------------------------------------------------------------
  private String createId(
  ) {
    return "_" + String.valueOf(id++);
  }

  //---------------------------------------------------------------------------
  private String getStereotypeId(
    String stereotype,
    String baseClass
  ) {
    String key = stereotype+baseClass;
    if (!this.stereotypeIds.containsKey(key))
    {
      this.stereotypeIds.put(
        key,
        this.createId()
      );
    }
    return (String)this.stereotypeIds.get(key);
  }

  //---------------------------------------------------------------------------
  private String getDataTypeId(
    String qualifiedName
  ) {
    if (!this.datatypeIds.containsKey(qualifiedName))
    {
      this.datatypeIds.put(
        qualifiedName,
        this.createId()
      );
    }
    return (String)this.datatypeIds.get(qualifiedName);
  }

  //---------------------------------------------------------------------------
  private String getClassId(
    String qualifiedName
  ) {
    if (!this.classIds.containsKey(qualifiedName))
    {
      this.classIds.put(
        qualifiedName,
        this.createId()
      );
    }
    return (String)this.classIds.get(qualifiedName);
  }

  //---------------------------------------------------------------------------
  private String getTagDefinitionId(
    String tag
  ) {
    if (!this.tagDefinitionIds.containsKey(tag))
    {
      this.tagDefinitionIds.put(
        tag,
        this.createId()
      );
    }
    return (String)this.tagDefinitionIds.get(tag);
  }

  //---------------------------------------------------------------------------
  private String getGeneralizationId(
    String parentQualifiedName,
    String childQualifiedName
  ) {
    String key = parentQualifiedName + "-" + childQualifiedName;
    if (!this.generalizationIds.containsKey(key))
    {
      this.generalizationIds.put(
        key,
        this.createId()
      );
    }
    return (String)this.generalizationIds.get(key);
  }

  //---------------------------------------------------------------------------  
  // Variables
  //---------------------------------------------------------------------------  
  private final PrintWriter pw;
  private final byte xmiDialect;
  private Map stereotypeIds = null;
  private Map datatypeIds = null;
  private Map classIds = null;
  private Map generalizationIds = null;
  private Map tagDefinitionIds = null;
  private int id = 0;
  private static int nTabs = 4;
  private static final String POSEIDON_LF = "
";
  private static char[] indent = {'\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t','\t'};

  public static final byte POSEIDON_XMI_DIALECT = 1;
  public static final byte MAGICDRAW_XMI_DIALECT = 2;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy