/** * * C O P Y R I G H T N O T I C E * Copyright (c) 2001 by: * * The MicroArray Gene Expression Database group (MGED) * * Rosetta Inpharmatics * * (expand as necessary) * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * * @author $Author: rhubley $ * @version $Revision: 1.2 $ * */ package org.biomage.tools.generate_classes ; /*--------------------------------------------------------------------------*/ /* Imported classes. */ /*--------------------------------------------------------------------------*/ import org.w3c.dom.*; /*--------------------------------------------------------------------------*/ /* XMIParseHelpers class. */ /*--------------------------------------------------------------------------*/ public final class XMIParseHelpers { /** * Description: * Returns the classifier of the association end element. * *

* @param associationEndElement: the association end element tree. *

* *

* @return The classifier of the association end element. *

*/ public static Element getAssociationEndClassifier( Element associationEndElement ) throws Exception { Element classifierElement = getFirstElementByTagNameArray( associationEndElement, new String[] { "Foundation.Core.AssociationEnd.type", "Foundation.Core.Classifier" }); if (classifierElement == null) { throw new Exception("Classifier not specified."); } return classifierElement; } /** * Description: * Returns the classifier of the association end element. * *

* @param associationEndElement: the association end element tree. *

* *

* @return The classifier of the association end element. *

*/ public static Element getAttributeClassifier( Element attributeElement ) throws Exception { Element classifierElement = getFirstElementByTagNameArray( attributeElement, new String[] { "Foundation.Core.StructuralFeature.type", "Foundation.Core.Classifier" }); if (classifierElement == null) { throw new Exception("Classifier not specified."); } return classifierElement; } /** * Description: * Returns the classifier of the association end element. * *

* @param attributeElement: the attribute element tree. *

* *

* @return The initial value for the attribute or the empty string. *

*/ public static String getInitialValue( Element attributeElement ) throws Exception { Element intialValueElement = getFirstElementByTagNameArray( attributeElement, new String[] { "Foundation.Core.Attribute.initialValue", "Foundation.Data_Types.Expression", "Foundation.Data_Types.Expression.body" }); return getElementText(intialValueElement); } /** * Description: * Returns the string representing the constraint. * *

* @param constraintElement: the constraint element tree. *

* *

* @return the String representing the constraint. *

*/ public static String getConstraintString( Element constraintElement ) throws Exception { Element constraintBody = getFirstElementByTagNameArray( constraintElement, new String[] {"Foundation.Core.Constraint.body", "Foundation.Data_Types.BooleanExpression", "Foundation.Data_Types.Expression.body" } ); if (constraintBody == null) { throw new Exception("Constraint body for constraint not specified."); } return getElementText(constraintBody); } /** * Description: * Returns a NodeList of constrained elements. * *

* @param constraintElement: the constraint element tree. *

* *

* @return a NodeList of constrained elements. *

*/ public static NodeList getConstrainedElements( Element constraintElement ) throws Exception { Element constrainedContainer = getFirstElementByTagName( constraintElement, "Foundation.Core.Constraint.constrainedElement"); if (constrainedContainer == null) { throw new Exception("Constrained elements for constraint not specified."); } return constrainedContainer.getElementsByTagName("Foundation.Core.ModelElement"); } /** * Description: * Returns a NodeList of operation elements. * *

* @param classElement: the class element tree. *

* *

* @return a NodeList of operation elements. *

*/ public static NodeList getOperationElements( Element classElement ) throws Exception { return classElement.getElementsByTagName("Foundation.Core.Operation"); } /** * Description: * Returns a NodeList of parameter elements. * *

* @param oeprationElement: the operation element tree. *

* *

* @return a NodeList of parameter elements. *

*/ public static NodeList getParameterElements( Element operationElement ) throws Exception { return operationElement.getElementsByTagName("Foundation.Core.Parameter"); } /** * Description: * Returns the id of the parameter element's data type. * *

* @param paramElement: the parameter element tree. *

* *

* @return The parameterID as a string. Can be null. *

*/ public static String getParameterTypeID( Element parameterElement ) throws Exception { Element kindElement = getFirstElementByTagName(parameterElement, "Foundation.Core.Parameter.kind"); Element typeElement = getFirstElementByTagNameArray( parameterElement, new String[] { "Foundation.Core.Parameter.type", "Foundation.Core.Classifier" }); return getElementIDRef(typeElement); } /** * Description: * Returns the kind of the parameter ("return", "inout", etc.). * *

* @param paramElement: the parameter element tree. *

* *

* @return The kind of parameter. *

*/ public static String getParameterKind( Element parameterElement ) throws Exception { Element kind = getFirstElementByTagName(parameterElement, "Foundation.Core.Parameter.kind"); if (null == kind) { throw new Exception("XMIParseHelpers.getParameterKind(): kind element was null."); } return getElementValue(kind); } /** * Description: * Returns the specification(semantics) of an operation. * *

* @param operationElement: the operation element tree. *

* *

* @return The specification as a String. Can be null. *

*/ public static String getOperationSpecification( Element operationElement ) throws Exception { Element specification = getFirstElementByTagName(operationElement, "Foundation.Core.Operation.specification"); if (null == specification) { throw new Exception("XMIParserHelpers.getSpecification(): No specification element found."); } return getElementText(specification); } /** * Description: * Returns the multiplicity range lower of the association end element. * *

* @param associationEndElement: the association end element tree. *

* *

* @return The multiplicity range lower of the association end element * (-1 if no lower). *

*/ public static int getAssociationEndMultiplicityRangeLower( Element associationEndElement ) throws Exception { Element lowerElement = getFirstElementByTagNameArray( associationEndElement, new String[] { "Foundation.Core.AssociationEnd.multiplicity", "Foundation.Data_Types.Multiplicity", "Foundation.Data_Types.Multiplicity.range", "Foundation.Data_Types.MultiplicityRange", "Foundation.Data_Types.MultiplicityRange.lower" }); if (lowerElement == null) { throw new Exception("Multiplicity range lower not specified."); } return Integer.parseInt(getElementText(lowerElement)); } /** * Description: * Returns the multiplicity range upper of the association end element. * *

* @param associationEndElement: the association end element tree. *

* *

* @return The multiplicity range upper of the association end element * (-1 if no upper). *

*/ public static int getAssociationEndMultiplicityRangeUpper( Element associationEndElement ) throws Exception { Element upperElement = getFirstElementByTagNameArray( associationEndElement, new String[] { "Foundation.Core.AssociationEnd.multiplicity", "Foundation.Data_Types.Multiplicity", "Foundation.Data_Types.Multiplicity.range", "Foundation.Data_Types.MultiplicityRange", "Foundation.Data_Types.MultiplicityRange.upper" }); if (upperElement == null) { throw new Exception("Multiplicity range upper not specified."); } return Integer.parseInt(getElementText(upperElement)); } /** * Description: * Returns the multiplicity range lower of the association end element. * *

* @param associationEndElement: the association end element tree. *

* *

* @return The multiplicity range lower of the association end element * (-1 if no lower). *

*/ public static int getAttributeMultiplicityRangeLower( Element attributeElement ) throws Exception { Element lowerElement = getFirstElementByTagNameArray( attributeElement, new String[] { "Foundation.Core.StructuralFeature.multiplicity", "Foundation.Data_Types.Multiplicity", "Foundation.Data_Types.Multiplicity.range", "Foundation.Data_Types.MultiplicityRange", "Foundation.Data_Types.MultiplicityRange.lower" }); if (lowerElement == null) { throw new Exception("Multiplicity range lower not specified."); } return Integer.parseInt(getElementText(lowerElement)); } /** * Description: * Returns the ID of the element. * *

* @param element: the element tree. *

* *

* @return The ID of the element. *

*/ public static String getElementID( Element element ) throws Exception { return element.getAttribute("xmi.id"); } /** * Description: * Returns the IDRef of the element. * *

* @param element: the element tree. *

* *

* @return The IDRef of the element. *

*/ public static String getElementIDRef( Element element ) throws Exception { return element.getAttribute("xmi.idref"); } /** * Description: * Returns the value of the element. * *

* @param element: the element tree. *

* *

* @return The value of the element. *

*/ public static String getElementValue( Element element ) throws Exception { return element.getAttribute("xmi.value").trim(); } /** * Description: * Returns the name of the element. * *

* @param element: the element tree. *

* *

* @return The name of the element. *

*/ public static String getElementName( Element element ) throws Exception { Element nameElement = getFirstElementByTagName(element, "Foundation.Core.ModelElement.name"); if (nameElement == null) { throw new Exception("Name not specified."); } return getElementText(nameElement); } /** * Description: * Returns the text of the element. * *

* @param element: the element tree. *

* *

* @return The text of the element. *

*/ public static String getElementText( Element element ) throws Exception { if (null == element || !element.hasChildNodes()) { return ""; } return element.getFirstChild().getNodeValue().trim(); } /** * Description: * Returns the text of the element with name of token. * *

* @param doc: the document which may have an elemnt with a name * corresponding to token * @param token: name of element to get the text of. *

* *

* @return The text of the element. *

*/ public static String getTokenValue( Document doc, String token ) throws Exception { if (null == doc) { return ""; } NodeList tokenList = doc.getElementsByTagName(token); if (null == tokenList || 0 == tokenList.getLength()) { return ""; } return getElementText((Element) tokenList.item(0)); } /** * Description: * Returns the first descendant Element with a given tag name, in the * order in which they are encountered in a preorder traversal of * this Element tree. * *

* @param element: the element tree. * @param sName: name of the tag to match on. The special value "*" * matches all tags. *

* *

* @return The first matching Element, or null if there was no match. *

*/ public static Element getFirstElementByTagName( Element element, String sName ) { NodeList nodeList = element.getElementsByTagName(sName); if (nodeList == null || nodeList.getLength() == 0) { return null; } return (Element)nodeList.item(0); } /** * Description: * Thrown when a lookup fails and the top element has an IDREF attribute. * This is needed to distinguish a problem when an element is both * a high-level element with an ID and a nested elemetn with an IDREF, * such as the constraint node. * */ static public class IDREFException extends Exception { public IDREFException( String message ) { super(message); } public IDREFException() { super(); } } /** * Description: * Returns the first descendant Element with a given tag name, in the * order in which they are encountered in a preorder traversal of * this Element tree. * *

* @param element: the element tree. * @param asName: array of names of the tags to match on. The special * value "*" matches all tags. *

* *

* @return The first matching Element, or null if there was no match. *

* *

* @exception IDREFException is thrown if the lookup fails to find the tag * and the element parameter has an idref attribute. *

*/ public static Element getFirstElementByTagNameArray( Element element, String[] asName ) throws IDREFException, Exception { Element nextElement = element; for (int n = 0; n != asName.length; ++n) { nextElement = getFirstElementByTagName(nextElement, asName[n]); if (nextElement == null) { // See if we have a referenced a nested tag instead of a top-level tag if (null != getElementIDRef(element) || 0 == getElementIDRef(element).length()) { throw new IDREFException("XMIParseHelpers.getFirstElementByTagNameArray(): element has idref attribute"); } return null; } } return nextElement; } /** * Typedefs for type of aggregation */ /** Is Independent */ static final public int NOT_AGGR = 0; /** Is Co-owned by one or more objects */ static final public int AGGREGATE = 1; /** Is solely owned by a containing object */ static final public int COMPOSITE = 2; /** * Description: * Returns whether the association end is aggregate. * *

* @param associationEndElement: the association end element tree. *

* *

* @return True if the association end is aggregate; false otherwise. *

*/ public static int typeAssociationEndAggregate( Element associationEndElement ) throws Exception { Element aggregationElement = getFirstElementByTagName( associationEndElement, "Foundation.Core.AssociationEnd.aggregation"); if (aggregationElement == null) { throw new Exception("Aggregation not specified."); } int typeAggregation = COMPOSITE; if ("aggregate".equals(aggregationElement.getAttribute("xmi.value"))) { typeAggregation = AGGREGATE; } else if ("none".equals(aggregationElement.getAttribute("xmi.value"))) { typeAggregation = NOT_AGGR; } return typeAggregation; } /** * Description: * Returns whether the association end is navigable. * *

* @param associationEndElement: the association end element tree. *

* *

* @return True if the association end is navigable; false otherwise. *

*/ public static boolean isAssociationEndNavigable( Element associationEndElement ) throws Exception { Element isNavigableElement = getFirstElementByTagName( associationEndElement, "Foundation.Core.AssociationEnd.isNavigable"); if (isNavigableElement == null) { throw new Exception("Navigability not specified."); } return "true".equals(isNavigableElement.getAttribute("xmi.value")); } /** * Description: * Returns whether the association end is ordered. * *

* @param associationEndElement: the association end element tree. *

* *

* @return True if the association end is ordered; false otherwise. *

*/ public static boolean isAssociationEndOrdered( Element associationEndElement ) throws Exception { Element orderingElement = getFirstElementByTagName( associationEndElement, "Foundation.Core.AssociationEnd.ordering"); if (orderingElement == null) { throw new Exception("Ordering not specified."); } return !"unordered".equals(orderingElement.getAttribute("xmi.value")); } static final public String tobeIdentifiable = "Identifiable"; /** * Description: * Returns whether or not a given class is Identifiable -- * useful in the C++ generation code. * *

* @param myclass: the element which we wish to check. *

* *

* @return True if the Class is Identifiable; false otherwise. *

*/ public static boolean isIdentifiable( Element myclass ) throws Exception { String result = myclass.getAttribute( tobeIdentifiable ); if ( result.equals("true" ) ) { return true; } else { return false; } } /** * Description: * Sets up a class as identifiable or not. Useful for classes that are indirect * subclasses of identifiable * * *

* @param myclass: the element which we wish to identify *

* *

* @param value: whether or not it is true or false. *

*/ public static void setIdentifiable( Element myclass, boolean value ) throws Exception { if ( value == true ) { myclass.setAttribute( tobeIdentifiable, "true" ); } else { myclass.setAttribute( tobeIdentifiable, "false" ); } } /** * Description: * Sets up a class as identifiable or not. Useful for classes that are indirect * subclasses of identifiable * * *

* @param myclass: the element which we wish to identify *

* *

* @param value: whether or not it is true or false. *

*/ public static void setIdentifiable( Element myclass, String value ) throws Exception { myclass.setAttribute( tobeIdentifiable, value ); } }