Extending C++-to-UML transformations

To customize how the transformation transforms C++ elements into corresponding UML elements, you can extend the C++-to-UML transformation and the transforms that it contains.

Before you begin

The following procedure assumes that you know how to create, test, and distribute plug-ins, and that you are familiar with the Eclipse Plug-in Development Environment (PDE).

About this task

The example in this topic explains how to extend the C++-to-UML transformation to customize the transformation of C++ attributes in C++ classes into UML attributes. For information about the transforms that transform other C++ elements into UML, see the related reference topics below.

To extend the C++-to-UML transformation:

Procedure

  1. Create a plug-in project in the Eclipse workspace:
    1. Click File > New > Transformation Authoring > Generic Transformation Project; then click Next.
  2. On the Plug-in Project page, in the Project name field, specify a project name. For this example, specify com.ibm.xtools.cpp.uml2.attributetypeextn.transformation.Extension.
  3. Click Next.
  4. On the Plug-in Content page, accept the default values, and click Next.
  5. Click Finish. If you are prompted to switch to the Plug-in Development perspective, click Yes.
  6. In the navigation view, in the plug-in project that you created in step 1, in the META-INF folder, double-click MANIFEST.MF.
  7. In the plug-in manifest file, create a TransformationExtension element:
    1. On the Extensions page, click Add.
    2. In the New Extension wizard, on the Extension Point Selection page, click the Extension Wizards tab.
    3. On the Extension Wizards page, click Transformation Templates > Transformation Extensions; then click Next.
  8. On the New Transformation Extension page, complete the following steps:
    • In the ID field, specify a unique value that identifies the transformation extension to the transformation service. This field is typically prepopulated with the project name and a transformationExtension suffix. For this example, verify that this field contains the value com.ibm.xtools.cpp.uml2.attributetypeextn.transformation.Extension.transformationExtension.
    • In the Name field, specify a name for the transformation extension. For this example, specify My Transformation Attribute Extension.
    • In the Target transformation ID field, specify com.ibm.xtools.transform.cpp.uml2.transformation.
    Note: For more information about the other fields on this page and the remaining pages in the wizard, see the context-sensitive help by pressing F1 when that page is displayed in the product. If you are using the Linux platform, press Shift+F1.
  9. Click Next.
  10. On the New Transformation Extension page, define a rule for the transformation extension:
    1. Click Insert.
    2. In the Element Type column, from the list of elements, select Rule.
    3. In the ID and Name columns, specify com.ibm.xtools.cpp.uml2.attributetypeextn.attrtyperule.
    4. In the Class column, specify attrtyperule.
    This action only declares the rule; it does not add it to any of the transforms that you extend.
  11. Click Next.
  12. On the next New Transformation Extension page, in the "Extended transforms" table, specify the transforms to extend. The transforms in the following list transform C++ attributes and interface attributes into corresponding UML elements. For each of these transforms, beside the "Extended transforms" table, click Insert, and specify the transform name in the Target Transformation ID column:
    • com.ibm.xtools.transform.cpp.uml2.CPPProjectMemberTransform.CPPFolderMemberTransform.CPPNamespaceMemberTransform.CPPClassStructUnionMemberTransform.CPPMemberVariableTransform
    • com.ibm.xtools.transform.cpp.uml2.CPPProjectMemberTransform.CPPSourceMemberTransform.CPPNamespaceMemberTransform.CPPClassStructUnionMemberTransform.CPPMemberVariableTransform
    • com.ibm.xtools.transform.cpp.uml2.CPPProjectMemberTransform.CPPSourceMemberTransform.CPPClassStructMemberTransform.CPPMemberVariableTransform
  13. Specify that each extended transform must implement the rule that you declared in step 10. For each transform you specify in the "Extended transforms" table, complete the following steps:
    1. In the "Extended transforms" table, click a cell in the Target Transformation ID column.
    2. Beside the "Additions to selected extended transform" table, click Insert.
    3. In the Element Type column, from the list, select Rule.
    4. In the ID column, specify the ID of the class contained in the rule that you declared in 10. For this example, specify com.ibm.xtools.cpp.uml2.attributetypeextn.attrtyperule.
    When you click a cell in the Target Transformation ID column of the "Extended transforms" table, the "Additions to the selected extended transform" table displays the elements that are associated with that transform. For this example, the attrtyperule rule is associated with each transform in the "Extended transforms" table.
  14. Click Next, then click Finish. If you are prompted to save the changes that you made to the plug-in, click Yes.
  15. For each transform, specify that the attrtyperule rule runs as the second rule in each of the extended transforms: In the plug-in manifest editor, on the Extensions page, in the All Extensions section, for each ExtendTransform element, complete the following steps:
    1. Click the AddRule element that is associated with the com.ibm.xtools.cpp.uml2.attributetypeextn.attrtyperule rule.
    2. In the Extension Element Details area, in the index field, type 1. Indexing starts at 0.
  16. Click File > Save.
  17. On the Dependencies page, in the Required Plug-ins section, if they do not already exist, add the following plug-ins:
    • org.eclipse.uml2.uml
    • com.ibm.xtools.cpp.model
    • com.ibm.xtools.transform.core
    • com.ibm.xtools.transform.cpp.uml2
  18. Click File > Save.
  19. Define the Java implementation of the attrtype rule that a transform in the C++-to-UML transformation invokes when it encounters a C++ attribute in the transformation source. In this example, the implementation class is located in a different project than the transformation extension. The following code fragment shows a possible implementation:
    /*
     *+------------------------------------------------------------------------+
     *| Licensed Materials - Property of IBM                                   |
     *| (C) Copyright IBM Corp. 2004.  All Rights Reserved.                    |
     *|                                                                        |
     *| US Government Users Restricted Rights - Use, duplication or disclosure |
     *| restricted by GSA ADP Schedule Contract with IBM Corp.                 |
     *+------------------------------------------------------------------------+
     */
    package com.ibm.xtools.cpp.uml2.attributetypeextn;
    
    import org.eclipse.uml2.uml.Classifier;
    import org.eclipse.uml2.uml.NamedElement;
    import org.eclipse.uml2.uml.Package;
    import org.eclipse.uml2.uml.Property;
    import org.eclipse.uml2.uml.Type;
    
    import com.ibm.xtools.cpp.model.CPPOwnedAttribute;
    import com.ibm.xtools.transform.core.AbstractRule;
    import com.ibm.xtools.transform.core.ITransformContext;
    import com.ibm.xtools.transform.cpp.uml2.internal.CPPModelToUML.util.CPPModelToUMLUtil;
    
    /**
     * attrtyperule is registered in plugin.xml as a RuleDefinition.  
     */
    
    /*
     * (non-Javadoc)
     * 
     * @see com.ibm.xtools.transform.core.AbstractRule
     */
    public class attrtyperule extends AbstractRule {
    
    	/*
    	 * (non-Javadoc)
    	 * 
    	 * @see com.ibm.xtools.transform.core.AbstractRule#createTarget(com.ibm.xtools.transform.core.ITransformContext)
    	 */
    	public static final String UML_TYPE_STRING = "String"; 
    
    	
    	public Object createTarget(ITransformContext ruleContext) {
    
    		//TODO Auto-generated method stub
    		Object source = ruleContext.getSource();
    		if (source instanceof CPPOwnedAttribute) {
    			CPPOwnedAttribute attribute = (CPPOwnedAttribute) source;
    			Classifier klass = (Classifier) ruleContext.getTargetContainer();
    			NamedElement umlElement = null;
    
    			if(klass instanceof org.eclipse.uml2.uml.Class){
    				umlElement = ((org.eclipse.uml2.uml.Class)klass).getOwnedMember(attribute.getName());
    			}
    			
    			Property umlProperty = (Property) umlElement;
    			if(attribute.getQualifierString().contains("*") &&(umlProperty.getType().getName().equalsIgnoreCase("char")) ){
    				setStringType(umlProperty);
    			}
    
    			return umlElement;
    
    		}	
    		return null;
    
    
    	}
    	public static Type setStringType( 	Property umlProperty ){
    		 Package rootElement = CPPModelToUMLUtil.getRootElement(umlProperty);
    		 Type umlString = (Type) rootElement.getImportedMember(UML_TYPE_STRING);
    		 umlProperty.setType(umlString);
    		return null;
    	}
    	
    	
    }

Results

The next time that you run the C++-to-UML transformation, it transforms the attributes as specified in the previous code fragment.

Feedback