Copyright © 1999 by Novosoft Inc. All rights reserved

NovoSoft UML API Programmer's Guide

NovoSoft UML API Programmer's Guide

Contents

1  Introduction
2  UML metamodel
    2.1  UML 1.3 metamodel
    2.2  UML 1.3 physical metamodel
    2.3  NOVOSOFT UML metamodel
3  Object model
    3.1  Primitives
    3.2  Enumerations
    3.3  Datatypes
    3.4  Elements
4  Access to attributes and associations
    4.1  Access to attributes
    4.2  Access to association
        4.2.1  Example
        4.2.2  Reference role
        4.2.3  List role
        4.2.4  Bag role
        4.2.5  Role classification principles
    4.3  Reflective API
    4.4  Removing elements
5  Event notification support
    5.1  Types of events
    5.2  Listener interface
    5.3  Factory class
    5.4  Event interpretation
6  Undo/redo support



1  Introduction

The Unified Modeling Language (UML) is a language for specifying, visualizing, constructing, and documenting the artifacts of software systems, as well as for business modeling and other non-software systems. The UML represents a collection of the best engineering practices that have proven successful in the modeling of large and complex systems. The main creator and developer of UML is OMG.

Novosoft UML API is a modern, high-quality Java-based software, supporting user's UML models. It organizes compact storage of model, provides fast and convenient access to its features (attributes and opposite roles in associations). It allows all conceivable kind of work with models, such as generating and serialization of UML models, organizing of access to model elements, modifying, adding and deleting of features. Novosoft UML API supports integrity and reliability of the model.

Novosoft UML API satisfies all of specifications of OMG/UML, it implements all elements of UML : packages, datatypes, classes, their methods and associations. Besides, Novosoft UML API contains many other useful methods not specified by OMG.

Novosoft UML API contains Reflective API. Together with standard access methods, it gives to the developer alternative orthogonal possibilities for accessing to features of UML model elements. Sometimes this significantly simplifies work with UML model.

Novosoft UML API has its own Event Notification Support. Novosoft UML API realizes supporting of undo/redo policy. This is made to simplify the work of a programmer, who needs such possibilities.

Novosoft UML API supports XMI standard. It can read and write model according to XMI format.

Novosoft UML API is widely used inside NOVOSOFT for constructing code generators, mapped various UML models to programming languages: Java, C++, SQL, etc. Also it can be very useful for tool builders, developing facilities of visual work with models of object-oriented program software.



2  UML metamodel

UML is the language for supporting software systems creation, but it does not look like ordinary programming language. It has its own lexicon, but it does not contains rules for construction strictly right sentences. Its semantics can be expressed on English languages or on the language of diagrams.

Novosoft UML API is an implementation of UML metamodel, based of Java language. It consists of interfaces, classes, attributes and methods, which supports notions of UML. There exist a simple correspondence between the names of UML metaobjects, types and roles and the names of NSUML Java types, interfaces, classes and methods.

2.1  UML 1.3 metamodel

UML presents not only tools for describing software artifacts, but UML itself can be expressed with the help of these tools. UML is expressed by UML diagrams of various types and by other facilities (English language, OCL expressions, etc.) Description of UML with the help of UML is called UML metamodel.

The last official version of UML metamodel is UML 1.3 metamodel. Its conceptions and semantic constructions are described in Chapter 2 "UML semantics" of the following document:

OMG Unified Modeling Language Specification, Version 1.3, June 1999

2.2  UML 1.3 physical metamodel

In addition to UML metamodel OMG proposed UML 1.3 physical metamodel, which is more clear for realization and more practical. The specifications of the physical metamodel are described in Chapter 6 "UML XMI DTD" of the above mentioned document "OMG Unified Modeling Language Specification, Version 1.3, June 1999".

UML 1.3 physical metamodel, simplifies UML 1.3 metamodel. It contains only bidirectional associations, it does not contain association classes, and is more closely aligned to XMI. The most part of the Chapter 6 contains the text of the document "UML XMI DTD".

