org.modeldriven.fuml.assembly.adapter.OpaqueExpressionAdapter.java Source code

Java tutorial

Introduction

Here is the source code for org.modeldriven.fuml.assembly.adapter.OpaqueExpressionAdapter.java

Source

/*
 * Copyright 2008 Lockheed Martin Corporation, except as stated in the file 
 * entitled Licensing-Information. All modifications copyright 2009 Data Access Technologies, Inc. Licensed under the Academic Free License 
 * version 3.0 (http://www.opensource.org/licenses/afl-3.0.php), except as stated 
 * in the file entitled Licensing-Information. 
 *
 * Contributors:
 *   MDS - initial API and implementation
 *
 */
package org.modeldriven.fuml.assembly.adapter;

import javax.xml.namespace.QName;
import javax.xml.stream.events.Attribute;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.modeldriven.fuml.assembly.AssemblyAdapter;
import org.modeldriven.fuml.repository.Classifier;
import org.modeldriven.fuml.xmi.XmiNode;
import org.modeldriven.fuml.xmi.stream.StreamNode;

import UMLPrimitiveTypes.UnlimitedNatural;
import fUML.Syntax.Classes.Kernel.Element;
import fUML.Syntax.Classes.Kernel.LiteralBoolean;
import fUML.Syntax.Classes.Kernel.LiteralInteger;
import fUML.Syntax.Classes.Kernel.LiteralString;
import fUML.Syntax.Classes.Kernel.LiteralUnlimitedNatural;

/**
 * OpaqueExpression is not supported in fUML and this class adapts 
 * away an OpaqueExpression into an fUML Element depending on the expression content.
 * While the below logic is questionable, the class is intended
 * to support conversion of these often found. For instance
 * RSA and Eclipse and other tools generate them as the ObjectFlow guard attribute (below).
 * <p>
 * <edge xmi:type="uml:ObjectFlow" xmi:id="_F4BJME_lEduAoLr6GBiiFQ" name="guard_0" source="_8bSJAE_kEduAoLr6GBiiFQ" target="_BxxFgE_lEduAoLr6GBiiFQ">
 *    <guard xmi:type="uml:OpaqueExpression" xmi:id="_F4BJMU_lEduAoLr6GBiiFQ">
 *        <body>1</body>
 *    </guard>
 *    <weight xmi:type="uml:LiteralInteger" xmi:id="_F4BJMk_lEduAoLr6GBiiFQ" value="1"/>
 * </edge> 
 * </p>
 * The next reasonable type in fUML to accommodate the expression is a LiteralInteger and
 * the below logic in general swaps OpaqueExpression for some type
 * of ValueSpecification. 
 * 
 */
public class OpaqueExpressionAdapter implements AssemblyAdapter {

    private static Log log = LogFactory.getLog(OpaqueExpressionAdapter.class);

    public Element assembleElement(StreamNode opaqueExpressionNode) {
        LiteralString literal = new LiteralString();

        XmiNode bodyNode = opaqueExpressionNode.findChildByName("body");

        String bodyContent = null;

        if (bodyNode != null) {
            bodyContent = bodyNode.getData();
        } else {
            Attribute bodyAttrib = opaqueExpressionNode.getAttribute("body");
            if (bodyAttrib != null)
                bodyContent = bodyAttrib.getValue();
        }
        if (bodyContent != null) {
            bodyContent = bodyContent.trim();
            if (bodyContent.startsWith("\"") && bodyContent.endsWith("\"")) {
                bodyContent = bodyContent.substring(1, bodyContent.length() - 1);
                literal.setValue(bodyContent);
                return literal; // must be a string, no need to continue. 
            }
        }
        literal.setValue(bodyContent);

        if ("true".equalsIgnoreCase(bodyContent) || "false".equalsIgnoreCase(bodyContent)) {
            LiteralBoolean literalBoolean = new LiteralBoolean();
            literalBoolean.setValue(Boolean.valueOf(bodyContent).booleanValue());
            return literalBoolean;
        } else if ("*".equals(bodyContent)) {
            LiteralUnlimitedNatural literalUnlimitedNatural = new LiteralUnlimitedNatural();
            UnlimitedNatural value = new UnlimitedNatural();
            value.naturalValue = -1;
            literalUnlimitedNatural.setValue(value);
            return literalUnlimitedNatural;
        } else {
            String type = findResultPinType(opaqueExpressionNode);
            if ("UnlimitedNatural".equals(type)) {
                int intValue = 0;
                try {
                    intValue = Integer.valueOf(bodyContent).intValue();
                } catch (NumberFormatException e) {
                    log.warn("could not parse content as unlimited-natural integer '" + bodyContent + "'");
                }
                LiteralUnlimitedNatural literalUnlimitedNatural = new LiteralUnlimitedNatural();
                UnlimitedNatural value = new UnlimitedNatural();
                value.naturalValue = intValue;
                literalUnlimitedNatural.setValue(value);
                return literalUnlimitedNatural;
            }
            try {
                if (log.isDebugEnabled())
                    log.debug("parsing expression: '" + bodyContent + "'");
                LiteralInteger literalInt = new LiteralInteger();
                literalInt.setValue(Integer.valueOf(bodyContent).intValue());
                return literalInt;
            } catch (NumberFormatException e) {
                if (log.isDebugEnabled())
                    log.debug("invalid number format: " + e.getMessage());
                literal.setValue(bodyContent);
            }
        }

        return literal;
    }

    private String findResultPinType(StreamNode opaqueExpressionNode) {
        String result = null;
        StreamNode parent = (StreamNode) opaqueExpressionNode.getParent();
        if (parent == null) {
            log.warn("expected parent node");
            return null;
        }

        StreamNode resultNode = (StreamNode) parent.findChildByName("result");
        if (resultNode != null) {
            StreamNode typeNode = (StreamNode) resultNode.findChildByName("type");
            if (typeNode != null) {
                QName name = new QName("href");
                String href = typeNode.getAttributeValue(name);
                if (href != null) {
                    // FIXME; gotta be a better way! URI resolver?? SOMETHING!
                    if (href.endsWith("Integer"))
                        result = "Integer";
                    else if (href.endsWith("String"))
                        result = "String";
                    else if (href.endsWith("Boolean"))
                        result = "Boolean";
                    else if (href.endsWith("UnlimitedNatural"))
                        result = "UnlimitedNatural";
                }
            }
        }
        return result;
    }

    public Classifier getClassifier(StreamNode node) {
        throw new IllegalStateException("OpaqueExpression should have no classifier");
    }
}