Replacing references to Rational Rose unique identifiers after the import of a model that used the Data Modeler add-in

Technote (FAQ)

Question

How do you replace references to the IBM Rational Rose (Rose) unique identifiers (QUID) in a project that used the Data Modeler add-in and was then imported into IBM Rational Software Architect (RSA)?

Cause

If your Rose model was making use of the Data Modeler add-in, and if you checked the Import property sets as UML profiles checkbox on theMap Property Sets of the Import wizard when importing the model into RSA, all the data added to your Rose model by the Data Modeler add-in will be imported into RSA.

However, because the functionalities offered by the Data Modeler add-in are not present in RSA, some of the imported properties are a raw copy of the ones of the Data Modeler add-in.

This is certainly the case for primary keys, foreign keys or indices that were defined with references to other Rose elements. If you look, in RSA, at the KeyList property (from the applied Default stereotype of the Data_Modeler profile) of those elements, you will see that this property refers to a Rose QUID that is not easily readable.

Therefore, you may want to find a way to convert this information into the name of the matching RSA UML element.

Answer

You will find instructions below that let you create a complete pluglet to replace all the references to Rose QUID in the KeyList property with the qualified name of the corresponding UML element.

NOTE: The KeyList property is of type String, which means that none of the changes made to the name of the elements to which it refers will be taken into account after the pluglet has been run. Indeed, the pluglet only changes the content of the KeyList property but not its type. If you also want the type of the KeyList property to be changed, so that it can hold direct references to UML elements of the model, you will have to write additional code.

Disclaimer

All source code and/or binaries attached to this document are referred to here as "the Program". IBM is not providing program services of any kind for the Program. IBM is providing the Program on an "AS IS" basis without warranty of any kind. IBM WILL NOT BE LIABLE FOR ANY ACTUAL, DIRECT, SPECIAL, INCIDENTAL, OR INDIRECT DAMAGES OR FOR ANY ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING LOST PROFITS OR SAVINGS), EVEN IF IBM, OR ITS RESELLER, HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

To build the pluglet:

Start Rational Software Architect

Select File > New > Pluglets Project

Select File > New > Pluglet

Select the type: UML Modeler > Model Enumeration

Select the package: com.ibm.rational.support

Select the name: DataModelerIdsConverter

Replace the code of the class DataModelerIdsConverter with the following and save the changes:

if (elements.isEmpty()) { out.println("Cannot perform enumeration on current selection."); //$NON-NLS-1$ out.println("Please select a UML Element from the Project Explorer or"); //$NON-NLS-1$ out.println("select a Notation element from a diagram."); //$NON-NLS-1$ }for (EObject element : elements) {if (!(element instanceof NamedElement)) // We are only accepting elements of type org.eclipse.uml2.uml.Element as they allow // to easily get access to the model, but this is not strictly mandatory. out.println("Element "+element+" is not valid: it should be a org.eclipse.uml2.uml.Element!"); //$NON-NLS-1$else { Element UMLElement = (Element)element; // Update the element, based on a map that binds all rose ids to the name of the matching RSA UMLElement. updateElementAndSubElements(UMLElement, mapRoseIdsAndNames(UMLElement.getModel())); } } } }); } catch (IllegalStateException e) { out.println("The operation was interrupted"); //$NON-NLS-1$ } }

/** * Create a map that associates the former Rose ids of all the elements of the model that were imported form a Rose model * with the fully qualified name of the matching elements. If no elements were imported from Rose, the map will be empty. * @param model The model to analyze. * @return a Hashmap where keys are the former Rose ids of all elements of the model that were imported from Rose and where * values are the fully qualified names of those elements. */protected Map<String, String> mapRoseIdsAndNames(Model model) { Map<String, String> result = new HashMap<String, String>(); List <NamedElement> modelElements = getUMLSubElements(model);for (NamedElement modelElement : modelElements){ String roseId = getRoseQUID(modelElement);if (roseId != null) // This will put the fully qualified name in the map. Use the following line instead, if you want the simple name: //result.put(roseId, modelElement.getName()); result.put(roseId, modelElement.getQualifiedName()); }return result; }

/** * convert a list of former Rose unique ids into the name of the matching UML Named element in the model. * @param idlist the comma separated list of all potential former Rose unique ids to analyze. * @param elementsIds a map that associates elements to their former rose unique id and to which the ids will be compared. * @return a comma separated list of all the former rose unique ids */private String convertIdsToRSANames(String idlist, Map<String, String> elementsIds){if (idlist == null)returnnull; List<String> roseIds = Arrays.asList(idlist.split(","));for (int i = 0; i < roseIds.size(); i++)for (String id: elementsIds.keySet())if (id.equals(roseIds.get(i))) roseIds.set(i, elementsIds.get(id));return listToString(roseIds); }

/** * return the RSA unique Id of a given EObject element. * @param element the EObject element for which the RSA unique Id must be returned. * @return the RSA unique Id of the element. */private String getId(EObject element) {return element.eResource().getURIFragment(element); }

/** * return the former Rose unique Id (QUID) of a given EObject element that was imported from a Rose model. * @param element the EObject element for which the former Rose unique Id must be returned. * @return the former Rose unique Id of the element if it was imported from a Rose model, null otherwise. */private String getRoseQUID(EObject element) { String rsaId = getId(element); // Unique ids of elements that were created within RSA are in mixed case // whereas elements imported from Rose are in upper case.if (null != rsaId && rsaId.toUpperCase().equals(rsaId)) // The former Rose unique ids of elements imported into RSA // are stored as the last 12 characters of the RSA unique id (eg: 4378501B02AF).return rsaId.substring(rsaId.length() - 12);returnnull; }

/** * Concatenate a list of character strings into a comma separated list stored as a unique character string. * @param strings the list of character strings to concatenate. * @return the comma separated list stored as a unique character string. */private String listToString (List<String> strings){ String result = "";for (String string: strings) result+=string+","; // We remove the last comma that is superfluous.return result.substring(0, result.length()-1); } }