We remind some of the distinctions of UML 1.3 physical metamodel from UML 1.3 metamodel.

Names:

Additions:

Association Classes:

2.3  NOVOSOFT UML metamodel

Novosoft UML metamodel is a base for creation Novosoft UML API . It is reproduced in the Rose format file xmi.mdl, which is contained in delivery package of Novosoft UML API .

Novosoft UML metamodel has minor differences from UML 1.3 physical metamodel. We produced such modification to allow the model to be mapped unambiguously to Java language. We follow UML physical metamodel very closely. There are five exceptions that are introduced to fix problems with metamodel. We:

  1. Renamed partition to partition1 in association contents(ModelElement)/partition(Partition) because of conflict with activityGraph(ModelElement)/partition(Partition).

  2. Renamed collaboration to collaboration1 in association constrainingElement(ModelElement)/collaboration(Collaboration) because of conflict with representedOperation(Operation)/collaboration(Collaboration).

  3. Renamed classifierRole to classifierRole1 in association availableContents(ModelElement)/classifierRole(ClassifierRole) because of conflict with base(Classifier)/classifierRole(ClassifierRole).

  4. Renamed elementImport to elementImport2 in association modelElement(ModelElement)/elementImport(ElementImport) because of conflict with package(Package)/elementImport(ElementImport).

  5. Changed multiplicity of binding end in association binding(Binding)/argument(ModelElement) because in phisical MM an item cannot be argument of more then one template which is wrong because there may be set<int> and map<int,int> and this is not allowed by this metamodel.



3  Object model

Novosoft UML API object model contains objects the following four types: primitives, enumerations, datatypes and elements. They correspond to UML types and metaobjects. The classification is based on UML stereotypes of the objects and the ways of NSUML mapping of these objects to Java constructions.

Primitives have stereotype primitive. Enumerations have stereotype enumeration. Datatypes and elements have no stereotypes. Distinction between datatypes and elements is concluded in two things. First, any datatype is mapped only to one Java class of NSUML , any element is mapped to one Java class and one Java interface. Secondly, datatype classes are created manually, but element classes and interfaces are created with the help of a generator program.

Novosoft UML API contains also auxiliary classes, which provide additional possibilities (events, undo/redo). All auxiliary interfaces and classes are created manually.

3.1  Primitives

Primitives are the UML objects, which have stereotype primitive. There are no special classes NSUML , which correspond to them. NSUML maps such objects to ordinary Java types, according to the following table.

 UML primitives Java types
 Boolean  boolean
 Name  String
 Integer  int
 UnlimitedInteger  int
 LocationReference    String
 Geometry  String

3.2  Enumerations

Enumerations are the UML objects, which have stereotype enumeration. NSUML realizes enumerations as final Java classes with private constructors only. Names of enumerations begins with letter M, prefixed to original UML name. Below all enumeration classes are indicated:

 UML enumerations   NSUML Java classes
 AggregationKind  MAggregationKind
 CallConcurrencyKind  MCallConcurrencyKind
 ChangeableKind  MChangeableKind
 MessageDirectionKind  MMessageDirectionKind
 OperationDirectionKind  MOperationDirectionKind
 OrderingKind  MOrderingKind
 ParameterDirectionKind   MParameterDirectionKind 
 PseudostateKind  MPseudostateKind
 ScopeKind  MScopeKind
 VisibilityKind  MVisibilityKind

During initialization of enumeration classes there are constructed several predefined final static public instances in according with UML specifications. For example, there are 3 available instances of the class MVisibilityKind: MVisibilityKind.PRIVATE, MVisibilityKind.PROTECTED, MVisibilityKind.PUBLIC. In addition, the class contains 3 integer attributes which correspond to the above-mentioned instances (see the following table).

MVisibilityKind
 Predefined Instances  Corresponding class attributes 
 MVisibilityKind.PRIVATE  MVisibilityKind._PRIVATE
 MVisibilityKind.PROTECTED  MVisibilityKind._PROTECTED
 MVisibilityKind.PUBLIC  MVisibilityKind._PUBLIC

