Rational Rhapsody API Getting Started
Rational Rhapsody API Getting Started
1
Table of Contents
Where do I start ?...............................................................................................................3
What is the main object I have to create in order to access all other objects in the API ?.............4
So I guess that the next step should be to create a Rhapsody project or open an existing
Rhapsody project ?.............................................................................................................4
Now that I have a project, I can begin adding elements to the model?......................................4
What if I want to use an existing package in a project?............................................................5
OK – I used findNestedElement to get the package/class/other element that I want to add new
elements to. What methods do I use to add new elements ?....................................................5
What if I want to perform an action on a group of elements, for example, all classes in a package
or all diagrams in my model?................................................................................................7
Are there any inheritance relationships between the various interfaces? If so, is there a diagram
anywhere of these relationships?..........................................................................................8
How about properties? Rhapsody has thousands of them – can I use the Rhapsody API to modify
the value of specific properties?............................................................................................9
What other actions can be performed on a collection?............................................................10
Can I use the API to add diagrams to my model?..................................................................14
OK, now that I have added a diagram, how can I add elements to the diagram?.......................14
Does the API also provide methods for generating code?........................................................17
OK, I've generated code for the model. Are there also API methods for building and running the
application?......................................................................................................................18
What about methods for saving a model after changes were made to it?..................................19
How about an example of creating a statechart?...................................................................21
What about extracting information from a model, for example, generating a report or exporting
diagrams as graphic files?..................................................................................................26
Can I see some sample code that shows some of the things you can do with classes and their
attributes and operations?..................................................................................................29
2
Where do I start ?
OK, so you've decided that the Rhapsody API may be useful for you and you want to get
started with the Java version of the API. First thing you've got to do is set up a Java
project in your IDE and define references to the necessary libraries.
The steps below assume you are using Eclipse as your code editor. If you're using an
editor that does a little less spoon-feeding than Eclipse, we'll assume you know what you
have to do to adapt these instructions to your coding environment.
1. Create a new Java project.
2. Select the new project and open the popup menu – select Properties.
3. Open the Java Build Path set of tabs.
4. On the Libraries tab, choose Add External JARs...
5. Select the rhapsody.jar file, located in [rhapsody installation]/share/javaapi.
6. Once rhapsody.jar appears in the list, use the + sign to expand the elements below
it.
7. Select Native Library Location and set it to point to [rhapsody
installation]/share/javaapi, which is the directory that contains the rhapsody.dll
library. (If you are working on Linux, the library file is named rhapsody.so)
If you are using the 32-bit version of Rational Rhapsody, but are using the
Rhapsody API for applications that will be run with a 64-bit version of Java, point
to the directory [Rational Rhapsody installation directory]Share/JavaAPI/64Bit,
which contains a 64-bit version of rhapsody.dll.
Similarly, if you are using the 64-bit version of Rational Rhapsody, but are using
the Rhapsody API for applications that will be run with a 32-bit version of Java,
point to the directory [Rational Rhapsody installation
directory]Share/JavaAPI/32Bit, which contains a 32-bit version of rhapsody.dll.
To shorten this process for future Rhapsody API projects, you may want to use
the Eclipse option of defining a user library for these files.
That's it – you're good to go. As soon as you start writing code in your project, you
should have access to code completion for the Rhapsody API, and any other goodies that
Eclipse provides such as tooltips for displaying the Javadoc documentation.
3
What is the main object I have to create in order to access all
other objects in the API ?
The first thing you have to do in your java file is create an IRPApplication object, which
represents Rhapsody. So any application you write will include a line like the following:
static IRPApplication app =
RhapsodyAppServer.getActiveRhapsodyApplication();
If you use this line, you can then type a period after app in your next line of code and
you'll see the methods that are now available to you.
app.openProject("l:\\temp\\hello_world\\Hello_World.rpy");
app.activeProject();
When creating a new project, you have to provide the path where the project should be
created, and the name to use for the project name.
When opening an existing project, you have to provide the full path for the relevant .rpy
file.
The activeProject method returns the project currently open in Rhapsody.
Yes. Since most elements are added to packages, the next step should be to create a
new package.
IRPProject prj = app.activeProject();
The addPackage method returns the IRPPackage object that was created.
4
What if I want to use an existing package in a project?
Rhapsody has two generic methods that are used to get model elements, such as a
package, so that you can work with them.
• findNestedElement
• findNestedElementRecursive
Both of these methods belong to IRPModelElement.
The difference between the two methods is findNestedElement only searches the first
level of elements below the current element, while findNestedElementRecursive searches
all the way down to the lowest hierarchical level.
Both of these methods take two String arguments – the first is the name of the element
you are looking for, while the second is the type of element, such as Package.
So to get an existing package, you'll use a line like this:
IRPPackage packageToUse =
(IRPPackage)prj.findNestedElement("GreeterPackage", "Package");
Note that the object returned was cast as an IRPPackage object. This is necessary
because the method is a generic one and therefore always returns an object of type
IRPModelElement.
There are certain inheritance relationships between the different types of
elements that can be defined in Rhapsody. We'll discuss this at a later point. For
now, we'll just mention that IRPModelElement is the base for most of the
elements available in Rhapsody.
5
• The specific “add” methods return the type of object that was added, for example,
IRPPackage.addClass returns an IRPClass object, but the generic addNewAggr
method always returns an object of type IRPModelElement. This means that you
have to cast the returned element.
Some examples:
//find existing package and add class to it
IRPPackage packageToUse =
(IRPPackage)prj.findNestedElement("GreeterPackage", "Package");
IRPClass composerClass =
(IRPClass)pkg.addNewAggr("Class","TextComposer");
6
What if I want to perform an action on a group of elements, for
example, all classes in a package or all diagrams in my model?
The API includes an interface called IRPCollection that represents a collection of model
elements. This interface includes methods that can help you iterate through the collection
and perform an action on one or more elements in the collection, for example,
getCount() and getItem(int index).
There are a number of methods that return IRPCollection objects. These include:
• methods for returning collections of specific types of model elements, for example,
getPorts(), and getEvents().
• generic methods that return “mixed” collections, for example,
getNestedElements() and getNestedElementsRecursive(). getNestedElements()
returns a collection of all the elements in the first level below the current element,
while getNestedElementsRecursive() returns all the contained elements down to
the lowest hierarchical level.
The following code is a simple example of performing an action on a collection of items,
in this case all elements that make up the model.
theMap.put(element.getMetaClass(), element.getInterfaceName());
7
Are there any inheritance relationships between the various
interfaces? If so, is there a diagram anywhere of these
relationships?
The following diagrams illustrate the relationships between the different interfaces in the
Rhapsody API.
• All the interfaces in the diagram extend IRPModelElement, directly or via IRPUnit
which is derived from IRPModelElement.
• IRPUnit contains methods used for dealing with Rhapsody units, such as saving
and loading. So the interfaces that extend IRPUnit are those that represent model
elements that Rhapsody allows you to save as individual files.
• IRPStatechartDiagram represents the actual statechart diagram, while
IRPStatechart represents the concept reflected by the diagram.
8
How about properties? Rhapsody has thousands of them – can I
use the Rhapsody API to modify the value of specific properties?
You can get or set the value of a property for a model element using the following
IRPModelElement methods:
• getPropertyValue
• getPropertyValueExplicit
• setPropertyValue
The get methods take a single parameter―the name of the property. In this context, the
full name of the property must be provided, using a period as the delimiter, for example,
CPP_CG.Attribute.AccessorGenerate
The getPropertyValueExplicit method only returns the value of the property if the default
value has been overridden. If the value of the property is the default value for the
property, this method throws an exception
The set method takes two String parameters. The first parameter is the name of the
property (full name, with period as delimiter), while the second is the value to use for the
property.
The following sample code demonstrates use of the get and set methods for properties:
//open existing project
app.openProject("l:\\temp\\hello_world\\Hello_World.rpy");
String currentPropertyValue =
writerClass.getPropertyValue("CPP_CG.Class.GenerateDestructor");
9
System.out.print("At the beginning, the property has its default value
which is\n " + "\t" + currentPropertyValue + "\n\n");
writerClass.setPropertyValue("CPP_CG.Class.GenerateDestructor",
newPropertyValue);
currentPropertyValue =
writerClass.getPropertyValue("CPP_CG.Class.GenerateDestructor");
currentPropertyValue =
writerClass.getPropertyValueExplicit("CPP_CG.Class.GenerateDestructor");
The following sample code demonstrates all of the IRPCollection methods. The following
points will help you understand the code:
• There are two ways to add new items to a collection: You can use the addItem
method to tack the specified element to the end of the collection. However, if you
are adding a number of items, it may be more efficient to call setSize to set the
new size of the collection and then call setModelElement to place elements in
specific locations in the collection.
• When using the getItem method or setModelElement method, the index parameter
is based on an index value of 1 for the first element (not 0).
package documentation.rhapsodyapi;
import java.util.List;
import com.telelogic.rhapsody.core.*;
// main method
if(app != null)
10
doCollectionTricks();
app.createNewProject("l:\\temp\\_sample_code",
"Collection_Tricks");
IRPProject prj =
app.openProject("l:\\temp\\_sample_code\\Collection_Tricks.rpy");
IRPClass convertibleClass =
vehiclePackage.addClass("Convertible");
IRPPackage airVehiclePackage =
prj.addPackage("Air_Vehicles");
airVehiclePackage.addClass("Helicopter");
convertibleClass.addGeneralization(carClass);
prj.save();
11
IRPClass tempClass = null;
tempClass = (IRPClass)(currentContentsOfCollection.get(i));
classCollection.empty();
classCollection.addItem(carClass);
classCollection.addItem(jeepClass);
+ "\n " +
((IRPClass)classCollection.getItem(1)).getDisplayName() + "\n "
+
((IRPClass)classCollection.getItem(2)).getDisplayName());
classCollection.setSize(5);
classCollection.setModelElement(3, busClass);
classCollection.setModelElement(4, convertibleClass);
classCollection.setModelElement(5, truckClass);
numberOfItemsInList = classCollection.getCount();
12
now contains the following " + classCollection.getCount() + " items:");
tempClass = (IRPClass)(classCollection.getItem(i));
IRPDiagram classDiagramToCreate =
vehiclePackage.addObjectModelDiagram("Classes in Vehicles package");
IRPCollection classesToAddToDiagram =
vehiclePackage.getClasses();
IRPCollection typesOfRelationsToShow =
app.createNewCollection();
typesOfRelationsToShow.setSize(2);
typesOfRelationsToShow.setString(1, "Inheritance");
typesOfRelationsToShow.setString(2, "Dependency");
classDiagramToCreate.populateDiagram(classesToAddToDiagram,
typesOfRelationsToShow, "fromto");
13
Can I use the API to add diagrams to my model?
The IRPPackage interface contains methods for adding the following types of diagrams:
• activity diagrams
• collaboration diagrams
• component diagrams
• deployment diagrams
• object model diagrams
• sequence diagrams
• use case diagrams
You can also use IRPModelElement's generic addNewAggr method to add a diagram to
your model.
To add a statechart or activity diagram to a class, however, the following methods must
be used:
• IRPClassifier.addActivityDiagram
• IRPClassifier.addStatechart
All of the diagram types extend the interface IRPDiagram, which provides methods for
basic diagram-related actions, such as:
OK, now that I have added a diagram, how can I add elements to
the diagram?
While there are a number of methods for adding model elements to a diagram, the
simplest approach is to use IRPDiagram.populateDiagram.
populateDiagram takes the following three arguments:
• an IRPCollection object consisting of the model elements you would like to place
on the diagram
• a second IRPCollection object consisting of the types of relations that you would
like to have displayed on the diagram
14
• a String argument that represents which related elements you would like to have
included on the diagram, in addition to those you specified directly. This argument
can take any of the following values: among, from, to, fromto.
The following code creates three classes, two of which are derived from the third class. It
then creates an object model diagram and places the three classes on the diagram,
showing the inheritance relationships.
app.openProject("l:\\temp\\_sample_diagrams\\Diagram_sample.rpy");
jeep.addGeneralization(car);
convertible.addGeneralization(car);
IRPDiagram vehicleOmd =
vehiclePackage.addObjectModelDiagram("vehicle_omd");
relationTypes.setSize(1);
relationTypes.setString(1, "Inheritance");
The next code snippet is similar to the first but demonstrates the use of “fromto” as the
third argument. In this case, one of the derived classes serves as a base class for a
fourth class. Even though this fourth class is not specified to be added to the diagram, it
is included in the diagram because it has a relation with one of the other three classes.
This may seem a little superfluous in this example, but the “fromto” and other values for
the third argument are useful in larger models where you may not be aware of all the
relations. The lines of code that were added to the previous sample are highlighted.
app.openProject("l:\\temp\\_sample_diagrams\\Diagram_sample.rpy");
15
jeep.addGeneralization(car);
convertible.addGeneralization(car);
coolJeep.addGeneralization(jeep);
IRPDiagram vehicleOmd =
vehiclePackage.addObjectModelDiagram("vehicle_omd");
relationTypes.setSize(1);
relationTypes.setString(1, "Inheritance");
16
Does the API also provide methods for generating code?
The IRPApplication interface contains the following methods for code generation:
• generate()
generates code for the active configuration
• generateElements(IRPCollection)
generates code for the specified elements
• generateEntireProject()
generates code for the entire project
• generateMainAndMakeFiles()
generates only the main file and makefiles
• generateWithDependencies()
generates code for the active configuration and for any component on which the
active component depends
There are also regenerate methods corresponding to each of these methods, except for.
generateMainAndMakeFiles.
The behavior of the regenerate methods is identical to that of the regenerate options in
the GUI, meaning they will always go through the code generation process even if
Rhapsody has not detected any changes to the elements, however, they will not
overwrite the source code file if no changes were made.
In the sample code below, three classes are created. At first, code is generated only for
two of the classes. The second code generation call generates code for all elements in the
active configuration. If you pause execution after the first code generation method call,
you will see that no code was generated for the Jeep class.
app.openProject("l:\\temp\\_sample_diagrams\\Diagram_sample.rpy");
jeep.addGeneralization(car);
convertible.addGeneralization(car);
classesToGenerate.addItem(car);
classesToGenerate.addItem(convertible);
app.generateElements(classesToGenerate);
17
app.generate();
The generate() method generates code for the active configuration. Use the
IRPApplication methods setComponent and setConfiguration to choose the
relevant configuration before calling the generate() method.
OK, I've generated code for the model. Are there also API
methods for building and running the application?
Before building the application, use the following methods to specify how the application
should be built:
• IRPComponent.setBuildType(String)
The possible argument values are “executable” and “library”.
• IRPConfiguration.setBuildSet(String)
The possible argument values are “debug” and “release”.
The following IRPApplication methods can be used to build/rebuild an application:
• build()
• buildEntireProject()
• buildWithDependencies()
• rebuild()
• rebuildEntireProject
• rebuildWithDependencies()
You can then run the application by calling IRPApplication.runApplication().
The following sample code creates a single class with a single operation that displays
some text. It then generates the code, builds the application, and runs the application.
A few things to note:
• Rhapsody automatically creates a file containing a main method
• The IRPConfiguration.addInitialInstance method is used to create objects from
within the main function.
• The IRPConfiguration.setInitializationCode method is used to add any additional
code to the main function.
app.openProject("l:\\temp\\_sample_diagrams\\Diagram_sample.rpy");
18
Rhapsody\");";
displayTextOp.setBody(bodyContent);
activeCfg.addInitialInstance(writer);
activeCfg.setInitializationCode(initCode);
app.generate();
app.build();
app.runApplication();
The following methods can be used to save an entire model. Their behavior is similar to
that of the corresponding menu items in the GUI:
• IRPProject.save()
• IRPProject.saveAs(String filename)
The format of the string used for the file name should be similar to that used to
open a project, for example, "l:\\temp\\_sample_diagrams\\Diagram_sample.rpy"
• IRPProject.saveAsPrevVersion(String filename, String prevVersion)
This method represents the option provided to save a model in the format of an
older version of Rhapsody. The second String argument should consist of the
version number that should be used, for example “7.4”.
The following sample code opens a project, adds a class, saves the project, and then
closes the project.
package documentation.rhapsodyapi;
import java.lang.*;
import com.telelogic.rhapsody.core.*;
19
if(app != null)
openAndCloseProject();
app.createNewProject("l:\\temp\\_sample_code", "Open_Close");
IRPProject prj =
app.openProject("l:\\temp\\_sample_code\\Open_Close.rpy");
vehiclePackage.addClass("Car");
prj.save();
prj.close();
20
How about an example of creating a statechart?
The following points will help you understand the sample code.
• All top-level states are added to the “root” state, which you get by calling
IRPStatechart.getRootState(). Elements such as termination states and condition
connectors are also added to the root state.
• All statecharts have a default transition. You create a default transition by calling
IRPState. CreateDefaultTransition and providing the root state as the parameter.
• Timeout transitions are created using the IRPTransition.setItsTrigger method, as
follows: screamTimeoutTransition.setItsTrigger("tm(10000)"). The number
represents the number of milliseconds.
• When you create a diagram with the API, the graphical representation is not
created by default. This means that the first time you open the diagram in
Rhapsody, you will be asked if the graphics should be created. You can create the
graphical representation directly by calling IRPStatechart.createGraphics().
package documentation.rhapsodyapi;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import com.telelogic.rhapsody.core.*;
if(app != null){
designStatechart();
21
app.createNewProject("l:\\temp\\_sample_code",
"Statechart_Design");
IRPProject prj =
app.openProject("l:\\temp\\_sample_code\\Statechart_Design.rpy");
IRPState celebratingState =
rootState.addState("Celebrating");
celebratingState.setEntryAction("exchangeHighFives();");
celebratingState.setExitAction("calmDown();");
thinkingState.createDefaultTransition(rootState);
IRPTransition tdTransition =
thinkingState.addTransition(celebratingState);
IRPTrigger tdTrigger =
tdTransition.setItsTrigger("touchdown");
tdTransition.setItsAction("raiseHands();");
22
IRPConnector tranqConditionConnector =
rootState.addConnector("Condition");
IRPTransition badCall =
thinkingState.addTransition(tranqConditionConnector);
badCall.setItsTrigger("bad_call_by_referee");
IRPAttribute takingTranquilizers =
coach.addAttribute("isTakingTranquilizers");
takingTranquilizers.setTypeDeclaration("RhpBoolean");
takingTranquilizers.setDefaultValue("true");
IRPTransition calmTransition =
tranqConditionConnector.addTransition(thinkingState);
calmTransition.setItsGuard("takingTranquilizers == true");
IRPTransition notCalmTransition =
tranqConditionConnector.addTransition(screamingState);
notCalmTransition.setItsGuard("else");
notCalmTransition.setItsAction("throwDownHeadset();");
IRPTransition screamTimeoutTransition =
screamingState.addTransition(thinkingState);
screamTimeoutTransition.setItsTrigger("tm(10000)");
IRPTransition celebTimeoutTransition =
celebratingState.addTransition(thinkingState);
celebTimeoutTransition.setItsTrigger("tm(20000)");
IRPTransition gameOver1Trans =
thinkingState.addTransition(termState);
23
gameOver1Trans.setItsTrigger("game_over");
gameOver1Trans.setItsGuard("noPenalty == true");
IRPTransition gameOver2Trans =
celebratingState.addTransition(termState);
gameOver2Trans.setItsTrigger(gameOver1Trans.getItsTrigger().getBody());
gameOver2Trans.setItsGuard(gameOver1Trans.getItsGuard().getBody());
IRPTransition gameOver3Trans =
screamingState.addTransition(termState);
gameOver3Trans.setItsTrigger(gameOver1Trans.getItsTrigger().getBody());
gameOver3Trans.setItsGuard(gameOver1Trans.getItsGuard().getBody());
coachChart.createGraphics();
String intro = "This message box will explain a bit about the
statechart, but it's really just a way" +
IRPEvent tempTrigger;
24
tempTrigger =
(IRPEvent)coachChart.getAllTriggers().getItem(trigCount + 1);
+ tdTransition.getItsSource().getDisplayName() + "
state, " +
+ tdTransition.getItsTarget().getDisplayName() + "
state.\n\n";
"When exiting this state, the coach performs the action "
+ celebratingState.getExitAction() + ".\n\n";
JOptionPane.showMessageDialog(new JFrame(),intro +
itsClassName + allTriggerText + tdTriggerText + celebStateText +
guardInfo);
25
What about extracting information from a model, for example,
generating a report or exporting diagrams as graphic files?
The API contains two methods for generating a report from your model, one that uses
the basic report generator, and one that uses ReporterPLUS:
• IRPApplication.report(String format, String outputFileName)
This method uses Rhapsody's basic report generator, allowing you to specify the
output format (“ASCII” or “RTF”), and where the output file should be saved. There
is no need to specify the file extension; Rhapsody will append “.txt” or “.rtf” to the
string you provide. Note that the report will include information for the elements in
the scope of the active component.
• IRPProject.generateReport(String modelscope, String templatename, String
docType, String filename, int showDocument, int silentMode)
This method generates a report using the reporting capabilities of ReporterPLUS.
The arguments to be provided represent: the name of the package to report on (or
empty string for the whole model), the name of the template to use, the type of
output to generate (“doc”, “html”, “ppt”, or “txt”), the filename for the generated
output, whether the output should be displayed (use 1 to display, 0 otherwise),
and whether or not the ReporterPLUS wizard should be displayed if not all of the
required information is provided as arguments (use 1 to skip display of the wizard
in such cases).
There is no need to specify the file extension; Rhapsody will append the
appropriate extension to the string you provide.
When this method is used to generate a report, the Rhapsody model is saved
before the report is generated.
With regard to exporting diagrams as graphic-format files, the API provides methods for:
• Saving a diagram as an emf file
IRPDiagram.getPicture(String filename)
• Saving a diagram in a graphic format other than emf
IRPDiagram.getPictureAs(String firstFileName, String imageFormat, int
getImageMaps, IRPCollection diagrammap)
The relevant strings for the imageFormat argument are “EMF”, “BMP”, “JPEG”,
“JPG”, “TIFF”.
For both of these export methods, the filename argument should include the appropriate
extension. Rhapsody does not add the extension automatically as it does for the report
generation methods.
26
In addition to allowing you to specify a graphic-file format, the getPictureAs
method includes arguments that allow you to
a) export the diagram as a number of files rather than shrinking the diagram
b) retrieve diagram element information that can be used to create an HTML
image map.
For a detailed explanation of these additional arguments, see the Javadoc output
for the API ([installation directory]\Doc\java_api).
The following sample code illustrates the use of the report generation methods and the
methods for exporting diagrams.
In this sample, the line that calls the generateReport method must be modified
before you run it because it has to point to the location of the ReporterPLUS
templates in your installation of Rhapsody.
package documentation.rhapsodyapi;
import com.telelogic.rhapsody.core.*;
if(app != null)
extractInformation();
app.createNewProject("l:\\temp\\_sample_code",
"Extract_Info");
IRPProject prj =
app.openProject("l:\\temp\\_sample_code\\Extract_Info.rpy");
jeep.addGeneralization(car);
convertible.addGeneralization(car);
coolJeep.addGeneralization(jeep);
27
IRPDiagram vehicleOmd =
vehiclePackage.addObjectModelDiagram("vehicle_omd");
relationTypes.setSize(1);
relationTypes.setString(1, "Inheritance");
vehicleOmd.populateDiagram(vehicleClasses, relationTypes,
"fromto");
prj.save();
app.report("RTF",
"l:\\temp\\_sample_code\\reports_and_pictures\\project_report");
prj.generateReport("",
"l:\\programs\\rhapsody_752_build_1471822\\reporterplus\\Templates\\Rhaps
ody HTML Exporter.tpl", "html",
"l:\\temp\\_sample_code\\reports_and_pictures\\project_report_rep_plus",
0, 1);
vehicleOmd.getPicture("l:\\temp\\_sample_code\\reports_and_pictures\\omd.
emf");
vehicleOmd.getPictureAs("l:\\temp\\_sample_code\\reports_and_pictures\\om
d.jpg", "JPG", 0, null);
28
Can I see some sample code that shows some of the things you
can do with classes and their attributes and operations?
package documentation.rhapsodyapi;
import com.telelogic.rhapsody.core.*;
// main method
if(app != null)
manipulateClassData();
app.createNewProject("l:\\temp\\_sample_code",
"Class_Tricks");
IRPProject prj =
app.openProject("l:\\temp\\_sample_code\\Class_Tricks.rpy");
IRPClass stillsCameraClass =
cameraPackage.addClass("StillsCamera");
IRPClass videoCameraClass =
cameraPackage.addClass("VideoCamera");
IRPClass comboCameraClass =
cameraPackage.addClass("ComboCamera");
29
// can use either of these two methods for establishing
inheritance relationship
stillsCameraClass.addGeneralization(cameraClass);
videoCameraClass.addGeneralization(cameraClass);
comboCameraClass.addSuperclass(cameraClass);
IRPCollection classesStillsInheritsFrom =
stillsCameraClass.getGeneralizations();
int numberOfBaseClasses =
classesStillsInheritsFrom.getCount();
IRPGeneralization tempGeneralization;
tempGeneralization = (IRPGeneralization)
(classesStillsInheritsFrom.getItem(i));
System.out.println(" " +
tempGeneralization.getDisplayName());
stillsCameraClass.deleteGeneralization(cameraClass);
classesStillsInheritsFrom =
stillsCameraClass.getGeneralizations();
numberOfBaseClasses = classesStillsInheritsFrom.getCount();
if (numberOfBaseClasses==0) {
} else {
tempGeneralization = (IRPGeneralization)
(classesStillsInheritsFrom.getItem(i));
System.out.println(" " +
30
tempGeneralization.getDisplayName());
// restore inheritance
stillsCameraClass.addGeneralization(cameraClass);
IRPCollection allBaseClasses =
stillsCameraClass.getBaseClassifiers();
numberOfBaseClasses = allBaseClasses.getCount();
IRPClass tempClass;
tempClass = (IRPClass)(allBaseClasses.getItem(i));
System.out.println("=====================================================
==============");
// like adding a base class, there are also two methods for
deleting a base class - deleteGeneralization (used above) and
deleteSuperclass (below)
IRPCollection classesVideoInheritsFrom =
videoCameraClass.getGeneralizations();
numberOfBaseClasses = classesVideoInheritsFrom.getCount();
tempGeneralization = (IRPGeneralization)
(classesVideoInheritsFrom.getItem(i));
System.out.println(" " +
tempGeneralization.getBaseClass().getDisplayName());
31
videoCameraClass.deleteSuperclass(cameraClass);
classesVideoInheritsFrom =
videoCameraClass.getGeneralizations();
numberOfBaseClasses = classesVideoInheritsFrom.getCount();
if (numberOfBaseClasses==0) {
} else {
tempGeneralization = (IRPGeneralization)
(classesVideoInheritsFrom.getItem(i));
System.out.println(" " +
tempGeneralization.getBaseClass().getDisplayName());
System.out.println("=====================================================
==============");
videoCameraClass.addGeneralization(cameraClass);
IRPCollection allDerivedClasses =
cameraClass.getDerivedClassifiers();
tempClass = (IRPClass)(allDerivedClasses.getItem(i));
32
tempClass =
(IRPClass)cameraClass.findDerivedClassifier("StillsCamera");
tempClass =
(IRPClass)stillsCameraClass.findBaseClassifier("Camera");
tempGeneralization =
(IRPGeneralization)stillsCameraClass.findGeneralization("Camera");
System.out.println("=====================================================
==============");
// for the first one, we'll use a variable for the attribute
created so we can use it later
IRPAttribute resolution =
cameraClass.addAttribute("maxResolution");
cameraClass.addAttribute("weight");
cameraClass.addAttribute("internalMemory");
cameraClass.addAttribute("color");
IRPAttribute tempAtt;
33
for(int i = 1; i < cameraAttributes.getCount()+1 ; i++) {
tempAtt = (IRPAttribute)cameraAttributes.getItem(i);
IRPAttribute attToDelete =
cameraClass.findAttribute("weight");
cameraClass.deleteAttribute(attToDelete);
cameraAttributes = cameraClass.getAttributes();
tempAtt = (IRPAttribute)cameraAttributes.getItem(i);
System.out.println("=====================================================
==============");
resolution.setVisibility("private");
System.out.println("=====================================================
==============");
34
cameraClass.findAttribute("internalMemory").setIsConstant(1);
cameraClass.findAttribute("internalMemory").setIsStatic(1);
cameraAttributes = cameraClass.getAttributes();
tempAtt = (IRPAttribute)cameraAttributes.getItem(i);
if (tempAtt.getIsConstant() == 1) {
} else {
if (tempAtt.getIsStatic() == 1) {
} else {
System.out.println("=====================================================
==============");
cameraClass.findAttribute("color").setIsReference(1);
cameraAttributes = cameraClass.getAttributes();
tempAtt = (IRPAttribute)cameraAttributes.getItem(i);
if (tempAtt.getIsReference() == 1) {
} else {
35
}
System.out.println("=====================================================
==============");
stillsCameraClass.addAttribute("hasTimer");
IRPCollection stillsAttributes =
stillsCameraClass.getAttributes();
System.out.println("The " +
stillsCameraClass.getDisplayName() + " contains the following attributes
of its own:");
tempAtt = (IRPAttribute)stillsAttributes.getItem(i);
IRPCollection stillsAttributesWithBases =
stillsCameraClass.getAttributesIncludingBases();
System.out.println("\nThe " +
stillsCameraClass.getDisplayName() + " contains the following attributes
(includes those of its base class):");
tempAtt =
(IRPAttribute)stillsAttributesWithBases.getItem(i);
System.out.println("=====================================================
==============");
IRPOperation takePicture =
cameraClass.addOperation("takePicture");
36
IRPOperation setResolution =
cameraClass.addOperation("setResolution");
cameraClass.addTriggeredOperation("checkBatteryStrength");
cameraClass.addDestructor();
IRPOperation tempOperation;
tempOperation =
(IRPOperation)cameraOperations.getItem(i);
if (tempOperation.getIsTrigger() == 1) {
System.out.println(" " +
tempOperation.getDisplayName() + "(triggered operation)");
} else {
if (tempOperation.getIsDtor() == 1) {
System.out.println(" " +
tempOperation.getDisplayName() + "(destructor)");
} else if (tempOperation.getIsCtor() == 1) {
System.out.println(" " +
tempOperation.getDisplayName() + "(constructor)");
else {
System.out.println(" " +
tempOperation.getDisplayName());
37
// use the final keyword
setResolution.setIsFinal(1);
cameraOperations = cameraClass.getOperations();
tempOperation =
(IRPOperation)cameraOperations.getItem(i);
if (tempOperation.getIsFinal() == 1) {
System.out.println(" " +
tempOperation.getDisplayName() + "(final)");
System.out.println("=====================================================
==============");
cameraClass.deleteDestructor();
cameraClass.deleteOperation(windFilm);
cameraOperations = cameraClass.getOperations();
tempOperation =
(IRPOperation)cameraOperations.getItem(i);
System.out.println(" " +
tempOperation.getDisplayName());
System.out.println("=====================================================
==============");
takePicture.setBody("openShutter();\ncloseShutter();");
38
// print out the return type of the method
System.out.println("=====================================================
==============");
setResolution.setVisibility("Private");
System.out.println("=====================================================
==============");
IRPDiagram classDiagramToCreate =
cameraPackage.addObjectModelDiagram("Classes in Cameras package");
IRPCollection classesToAddToDiagram =
cameraPackage.getClasses();
IRPCollection typesOfRelationsToShow =
app.createNewCollection();
typesOfRelationsToShow.setSize(1);
typesOfRelationsToShow.setString(1, "Inheritance");
classDiagramToCreate.populateDiagram(classesToAddToDiagram,
typesOfRelationsToShow, "fromto");
// you can also use a debugger to step through the code and
view the changes made to the model in Rhapsody's model browser
39