The Components

 

In this subsection we start using the CDE editor to create a project for our banking application and to add the Customer and Account classes to it.

  1. Launch the CDE editor by executing the batch file directly in the CDE root directory or by clicking on a shortcut you created during installation.

  2. In the File menu, select the New Project... item to open a file dialog. Go to the application directory (i.e., demos/tour), write tour.cdp in the file name text box, and click New. Actually, any file name will do, but we suggest to use the same name as the application directory with extension cdp (coordination project). Notice that in the left pane of the CDE editor a new project has appeared. Moreover, in the bottom pane, a message appears, stating that the project file has been created. The component subdirectory is also created, as you can check with Windows Explorer.

  3. In the File menu, select the Add->Add Component... item. A file dialog appears with the current directory being the last one that was visited, in this case the application directory. Go to the src/Bank subdirectory. Select the Account.java file. On the left pane, the project root node has now a handle. Click on it (or double-click on the node name) to see the child node for the Account component.

  4. Expand the Account node, again either by clicking on the handle or double-clicking on the name. There is one child node for the operations and another one for the file (with icon ). Double-click on the file node. A new tabbed window appears on the right pane, containing the Account source file.Double-click on the gray thick line on the left margin of the text window to show the line numbers. You can drag the line left and right to change the width, and double-clicking it again will make the line numbers disappear.

  5. Expand the operations node. There will be one child for each method implemented by the class, except for constructors. The icon in front of the method name indicates whether this method will be coordinated () or not (). If the method is a query, i.e., if it does not change the state of the object, then a question mark is part of the icon. Right-click on the ownedBy method node and select the Query item from the pop-up menu. The question mark will show up.

  6. Repeat steps 3 to 5 for the Customer.java file in the src/Bank subdirectory and set the owns method as a query.

At this moment, the CDE editor window should look as shown next, with two components in the project pane on the left, two file edition windows in the right pane, and messages about the loading process in the bottom pane.

Notice from the messages that the two class files have been saved into the component directory. If you look into the source directory (e.g., using the Windows Explorer or selecting File->Open in CDE to browse directories and then cancelling the dialog) you will notice that the Account.java file has been renamed into Account.java.original, and similarly for the Customer class. The reason for this is that the CDE has to adapt the component classes in order for them to work with contracts. For that purpose, the CDE will change the original Java files and put the result in the generation directory, together with the compiled contracts. The files in the generation and source directories make up the application, and therefore there cannot be two files with the same name in those directories: hence, all files in the source directory that implement classes under coordination must be renamed.

Before moving on to the definition of the contracts, it is necessary to understand what the components do, and more importantly, what they don't do. The most important issue is that components should be as simple as possible, providing only the core functionality that one does not foresee to be changed in the future. Putting it differently, all issues that are related to the way components interact with each other should not be hard-wired into the component.

The Customer class contains only personal data (for this toy example, just a unique identifier and the name), a list of the accounts she or he owns, and methods to create and query Customer objects.Notice that the toString() method has been redefined to return the customer's name. This is important to have the animator display meaningful object identifiers, as we will see in the Testing Contracts section.

The Account class is less simple. Each account has a number, one or more owners, and a current balance. There are methods to query these attributes and to change the owners. To change the balance one must use the deposit and withdraw methods, which take as arguments the amount and the customer that is performing the operation. This is important to support evolution of the system: contracts will be able to intercept the calls to these methods and will use the second argument to check if any conditions apply to that particular customer-account interaction. For the sake of the example, we assume there is a business rule that is unlikely to change and therefore has been incorporated into the account's behaviour: a customer can only withdraw money from the accounts she or he owns. On the other hand, a customer may deposit money in any account. Moreover, one can only withdraw or deposit positive amounts.

Whenever one of these conditions is violated, an exception is raised. The exceptions are implemented by class AccountException and interface AccountExceptionTypes. They are not added to the project for different reasons: there will be no contracts on exception objects in our example, and contracts are never defined over interfaces. To see the definition of the class and the interface it is not necessary to use an external editor or Java IDE; it is possible to view and edit any text file with the CDE, even if it is not part of any application with coordination contracts.

  1. There are three ways to open a file:

    1. Choose Open File... from the File menu.

    2. Press Ctrl-O.

    3. Click on the open file icon ( ) in the tool bar.

  2. Choose the file using the file dialog that appears. In this case, files AccountException.java and AccountExceptionTypes.java are in the src/Bank subdirectory.

  3. When you are done with viewing the files, close them. There are four ways to close the file in the current edit window:

    1. Choose Close from the File menu.

    2. Press Ctrl-W.

    3. Click on the close file icon ( ) in the tool bar.

    4. Right-click on the edit window and choose Close from the pop-up menu.

Returning to the Account class, notice that besides a restriction on the customer's identity, no further business rules are imposed on withdrawals; in particular, any amount may be withdrawn. This may be surprising at first, but such conditions may be quite complex (depending on the type of the account, on its current balance, on the assessment the bank makes about the customer's liability, etc.) and, more importantly, may evolve (due to new legislation, new financial products introduced by the bank, time-limited promotions, etc.). It is therefore more adequate to have a contract for each condition and then to plug such contracts in and out of the system, as evolution requires.

Whenever a component is added to a project, by default, all methods can be coordinated and all methods starting with "get" are queries. CDE also knows that toString is a query method. You can change all those settings, but in the usual case you will only state which other methods are also queries, because CDE cannot find that out by itself. You should leave all methods as coordinated, except those for which it really doesn't make sense to coordinate them. You should not set as coordinated only those methods that are used in the triggers of the current contract rules, because as contracts and rules are added, modified, and deleted during system evolution, so must the component method settings be updated, and this would lead to regenerating the component each time a method setting is changed. The idea is thus to set the coordinated settings only once. There is no run-time performance penalty if a method that is indicated to be coordinated is not actually in the trigger of any contract rule. For our example, although we will only coordinate the withdraw method of the Account class, we indicate that all methods of both components may be subject to coordination.

Now that we have stated which methods of which classes of this application can be subject to coordination, we have to generate the actual Java code that will make it possible for the contracts to impose their interaction rules on the components. Since we are going to use the animator to watch the execution of components and contracts, we first have to tell the CDE that the generated code should include notifications to the animator whenever a method is called, so that it may be properly visualized in the animator.

  1. Open the project options dialog. There are two ways:

    1. Select Project->Project Options... .

    2. Right-click on the project root node and choose Project Options... from the pop-up menu.

  2. Click on the second tab, named Generation.

  3. Click on the check-box to activate the "Generate Animation Events" option. Click OK

Now we are ready to generate the Java files that adapt the components for coordination.

  1. Right-click on the Account node and choose Generate from the pop-up menu. There will be a new child node "Generated Files" and the message pane will indicate that the adapted Account component has been successfully generated into the generation directory.

  2. Expand the "Generated Files" node. There are three files. You can double-click on them to view the code that the CDE has produced. Don't forget to close them afterwards. Do not change the content of those files!

  3. Repeat for the Customer component.

We have now set up the components that will be subject to coordination and can proceed to write the actual contracts.

Top    CDE Documentation Home    Next