The instances are created in according with UML specifications, the corresponding integer class attributes are created for simpler organization of Java switches.

3.3  Datatypes

Datatypes have no stereotypes. Each datatype is mapped exactly to one NSUML Java class. The creation of NSUML names for datatypes is the same as for enumerations. Below all datatype classes are presented.

NSUML datatype classes
 MExpression  MMultiplicity
 MActionExpression  MMultiplicityRange
 MArgListsExpression
 MBooleanExpression
 MIterationExpression
 MMappingExpression
 MProcedureExpression
 MTimeExpression
 MTypeExpression

Class MExpression is the superclass for all the group of Expression classes.

Class MMultiplicity is intended for description of role multiplicities. There are four predefined instances of this class. They correspond to the most widespread types of UML multiplicities:

MMultiplicity
 Predefined Instances  Corresponding UML multiplicities 
 MMultiplicity.M0_1  0..1
 MMultiplicity.M1_1  1
 MMultiplicity.M0_N  *
 MMultiplicity.M1_N  1..n

With the help of this class you can create arbitrary possible UML multiplicitities, invoking the constructor with the string parameter like this "1,3..5,7,9,10..n".

All enumeration and datatype classes are contained in the package ru/novosoft/uml/foundation/datatypes.

3.4  Elements

Elements form the biggest object class. UML elements are structured in packages (Foundation, Core, Behavior, etc.). The typical elements of UML are Package, Classifier, Attribute, Method, Operation, etc. Each element is mapped exactly to one interface and one class of Novosoft UML API . There exists a simple names' correspondence between UML elements and NSUML Java interfaces and classes. See the following table, illustrating names' correspondence.

Names' correspondence
 UML element  NSUML interface  NSUML class 
 Package   MPackage  MPackageImpl
 Classifier   Mclassifier   MClassifierImpl  
 ...   ...  ...

Novosoft UML API contains one important class which is the superclass for all the element Java classes. This is the class MBaseImpl, which implements interface MBase. Many interesting additional possibilities of NSUML elements are realized due to the methods defined in the base class. It is supposed you need not in creation of instances of this class, but you will create instances of its successors. For example, NSUML Java class MClassImpl implementing UML metaclass Class is a successor of the base class. You can create new instances of the metaclass Class, choosing any variant from the following

MBase  cls0 = new MClassImpl();
MClass cls1 = new MClassImpl();

We remark, that the user have to operate with interface references only, and using the following code

MClassImpl cls = new MClassImpl(); // Error! Do not use similar references

is not allowed and can further lead to mistakes.

Note also, that interface MBase contains overridden in all successors method getUMLClassName(), returning real UML name of the metaclass, which is implemented in NSUML . See the following fragment:

public class MStereotypeImpl extends    MGeneralizableElementImpl
                             implements MStereotype
{
  // ------------ code for class Stereotype -----------------
  ...
  public String getUMLClassName()
  {
    return "Stereotype";
  }
  ...
}

So, if you have a reference to interface MBase, you can easy recognize which UML metaobject corresponds to this reference.



4  Access to attributes and associations

Element objects may contain attributes, whose types are primitive, enumeration or datatype. Two element metaclasses can be connected with the help of an association.

Each attribute and role (in association) is mapped to a set of NSUML public user methods of element interfaces (and classes). These methods support access to an attribute or role, possibilities of modifications of their values. There is a simple correspondence between the names of attributes or roles in UML and the names of NSUML methods. This section contains classification of the user methods for accessing to attributes and associations, description of rules for naming of the methods and semantic of these methods.

Attributes are divided on two types: boolean and non-boolean. A set of methods for access to boolean and non-boolean attributes is the same, but there exists a minor difference in naming the methods.

Roles in associations are divided on three types: reference, bag and list roles. Reference roles have multiplicities 1 or 0..1. Roles with other multiplicities belong to bag (unordered multiplicities) or list roles (ordered multiplicities).

Some methods of NSUML element interfaces are public, but designed for internal use only. You are not allowed to invoke them. The names of all of them begin with the word internal.

4.1  Access to attributes

NSUML element class stores attributes as private objects. Access to object attributes is organized with the help of so-called Setter and Getter methods, declared in corresponding interface and implemented in class. Semantic of the methods is the following: Getter is the method, which returns value of the attribute, Setter sets the value of this attribute. For example, UML metaclass Abstraction has the attribute mapping, which belongs to the metaclass MappingExpression.

Metaclass Abstraction

NSUML interface MAbstraction corresponding to the metaclass has the next form:

public interface MAbstraction extends MDependency {
  // generating attributes
  // attribute: mapping
  MMappingExpression getMapping();
  void setMapping(MMappingExpression __arg);
  ...
  // generating associations
  ...
}

Method getMapping() is the Getter method, method setMapping(...) is the Setter method. These methods are implemented in class MAbstractionImpl. The rule for naming of Getter and Setter methods for non-boolean attribute is generally used: name of the Getter is created by capitalization of first letter of attribute name with addition to it the prefix get, name of the Setter is formed in the same manner with addition to the attribute name the prefix set.

A distinction arises for boolean attributes. In this case an interface looks like the following:

public interface MAssociationEnd extends MModelElement {
  // generating attributes
  ...
  // attribute: isNavigable
  boolean isNavigable();
  void setNavigable(boolean __arg);
  ...
}

Here the name of the UML attribute is isNavigable. To form the names for Getter and Setter method NSUML deletes the prefix is from the attribute's name. Then it uses the custom rule for forming name of Setter method, but Getters begins with the prefix is.

4.2  Access to association

Each association in Novosoft UML metamodel is an unnamed association between two elements. An association have two roles (or ends), each role has name and multiplicity. The role attached to an element is the direct role, other role is called the opposite role.

Novosoft UML API has not special objects for association. It maps association to fields and methods of element classes. Primitively, you can consider, that class contains and treats information about the opposite association end of the association to which it belongs.

4.2.1  Example

See the following class diagram.

Project Interaction Scheme

Here your can see two UML metaclasses: Feature, Classifier and an unnamed association between them.

  1. The role with the name owner is the opposite role for metaclass Feature and has the multiplicity 0..1.

  2. The role with the name feature is the opposite role for metaclass Classifier and has the ordered multiplicity *.

  3. The association is read as " any Classifier contains arbitrary number of Features, which are ordered. Any Feature can be attached to one Classifier only".

Role owner is a reference role, role feature is a list role, because it is ordered. NSUML maps this roles to next private fields:

 Additional field  Java Class
 MClassifier _owner;  MFeatureImpl
 List _feature;  MClassifierImpl 

Now, it is provided that Feature contains the information about it owner Classifier in the field _owner, Classifier contains the list of Feature in the field _feature. You have not direct access to these fields, this is provided through Getter, Setter and other methods.

4.2.2  Reference role

Remind, that reference role is the role which have multiplicity 1 or 0..1. On the example of reference role owner, we show which new methods a reference role generates and explain their semantic. See the syntax of the methods for role owner from Java interface, corresponding to metaclass Feature.

public interface MFeature extends MModelElement
{
  ...
  // opposite role: owner this role: feature
  MClassifier getOwner();
  void setOwner(MClassifier __arg);
  ...
}

Analyzing interface you can see that the reference role generates the same Getter and Setter methods, as we saw any attribute generated. The difference is in semantic of Setter method in MFeatureImpl. In the case of attribute access a Setter simply refreshes private field with a new value of the attribute. Now Setter have to support correctness of the model, that is bilateral UML semantic of the association. So, it

4.2.3  List role

List role is the role which have ordered multiplicity different from 1 or 0..1.

Now we consider again our example, the list role feature. This role is opposite to metaclass Classifier. See the code from Java interface, which supports operation with this role.

public interface MClassifier extends MNamespace, MGeneralizableElement
{
...
  // opposite role: feature this role: owner
  List getFeatures();
  void setFeatures(List __arg);
  void addFeature(MFeature __arg);
  void removeFeature(MFeature __arg);
  void addFeature(int __pos, MFeature __arg);
  void removeFeature(int __pos);
  void setFeature(int __pos, MFeature __arg);
  MFeature getFeature(int __pos);
  ...
}

Again you can see the well-known Setter and Getter and additional six methods too. Setter and Getter have semantics different from previous cases.

Semantics of rest six methods are clear from their syntax. They present few functions, that are allowed for the Java interface List.

All methods support semantic of association: the Feature deleted from List _feature changes its owner to null, the Feature added to List _feature changes its owner to reference to the current object of the class MClassifierImpl.

4.2.4  Bag role

Bag role is the role which have unordered multiplicity different from 1 or 0..1.

Now we consider again our example 4.2.1, but suppose that the role feature is not ordered, and change the name of metaclass Classifier to abstract name Something. Then NSUML classes have to contain the following additional fields.

 Additional field  NSUML Java Classes 
 Something _owner;  MFeatureImpl
 Collection _feature;  MSomethingImpl 

See how could be looked Java interface, supporting operations with the bag role feature.

public interface MSomething ...
{
...
  Collection getFeatures();
  void setFeatures(Collection __arg);
  void addFeature(MFeature __arg);
  void removeFeature(MFeature __arg);
  ...
}

We can see only four methods instead of eight ones, which we saw for list role. Their semantic is similar to previous, but interface List is changed to interface Collection.

4.2.5  Role classification principles

Here we specify, which role multiplicities exist in NOVOSOFT UML metamodel, and how NSUML divides them on three types: reference, bag, list roles. See the following table:

Role classification
 NS role names  Base multiplicity  Supported Multiplicities 
 Reference   (0..1)  (0..1), (1)
 Bag   (0..*)  (2..*), (1..*), (0..*), (*)  
 List   (0..*)ordered  all previous ordered

The third column indicate the types of multiplicities existing in NOVOSOFT UML metamodel. It easy to understand that reference, bag, and list roles is a sufficient set for supporting all kinds of role multiplicities. If your association role have complicated multiplicity, for example, (1,4..6,8..*), you can refer it to bag roles, because it is unordered and contain more than one element. On the finish step, after modifying your model, you can simply verify if the collection's (bag's) size keeps within limits (1,4..6,8..*).

In conclusion remember main methods for accessing associations.

If a metaclass has opposite reference role, then corresponding NSUML interface(class) has only two users methods (Getter and Setter), whose names begin from get and set.

If a metaclass has opposite bag role, then corresponding NSUML interface(class) has four users methods, Getter, Setter, Adder and Remover methods, whose names begin from get, set, add, remove.

If a metaclass has opposite list role, then corresponding NSUML interface(class) has eight users methods, two Getter, two Setter, two Adder and two Remover methods, whose names begin from get, set, add, remove.

4.3  Reflective API

This Section explains syntax and semantic of Reflective API methods, builded in Novosoft UML API . These facilities give orthogonal possibilities of invoking the access methods to features (attributes and roles) by attribute's or role's names. Reflective API works slower then the earlier described API, but it significantly reduces the space of method's names, it contains only eight methods, which syntax is the same for all elements. To illustrate this, one can consider any element interface. For example, see an extract from the interface MBase.

public interface MBase {
  ...
  // Reflective API

  public Object reflectiveGetValue(String feature);
  public void reflectiveSetValue(String feature, Object obj);
  public void reflectiveAddValue(String feature, Object obj);
  public void reflectiveRemoveValue(String feature, Object obj);
  public Object reflectiveGetValue(String feature, int pos);
  public void reflectiveSetValue(String feature, int pos, Object obj);
  public void reflectiveAddValue(String feature, int pos, Object obj);
  public void reflectiveRemoveValue(String feature, int pos);
  ...
}

Reflective methods begins with the prefix reflective. These methods are overridden in all successors of NSUML class MBaseImpl. Argument feature is an UML name of attribute, opposite reference, bag or list role. The main sense of reflective methods is the access to features by their names, instead of invocation of explicit Setter, Getter, Adder or Remover methods.

As you can easy to see it, there exists a strict correspondence of reflective methods to the Setter, Getter, Adder or Remover methods, described earlier. First two methods provide access to attribute or opposite reference role. Next two methods are possible for feature, which is the name of an opposite bag role. Last four methods is intended for access to list roles.

To clear the semantic of the methods, consider, for example, the implementation of the method reflectiveGetValue in the class MElementResidenceImpl:

public class MElementResidenceImpl extends MBaseImpl
                                   implements MElementResidence
{
  ...
  // Reflective API

  public Object reflectiveGetValue(String feature)
  {
    if ("visibility".equals(feature))
    {
      return getVisibility();
    }
    if ("resident".equals(feature))
    {
      return getResident();
    }
    if ("implementationLocation".equals(feature))
    {
      return getImplementationLocation();
    }

    return super.reflectiveGetValue(feature);
  }
  ...
}

You can see that the class MElementResidenceImpl owns 3 features, not inherited from superclass. This 3 features: visibility, resident, implementationLocation. The object visibility is an attribute of the metaclass ElementResidence, and resident, implementationLocation are opposite roles of this metaclass. The method reflectiveGetValue() verifies, that input field feature coincides with one of the existing features and invokes corresponding Getter method. If this feature does not belong to features' set of this class, then the method invokes the method with the same name from the superclass. If feature does not belong any of element superclasses, then the base class MBaseImpl throws IllegalArgumentException.

This example has explained only the semantic of the first reflective method. Semantics of other methods can be easily guessed by a user with the help of NSUML Java codes for element classes.

4.4  Removing elements

One important method for any element object is its removing from user's model. Each element class contains the public method remove(), producing this action.

Remark, that element can participate in different associations. So during the removing of element NSUML can invoke many methods of this class and many methods of opposite classes in associations to support correctness of the user's model.



5  Event notification support

This section describes NSUML classes and interfaces, which support event policy.

5.1  Types of events

The events, which can be generated by Novosoft UML API , belong to the class MElementEvent. NSUML classes, inherited MBaseImpl can generate such event, when Setter, Adder or Remover methods for attributes or roles are invoked (including corresponding methods from Reflective API). Besides, event is generated by class remove method 4.4, and by internal methods which restore removed element. Below we give the list of all types of possible events.

public class MElementEvent extends java.util.EventObject
{
  ...
  public final static int ELEMENT_REMOVED = 0;
  public final static int ELEMENT_RECOVERED = 1;
  public final static int ATTRIBUTE_SET = 2;
  public final static int REFERENCE_SET = 3;
  public final static int BAG_ROLE_SET = 4;
  public final static int BAG_ROLE_ADDED = 5;
  public final static int BAG_ROLE_REMOVED = 6;
  public final static int LIST_ROLE_SET = 7;
  public final static int LIST_ROLE_ADDED = 8;
  public final static int LIST_ROLE_ITEM_SET = 9;
  public final static int LIST_ROLE_REMOVED = 10;
  ...
}

Static fields describes types of situations generating events. Their meanings are clear from their names. First event reports, that user invoked method remove for some element. Second event reports, that API recovered previously removed element in the model.

5.2  Listener interface

If a user of NSUML want to listen events, going from model elements, he/she have to

Below we give description of the listener interface.

public interface MElementListener
{
  void propertySet(MElementEvent e);
  void roleAdded(MElementEvent e);
  void roleRemoved(MElementEvent e);
  void listRoleItemSet(MElementEvent e);
  void removed(MElementEvent e);
  void recovered(MElementEvent e);
}

Next example illustrate, how to create class EventTest implementing interface MElementListener (we omit implementation details). Method main() creates new listener instance listener and new model element Class, which registers the listener.

public class EventTest implements MElementListener
{
  public static void main (String args[])
  {
      EventTest listener = new EventTest();
      MClass cls = new MClassImpl();
      cls.addMElementListener(listener);
  }
  ...
}

5.3  Factory class

Public class MFactory manages by the line of events. All model element initially fire events to this class. You need not create instances of this class, only have to use its static methods. It support 3 kind of event policy, see below.

  static int event_policy = EVENT_POLICY_DISABLED;

  public static final int EVENT_POLICY_DISABLED  = 0;
  public static final int EVENT_POLICY_IMMEDIATE = 1;
  public static final int EVENT_POLICY_FLUSH     = 2;

Default state of event_policy is disable, so listeners will not get events by default. To set the event policy you have to invoke its method setEventPolicy(...), for example

   MFactory.setEventPolicy(MFactory.EVENT_POLICY_IMMEDIATE);

Explain the sense of these polices.

5.4  Event interpretation

Previously you can see that the class MElementEvent support 11 types of events, and the interface MElementListener contains 5 methods. The following code shows the correspondence between the events and the methods, which are invoked by this events.
  MElementEvent evt ;
  MElementListener l;
  ...
  switch (evt.getType())
  {
  case MElementEvent.ELEMENT_REMOVED:
    l.removed(evt);
    break;
  case MElementEvent.ELEMENT_RECOVERED:
    l.recovered(evt);
    break;
  case MElementEvent.ATTRIBUTE_SET:
  case MElementEvent.REFERENCE_SET:
  case MElementEvent.BAG_ROLE_SET:
  case MElementEvent.LIST_ROLE_SET:
    l.propertySet(evt);
    break;
  case MElementEvent.BAG_ROLE_ADDED:
  case MElementEvent.LIST_ROLE_ADDED:
    l.roleAdded(evt);
    break;
  case MElementEvent.BAG_ROLE_REMOVED:
  case MElementEvent.LIST_ROLE_REMOVED:
    l.roleRemoved(evt);
    break;
  case MElementEvent.LIST_ROLE_ITEM_SET:
    l.listRoleItemSet(evt);
    break;
  default:
    System.err.println("bad event: "+evt.getType());
  }
  ...



6  Undo/redo support

User interface of NSUML , allowing realization of undo/redo operations, consists of two classes: MCheckPointUndoManager and MCheckPoint. Concept of redo/undo policy is based on the notion of CheckPoint. CheckPoint is a state of the model fixed by NSUML in the moment of method getCheckPoint() invocation. User have to remember these states as instances of the class MCheckPoint. If the user produced some modification of the model, then it can return to the state of the model in CheckPoint with the help of undo or redo methods.

Class MCheckPointUndoManager has the next form:

public class MCheckPointUndoManager
{
  ...
  static int undo_policy = UNDO_POLICY_DISABLED;
  public static final int UNDO_POLICY_DISABLED = 0;
  public static final int UNDO_POLICY_ENABLED = 1;

  public static void setUndoPolicy(int policy)
  ...
  public static MCheckPoint getCheckPoint()
  ...
  public static void undo(MCheckPoint c)
  ...
  public static void redo(MCheckPoint c)
  ...
}

Explain the sense of methods.

Below see a simple example of the program, illustrating work with undo/redo methods.

  MCheckPointUndoManager.setUndoPolicy(MCheckPointUndoManager.UNDO_POLICY_ENABLED);
  MCheckPoint c1 = MCheckPointUndoManager.getCheckPoint();
  MClass cls = new MClassImpl();
  cls.addMElementListener(l);
  cls.setName("Test");
  cls.setName("Test2");
  MAttribute attr = new MAttributeImpl();
  attr.setType(cls);
  attr.setName("test");
  cls.addFeature(attr);
  cls.remove();
  MCheckPoint c4 = MCheckPointUndoManager.getCheckPoint();
  System.out.println("Doing full undo ...");
  MCheckPointUndoManager.undo(c1);
  System.out.println("Doing full redo ...");
  MCheckPointUndoManager.redo(c4);

Following diagram illustrates possible variant of time evolution of some program.

Project Interaction Scheme

The program

Copyright © 1999 by Novosoft Inc. All rights reserved


File translated from TEX by TTH, version 2.25.
On 13 Jan 2000, 11:33.