cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aadamc...@apache.org
Subject svn commit: r491820 [2/2] - in /incubator/cayenne/site/target/articles: ./ 082006/ 082006/cayenne-gef/ 082006/cayenne-gef/images/
Date Tue, 02 Jan 2007 15:53:33 GMT
Added: incubator/cayenne/site/target/articles/082006/cayenne-gef/index.html
URL: http://svn.apache.org/viewvc/incubator/cayenne/site/target/articles/082006/cayenne-gef/index.html?view=auto&rev=491820
==============================================================================
--- incubator/cayenne/site/target/articles/082006/cayenne-gef/index.html (added)
+++ incubator/cayenne/site/target/articles/082006/cayenne-gef/index.html Tue Jan  2 07:53:32 2007
@@ -0,0 +1,567 @@
+<html>
+<head>
+<title>Combining GEF and Cayenne</title>
+<style type="text/css">
+    <!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }-->
+</style>
+</head>
+<body>
+<h1>Combining GEF and Cayenne</h1>
+<p><i>By Marcel Gordon, August 2006</i></p>
+<h2>1	ABSTRACT</h2>
+<p><a href="http://www.eclipse.org/gef">GEF</a> is a powerful <a href="http://www.eclipse.org">Eclipse</a>-based framework for enabling visual interaction with models. <a href="http://incubator.apache.org/cayenne/index.html">Cayenne</a> is an open-source project which provides object-relational mapping, translating from data in a relational database to objects in Java. The two technologies combine fluidly to allow visual editing of data from a database. This article gives a high level explanation of the structure of an application which utilises GEF and demonstrates the use of Cayenne persistent objects as a model for GEF through the development of a visual database editor.</p>
+<h2>2	INTRODUCTION</h2>
+<p>Graphical editing is one of the most intuitive and effective ways to allow users to manipulate data. Diagrams convey a wealth of information in a simple fashion. Simple for the user, in any event; creating such applications can be a time-consuming process for the developer. Enter GEF, the Eclipse project's Graphical Editing Framework. GEF allows the rapid development of visual editors by providing a framework for display and interaction, leaving the developer free to focus on the user experience.</p>
+<p>GEF utilises the well-known Model-View-Controller pattern. Usually the application's model will comprise of simple Java objects, but more sophisticated applications can take advantage of the <a href="http://www.eclipse.org/emf/">Eclipse Modeling Framework (EMF)</a>. However, for many applications the data which underlies the model resides in a database. Translating from the relational structure to Java objects can be burdensome and conceptually difficult.</p>
+<p>
+Cayenne is a well-established open source project which is designed to alleviate that burden. Cayenne allows relational databases to be mapped to objects in Java. The resulting objects can be accessed via single-method queries, and changes to the Java objects can be committed through to the database. These objects are suitable for use as the model for a GEF-based application. Cayenne is presently released under an Apache-like license, and the next release will be under the Apache license itself as the project recently migrated to the Apache Software Foundation's incubator.</p>
+<h2>3	THE DATABASE EDITOR</h2>
+<p>This article explains the design of a simple database editing tool. The editor allows users to run a query and display the results, expand relationships between tables, insert and delete records, alter relationships between records and edit the value of fields.</p>
+<img src="images/ropbrowser.jpg" alt="Database Editor in action" />
+<h3>3.1	Running the editor</h3>
+<p>The source code for the editor can be <a href="https://svn.apache.org/repos/asf/incubator/cayenne/soc/trunk/cayenne-rop">checked out of the repository</a>. The application consists of two Eclipse projects. The client is an Eclipse plugin and the server is a web application. The following are required in order to run the editor:
+<ul><li><a href="http://www.eclipse.org/downloads/">Eclipse 3.2 or later</a></li>
+<li><a href="http://download.eclipse.org/tools/gef/downloads/index.php">GEF 3.2 or later</a></li></ul>
+</p>
+<p>In addition, <a href="http://jettylauncher.sourceforge.net/">Jettylauncher</a> will - in conjunction with <a href="http://www.mortbay.org/jetty/">Jetty</a> - allow the server to be launched directly from Eclipse. All other required libraries are included with the source.</p>
+<p>The database is already configured and is hosted in an embedded instance of <a href="http://db.apache.org/derby/">Derby</a>. Once the server is running, launch the client plugin and change perspective to the 'ROP Browser' perspective. Using the configuration provided, the server will be located at http://localhost:8080/rop-browser. Connect and experiment!</p>
+<h4>3.1.1	Remote or local?</h4>
+<p>Cayenne can be used in either a two or three tier configuration. In the former, the Cayenne library is packaged with the application and the application uses the library to access the database directly. In the latter, a stripped-down version of the library is used to connect to a web application which uses the full library to access the database. The two modes of operation are almost identical from a developer's perspective. The main difference - constituting about two lines of code - is that in the three tier configuration the application must first make a connection to the server.</p>
+<p>As packaged the database editor utilises the three-tier configuration in order to demonstrate some advanced features available in Cayenne (link). Modifying it to access a database directly would be a trivial task. See below, <a href="#connect">Connecting to the server</a>, for more information.</p>
+<h3>3.2	Cayenne basics</h3>
+<p>First, some terminology. Cayenne translates from a relational world to an object-oriented one. In order to explain this translation it is necessary to map some words from each domain.</p>
+<p><table cellpadding="3" cellspacing="0" style="border: solid 1px black;">
+<tr><th style="border: solid 1px black;">Database term</th><th style="border: solid 1px black;">Object-oriented term</th></tr>
+<tr><td style="border: solid 1px black;">Table</td><td style="border: solid 1px black;">Entity</td></tr>
+<tr><td style="border: solid 1px black;">Record</td><td style="border: solid 1px black;">Object</td></tr>
+<tr><td style="border: solid 1px black;">Field</td><td style="border: solid 1px black;">Attribute</td></tr>
+<tr><td style="border: solid 1px black;">Foreign key constraint</td><td style="border: solid 1px black;">Relationship</td></tr>
+</table></p>
+<p>Cayenne provides a GUI tool known as the <a href="http://cwiki.apache.org/CAYDOC/modeler-guide.html">Modeler</a> in order to facilitate the mapping of a database. If the database already exists, the Modeler can generate the mapping automatically. Alternatively, the Modeler can be used to design and create a database and the associated mapping. Either way, upon completion of the mapping process Cayenne has the metadata which it needs. This is used to generate Java classes for use in the application, and the developer never need deal with the database directly again.</p>
+<p>Cayenne stores its mapping metadata in XML files. The database editor includes metadata files for a simple database involving three entities - Artist, Painting, and Gallery - commonly used in the Cayenne documentation. As we will see below, you can use the database editor with a different database simply by replacing these files with your own.</p>
+<img src="images/entity.gif" align="left" alt="Entity type hierarchy" />
+<h4>3.2.1	Cayenne's persistent classes</h4>
+<p>Cayenne generates persistent classes in pairs. For each entity, two persistent classes are generated: _<i>Entity </i>and <i>Entity</i>. The relationship between the two is shown in Figure 1. _<i>Entity </i>contains all of the generated code which Cayenne uses to handle database access. <i>Entity </i>is provided to allow the developer to add methods to the class as required. When the classes are regenerated, _<i>Entity </i>will be overwritten while <i>Entity </i>will not. <i>PersistentObject </i>provides Cayenne's shared persistence functionality.</p>
+<p>As noted above, the persistent classes generated by Cayenne could correspond directly to visual elements in an application. This is the most straight-forward approach, but it has a significant limitation: knowledge of the attributes of the entities has to be programmed into the application. For instance, if an entity <i>User </i>with an attribute <i>username </i>is to be displayed, the view has to know about the getter method and the controller must know about the setter method (<i>getUsername </i>and <i>setUsername </i>respectively). This can be very inconvenient: where multiple entities are used there will be multiple instances of code that is essentially the same; and if the database is modified (say <i>username </i>becomes <i>name</i>) the application code will have to be updated.</p>
+<p>For some applications, this will not be a concern. However, for most projects a more flexible, more generic approach is preferable.</p>
+<img src="images/entity-super.gif" align="right" alt="Entity type hierarchy with custom super-class" />
+<h4>3.2.2	Custom super-classes</h4>
+<p>Cayenne allows the developer to specify a super-class for all of the persistent classes which it generates. Figure 2 shows the type hierarchy after the introduction of a custom super-class. This allows the developer to specify behaviour to be shared between all Cayenne classes. Adding a custom super-class gives the opportunity to access attributes in a generic way. Cayenne has mechanisms for accessing attributes using the name of the entity and the name of the attribute. Shown below is a method from <i>AbstractObject</i> which accesses a named attribute.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#3f5fbf">/**</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;Accesses&nbsp;a&nbsp;property&nbsp;of&nbsp;the&nbsp;object,&nbsp;returning&nbsp;the&nbsp;result&nbsp;as&nbsp;a&nbsp;String</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;</font><font color="#7f9fbf">@param&nbsp;</font><font color="#3f5fbf">id&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;property</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;</font><font color="#7f9fbf">@return&nbsp;</font><font color="#3f5fbf">the&nbsp;value&nbsp;of&nbsp;the&nbsp;property&nbsp;as&nbsp;a&nbsp;String</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*/</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">String&nbsp;getPropertyValue</font><font color="#000000">(</font><font color="#000000">Object&nbsp;id</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if</b></font><font color="#000000">(</font><font color="#000000">objectContext&nbsp;!=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;prepare&nbsp;the&nbsp;object&nbsp;for&nbsp;access</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">objectContext.prepareForAccess</font><font color="#000000">(</font><font color="#000000">this,&nbsp;id.toString</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">EntityResolver&nbsp;resolver&nbsp;=&nbsp;objectContext.getEntityResolver</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ClassDescriptor&nbsp;descriptor&nbsp;=&nbsp;resolver.getClassDescriptor</font><font color="#000000">(</font><font color="#000000">getName</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Object&nbsp;value&nbsp;=&nbsp;descriptor.getProperty</font><font color="#000000">(</font><font color="#000000">id.toString</font><font color="#000000">())</font><font color="#000000">.readProperty</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">16</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>Using this approach, the view and controller no longer need to know anything about the individual persistent classes. It is sufficient to know that they all inherit from the same super-class. For the database editor, this means that the persistent classes can be substituted without having to modify or rebuild the application. To run the database editor with a different database, simply replace the Cayenne configuration files with your own and include generated classes for your entities in the appropriate directories of the server and the client. The only requirement is that you must specify <i>AbstractObject</i> as the super-class for your persistent objects.</p>
+<p>For some applications, this will be a sufficient degree of abstraction as it allows all Cayenne entities to be treated the same way by the other parts of the application. If the entities are to be directly represented in the GEF diagram by components then the use of a super-class allows one view part to represent different entities and to be agnostic to changes in the underlying database.</p>
+<p>However, in many cases a visual component will want to offer more than just the data from the database. In that case - and the database editor is such a case - the persistent classes will be wrapped inside other classes. With the basics of Cayenne under our belt, it is time to move on to using Cayenne with GEF.</p>
+<h3>3.3	GEF basics</h3>
+<p>There are a number of excellent introductory articles on GEF available,  and it is recommended that the reader peruse those if they are new to the topic.<a name="bn1" href="#fn1">[1]</a> This article will focus on the design of the various elements employed by GEF in the context of this application, and the use of Cayenne with GEF.</p>
+<h3>3.4	Designing the model</h3>
+<p>GEF uses a factory to map different classes in the model to components on the screen. Not every class in the model need be represented by a visual component, and some components may represent more than one class in the model. Classes in the model which are represented on the screen are referred to hereafter as 'visual model elements', whilst others are referred to as 'business model elements'.<a name="bn1" href="#fn1">[2]</a> In some applications there may be no separation between business and visual model element; in the database editor the separation is relatively clean.</p>
+<h4>3.4.1	Business model elements</h4>
+<img src="images/entity-editor.gif" align="right" alt="Type hierarchy for the database editor model" />
+<p>Although in some cases the model can be designed without regard to its visual representation, the database editor is not one of these cases. The first instinct in creating a database editor is that a visual element will represent an entity from the database. That way each record will appear on the screen as a separate component and can be manipulated by the user. All Cayenne persistent objects are descended from the same custom super-class - in the database editor, <i>AbstractObject </i>- so that would be the main visual model element.</p>
+<p>However, displaying the contents of a database has some subtle challenges. Sometimes one entity will be linked to only one other entity; but in other cases it will be linked to a number of other entities, or none at all (a null value). If a gallery has two thousand paintings, how do we display all those paintings in the diagram, let alone show the relationship between the paintings and the gallery? It is clearly not feasible to put two thousand components in front of the user.</p>
+<p>This complexity means that it is necessary to introduce more sophistication to the model. The final type hierarchy is shown in Figure 3. <i>CollectionModelElement </i>manages a collection of persistent objects - each of which extends <i>AbstractObject </i>- and <i>SingleModelElement </i>manages a single persistent object.</p>
+<p>Why have a separate class in the model to manage single persistent objects? Isn't an <i>AbstractObject </i>itself just a single persistent object? One reason is that Java doesn't allow for multiple inheritance. <i>AbstractObject </i>must extend <i>PersistentObject</i>, and in order to share functionality common to parts of the model which are represented visually, <i>SingleModelElement </i>must extend <i>ModelElement</i>. Even without this limitation, it is still a good idea to separate the two as one deals with business logic (storing and retrieving data) while the other is visual.</p>
+<img src="images/visual-model-elements.png" align="right" alt="Single and collection model elements in the display" />
+<h4>3.4.2	Visual model elements</h4>
+<p><i>ModelElement </i>is the base class for visual model elements which can be interacted with (as distinct from connections, discussed below). <i>ModelElement </i>offers three different groups of functionalities. First, it implements the <i>org.eclipse.ui.views.properties.IPropertySource</i> interface, allowing users to edit its properties through the standard Eclipse Properties view. Second, it can fire events when a property is changed. Finally, it manages non-database data - view data - such as size, location, name and connections with other elements. It makes sense to abstract this functionality to a super-class.</p>
+<p>Enabling the Properties view is relatively simple for <i>ModelElement</i>. The <i>AbstractObject </i> treats its attributes - whatever they may happen to be - as properties. Calls to <i>getPropertyValue </i>, <i>setPropertyValue </i>, <i>isPropertySet </i>and <i>resetPropertyValue </i>are delegated to the AbstractObject methods of the same name. The method for retrieving property descriptors, which dictate the way in which a property is to be edited, is only slightly more complicated: it caches the results of a call to its equivalent <i>AbstractObject</i> method. This is done because generating the property descriptors involves some work, and need not be repeated every time the <i>ModelElement </i>is selected.</p>
+<img src="images/properties.png" align="left" alt="Properties view in action" />
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">IPropertyDescriptor</font><font color="#000000">[]&nbsp;</font><font color="#000000">getPropertyDescriptors</font><font color="#000000">()&nbsp;{</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">objectContext&nbsp;!=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">EntityResolver&nbsp;entityResolver&nbsp;=&nbsp;getObjectContext</font><font color="#000000">()</font><font color="#000000">.getEntityResolver</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ObjEntity&nbsp;entity&nbsp;=&nbsp;entityResolver.getObjEntity</font><font color="#000000">(</font><font color="#000000">getName</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Iterator&nbsp;attributes&nbsp;=&nbsp;entity.getAttributes</font><font color="#000000">()</font><font color="#000000">.iterator</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">IPropertyDescriptor</font><font color="#000000">[]&nbsp;</font><font color="#000000">properties&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">IPropertyDescriptor</font><font color="#000000">[</font><font color="#000000">entity.getAttributes</font><font color="#000000">()</font><font color="#000000">.size</font><font color="#000000">()]</font><font color="#000000">;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>int&nbsp;</b></font><font color="#000000">i&nbsp;=&nbsp;</font><font color="#990000">0</font><font color="#000000">;</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>while&nbsp;</b></font><font color="#000000">(</font><font color="#000000">attributes.hasNext</font><font color="#000000">())&nbsp;{</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ObjAttribute&nbsp;attribute&nbsp;=&nbsp;</font><font color="#000000">(</font><font color="#000000">ObjAttribute</font><font color="#000000">)&nbsp;</font><font color="#000000">attributes.next</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">properties</font><font color="#000000">[</font><font color="#000000">i++</font><font color="#000000">]&nbsp;</font><font color="#000000">=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">TextPropertyDescriptor</font><font color="#000000">(</font><font color="#000000">attribute.getName</font><font color="#000000">()</font><font color="#000000">,&nbsp;attribute.getName</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">properties;</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">IPropertyDescriptor</font><font color="#000000">[</font><font color="#990000">0</font><font color="#000000">]</font><font color="#000000">;</font><br />
+<font color="#808080">15</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<h4>3.4.3	Other visual model elements</h4>
+<p>GEF requires some other elements in the model. They are visual model elements in the sense described above - they are represented by components on the screen. In some applications they may also handle some business logic, but in the database editor they do not.</p>
+<img src="images/connections.png" align="left" alt="Single and collection model elements in the display" />
+<p>In the database editor connections between elements represent relationships between different objects. If a painting belongs to an artist, the components which represent the painting and the artist on screen should be connected. Connections are represented in the model by the classes <i>Connection</i>, <i>RelationshipConnection </i>and <i>MemberConnection</i>. The first is abstract. The second represents a relationship between two database records - a foreign key constraint between tables.</p>
+<p>The third is a consequence of the use of collections to manage more than one persistent object. While a persistent object may appear more than one collection, it should only appear once as a single element. Otherwise our representation of the database would not be accurate: we would be showing more than one copy of an object when in reality there is only one, linked to by a number of different objects. The solution is to let a number of collections point to the same single element and indicate that it is one of the objects which they manage. That is, there should be a connection between a <i>SingleModelElement </i>and a <i>CollectionModelElement </i>which indicates that the object contained in the single element is also contained in the collection. This is represented in the model as a <i>MemberConnection</i>.</p>
+<p>Finally, every GEF program must have a diagram. The diagram is the part of the model used to manage all the other elements which make up the model. Other visual elements are added to and removed from the diagram in order to appear in the display. In the database editor this role is fulfilled by <i>ElementDiagram</i>.</p>
+<h3>3.5	Adding the controller</h3>
+<p>The majority of the work involved in developing a GEF-based application comes in writing the controller component. The controller is made up of two main elements: parts, which broker requests from the user and respond to changes in the model; and commands, bite-sized changes to the model representing one interaction. In addition, policies are used to handle the mapping of requests (provided to parts by GEF to indicate user interactions) to commands.</p>
+<h4>3.5.1	Parts</h4>
+<p>Generally, the hierarchy of part classes will reflect the hierarchy of visual model elements. In the database editor the <i>ElementEditPart </i>corresponds to <i>ModelElement</i>, and <i>SingleEditPart </i>and <i>CollectionEditPart </i>correspond to <i>SingleModelElement </i>and <i>CollectionModelElement </i>respectively. The actually mapping of the model elements to their parts is done by <i>ElementEditPartFactory</i>, which takes a model class as input and returns a part.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">EditPart&nbsp;createEditPart</font><font color="#000000">(</font><font color="#000000">EditPart&nbsp;context,&nbsp;Object&nbsp;modelElement</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;get&nbsp;EditPart&nbsp;for&nbsp;model&nbsp;element</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">EditPart&nbsp;part&nbsp;=&nbsp;getPartForElement</font><font color="#000000">(</font><font color="#000000">modelElement</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;store&nbsp;model&nbsp;element&nbsp;in&nbsp;EditPart</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">part.setModel</font><font color="#000000">(</font><font color="#000000">modelElement</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;</b></font><font color="#000000">part;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#000000">}</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">09</font>&nbsp;<font color="#3f5fbf">/**</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;Maps&nbsp;an&nbsp;object&nbsp;to&nbsp;an&nbsp;EditPart.&nbsp;</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;</font><font color="#7f9fbf">@throws&nbsp;</font><font color="#3f5fbf">RuntimeException&nbsp;if&nbsp;no&nbsp;match&nbsp;was&nbsp;found&nbsp;(programming&nbsp;error)</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*/</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#7f0055"><b>private&nbsp;</b></font><font color="#000000">EditPart&nbsp;getPartForElement</font><font color="#000000">(</font><font color="#000000">Object&nbsp;object</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">object&nbsp;</font><font color="#7f0055"><b>instanceof&nbsp;</b></font><font color="#000000">ElementDiagram</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">ElementDiagramEditPart</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">16</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">17</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">object&nbsp;</font><font color="#7f0055"><b>instanceof&nbsp;</b></font><font color="#000000">CollectionModelElement</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">18</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">CollectionEditPart</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">19</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">20</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">object&nbsp;</font><font color="#7f0055"><b>instanceof&nbsp;</b></font><font color="#000000">SingleModelElement</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">21</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">SingleEditPart</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">22</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">23</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">object&nbsp;</font><font color="#7f0055"><b>instanceof&nbsp;</b></font><font color="#000000">Connection</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">24</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">ConnectionEditPart</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">25</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">26</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>throw&nbsp;new&nbsp;</b></font><font color="#000000">RuntimeException</font><font color="#000000">(</font><br />
+<font color="#808080">27</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#2a00ff">&#34;Can't&nbsp;create&nbsp;part&nbsp;for&nbsp;model&nbsp;element:&nbsp;&#34;</font><br />
+<font color="#808080">28</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">+&nbsp;</font><font color="#000000">((</font><font color="#000000">object&nbsp;!=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)&nbsp;</font><font color="#000000">?&nbsp;object.getClass</font><font color="#000000">()</font><font color="#000000">.getName</font><font color="#000000">()&nbsp;</font><font color="#000000">:&nbsp;</font><font color="#2a00ff">&#34;null&#34;</font><font color="#000000">)</font><br />
+<font color="#808080">29</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">30</font>&nbsp;<font color="#000000">}</font></code>
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>Parts are the heart of the controller. Each part listens for property change notification from its underlying model so that it can update the view. This is done through the Java Beans property change mechanism. Each persistent object inherits a <i>java.beans.PropertyChangeSupport</i> from the common super-class <i>AbstractObject</i>. When a change is made to the object - for instance by writing a property or deleting the object - a property change event is fired using the <i>PropertyChangeSupport</i>. These events are received by the <i>ModelElement </i>which contains the persistent object, but they are not handled there. They are merely fired onwards - the visual model element recognises that its data has changed, and therefore it fires a property change event of its own to notify its part.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">AbstractObject&nbsp;</font><font color="#7f0055"><b>extends&nbsp;</b></font><font color="#000000">PersistentObject&nbsp;</font><font color="#000000">{</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f5fbf">/**&nbsp;Property&nbsp;indicating&nbsp;that&nbsp;the&nbsp;object&nbsp;has&nbsp;been&nbsp;modified&nbsp;*/</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;static&nbsp;final&nbsp;</b></font><font color="#000000">String&nbsp;PROP_MODIFIED&nbsp;=&nbsp;</font><font color="#2a00ff">&#34;AbstractObject.Modified&#34;</font><font color="#000000">;</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f5fbf">/**&nbsp;Delegate&nbsp;used&nbsp;to&nbsp;implemenent&nbsp;property-change-support.&nbsp;*/</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>private&nbsp;transient&nbsp;</b></font><font color="#000000">PropertyChangeSupport&nbsp;pcsDelegate&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">PropertyChangeSupport</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">16</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>protected&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">firePropertyChange</font><font color="#000000">(</font><font color="#000000">String&nbsp;property,&nbsp;Object&nbsp;oldValue,&nbsp;Object&nbsp;newValue</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">17</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">pcsDelegate.hasListeners</font><font color="#000000">(</font><font color="#000000">property</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">18</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">pcsDelegate.firePropertyChange</font><font color="#000000">(</font><font color="#000000">property,&nbsp;oldValue,&nbsp;newValue</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">19</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">20</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">21</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">22</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">23</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">24</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">setPropertyValue</font><font color="#000000">(</font><font color="#000000">Object&nbsp;id,&nbsp;Object&nbsp;value</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">25</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">26</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">firePropertyChange</font><font color="#000000">(</font><font color="#000000">PROP_MODIFIED,&nbsp;null,&nbsp;</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">27</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">28</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">29</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">30</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>Each part is produced by the factory when a visual model element is added to the diagram. The first thing that the part does is to add itself as a property change listener for events from its model. As well as passing on events caused by changes in persistent objects, the <i>ModelElement </i>fires events of its own. This occurs when connections are added or removed or data that the model element contains - data such as the size and location of the element and the number of records it contains - are altered. In this way, changes to both the business elements and the visual elements of the model are monitored in the part.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#3f5fbf">/**</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;</font><font color="#7f9fbf">@see&nbsp;</font><font color="#3f5fbf">java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*/</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">propertyChange</font><font color="#000000">(</font><font color="#000000">PropertyChangeEvent&nbsp;evt</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">String&nbsp;prop&nbsp;=&nbsp;evt.getPropertyName</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">ModelElement.PROP_BOUNDS.equals</font><font color="#000000">(</font><font color="#000000">prop</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Figure&nbsp;tableFigure&nbsp;=&nbsp;</font><font color="#000000">(</font><font color="#000000">Figure</font><font color="#000000">)&nbsp;</font><font color="#000000">getFigure</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">Rectangle&nbsp;constraint&nbsp;=&nbsp;</font><font color="#000000">(</font><font color="#000000">Rectangle</font><font color="#000000">)&nbsp;</font><font color="#000000">evt.getNewValue</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">ElementDiagramEditPart&nbsp;parent&nbsp;=&nbsp;</font><font color="#000000">(</font><font color="#000000">ElementDiagramEditPart</font><font color="#000000">)&nbsp;</font><font color="#000000">getParent</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">parent.setLayoutConstraint</font><font color="#000000">(</font><font color="#000000">this,&nbsp;tableFigure,&nbsp;constraint</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>else&nbsp;if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">ModelElement.PROP_SOURCE_CONN.equals</font><font color="#000000">(</font><font color="#000000">prop</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">refreshSourceConnections</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;in&nbsp;case&nbsp;relationship&nbsp;button&nbsp;states&nbsp;have&nbsp;changed</font><br />
+<font color="#808080">16</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">((</font><font color="#000000">ElementFigure</font><font color="#000000">)&nbsp;</font><font color="#000000">getFigure</font><font color="#000000">())</font><font color="#000000">.refresh</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">17</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">18</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>else&nbsp;if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">ModelElement.PROP_TARGET_CONN.equals</font><font color="#000000">(</font><font color="#000000">prop</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">19</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">refreshTargetConnections</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">20</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">21</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>else&nbsp;</b></font><font color="#000000">{</font><br />
+<font color="#808080">22</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;for&nbsp;any&nbsp;other&nbsp;kind&nbsp;of&nbsp;property&nbsp;change,&nbsp;refresh&nbsp;the&nbsp;figure</font><br />
+<font color="#808080">23</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">Display.getCurrent</font><font color="#000000">()&nbsp;</font><font color="#000000">!=&nbsp;</font><font color="#7f0055"><b>null</b></font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">24</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">((</font><font color="#000000">ElementFigure</font><font color="#000000">)&nbsp;</font><font color="#000000">getFigure</font><font color="#000000">())</font><font color="#000000">.refresh</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">25</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">26</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">27</font>&nbsp;<font color="#000000">}</font></code>
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>Parts also handle requests prompted by user interactions, executing commands which will change the model. Whereas the mechanism for notification of changes to the model is chosen by the developer, the request system is mandated by GEF. When the user interacts with the diagram, standard requests are issued to the parts which are involved in the interaction. Each part must be capable of responding to the request with a command. For some commands this can involve some processing in order to determine what ought to be done; but for all the commands in the database editor a simple mapping is all that is required. Additionally, because all commands can be applied to both <i>CollectionModelElement</i> and <i>SingleModelElement</i> via their respective parts, the mapping is handled in the part super-class <i>ElementEditPart</i>.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#646464">@Override</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">performRequest</font><font color="#000000">(</font><font color="#000000">Request&nbsp;request</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">getViewer</font><font color="#000000">()</font><font color="#000000">.getEditDomain</font><font color="#000000">()</font><font color="#000000">.getCommandStack</font><font color="#000000">()</font><font color="#000000">.execute</font><font color="#000000">(</font><font color="#000000">getCommand</font><font color="#000000">(</font><font color="#000000">request</font><font color="#000000">))</font><font color="#000000">;</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#000000">}</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">06</font>&nbsp;<font color="#646464">@Override</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#000000">Command&nbsp;getCommand</font><font color="#000000">(</font><font color="#000000">Request&nbsp;request</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">request.getType</font><font color="#000000">()</font><font color="#000000">.equals</font><font color="#000000">(</font><font color="#000000">HideAction.HIDE_REQUEST</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">HideElementCommand</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">.getModelCast</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">request.getType</font><font color="#000000">()</font><font color="#000000">.equals</font><font color="#000000">(</font><font color="#000000">InsertAction.INSERT_REQUEST</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">ObjectInsertCommand</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">.getModelCast</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">request.getType</font><font color="#000000">()</font><font color="#000000">.equals</font><font color="#000000">(</font><font color="#000000">RemoveAction.REMOVE_REQUEST</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">RemoveObjectCommand</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">.getModelCast</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">16</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">17</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">request.getType</font><font color="#000000">()</font><font color="#000000">.equals</font><font color="#000000">(</font><font color="#000000">ExistingObjectRequest.EXISTING_REQUEST</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">18</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">ExistingObjectCommand</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">.getModelCast</font><font color="#000000">()</font><font color="#000000">,&nbsp;</font><font color="#000000">((</font><font color="#000000">ExistingObjectRequest</font><font color="#000000">)&nbsp;</font><font color="#000000">request</font><font color="#000000">)</font><font color="#000000">.getSelectedObject</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">19</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">20</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">request.getType</font><font color="#000000">()</font><font color="#000000">.equals</font><font color="#000000">(</font><font color="#000000">DeleteAction.DELETE_REQUEST</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">21</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">DeleteObjectCommand</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">.getModelCast</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">22</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">23</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">request.getType</font><font color="#000000">()</font><font color="#000000">.equals</font><font color="#000000">(</font><font color="#000000">SetNameElementRequest.SET_NAME_REQUEST</font><font color="#000000">))&nbsp;{</font><br />
+<font color="#808080">24</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;new&nbsp;</b></font><font color="#000000">SetNameElementCommand</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">.getModelCast</font><font color="#000000">()</font><font color="#000000">,&nbsp;</font><font color="#000000">((</font><font color="#000000">SetNameElementRequest</font><font color="#000000">)&nbsp;</font><font color="#000000">request</font><font color="#000000">)</font><font color="#000000">.getName</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">25</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">26</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>return&nbsp;super</b></font><font color="#000000">.getCommand</font><font color="#000000">(</font><font color="#000000">request</font><font color="#000000">)</font><font color="#000000">;&nbsp;</font><br />
+<font color="#808080">27</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>In addition, there are parts representing connections (<i>ConnectionEditPart</i>) and the diagram (<i>ElementDiagramEditPart</i>). The diagram part handles some important global interactions, such as adding and removing elements and changing the layout, and it is notified of changes in the underlying diagram model using the property change mechanism described above. The connection part merely specifies the way that it is to be represented in the display, distinguishing between <i>RelationshipConnection </i>and <i>MemberConnection </i>through the use of a dashed line in the latter.</p>
+<h4>3.5.2	Policies</h4>
+<p>Policies are used to generalise the translation of a request to a command, so that the same mapping can be applied to numerous parts. Even where this is not needed, policies are also a clean way of handling standard requests generated by GEF. Policies are installed in parts, and requests which are not handled by the part are passed on to its policies. Installing policies saves each part from having to separate out standard requests - they can simply be left to fall through to the appropriate policy.</p>
+<p>The database editor uses policies sparingly. This is because most interaction in the editor is handled through the context menu (discussed below). Policies are used for open/double-click (<i>CollectionSelectionPolicy</i>) and direct edit/single-click (<i>CollectionDirectEditPolicy</i>) on <i>CollectionEditPart </i>in order to allow scrolling through records and 'popping out' of individual objects from the collection. Drag and drop is enabled for <i>ElementEditPart </i>through the use of a layout edit policy (<i>ElementLayoutEditPolicy</i>). Policies are also used on <i>ElementEditPart </i>to allow elements to be moved when manual layout is selected (<i>ElementXYLayoutEditPolicy</i>), and to ensure selection handles appear in automatic layout mode (<i>SelectionHandlesEditPolicy</i>). </p>
+<h4>3.5.3	Commands</h4>
+<p>All changes to the model should be encapsulated in commands. This encourages reuse of code between parts and reduces the complexity of the part. In addition, GEF commands can be undone and redone, enhancing the user experience with little development overhead. Commands need not worry about the view - changes to the model will result in notification of the part, which in turn will update the view.</p>
+<p>Commands should generally be executed using the command stack, in order to ensure that undo and redo are available. The command stack is available through the <i>EditDomain</i>, which is itself accessible through the <i>EditPartViewer</i>. It is also available from within actions which are sensitive to the selection (see below).</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#3f5fbf">/**</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;Handles&nbsp;action&nbsp;events&nbsp;from&nbsp;its&nbsp;figure's&nbsp;relationship&nbsp;buttons,</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;expanding&nbsp;or&nbsp;contracting&nbsp;a&nbsp;relationship.</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*/</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">actionPerformed</font><font color="#000000">(</font><font color="#000000">ActionEvent&nbsp;event</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">ButtonModel&nbsp;buttonModel&nbsp;=&nbsp;</font><font color="#000000">((</font><font color="#000000">Button</font><font color="#000000">)&nbsp;</font><font color="#000000">event.getSource</font><font color="#000000">())</font><font color="#000000">.getModel</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">buttonModel.isSelected</font><font color="#000000">())&nbsp;{</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">getViewer</font><font color="#000000">()</font><font color="#000000">.getEditDomain</font><font color="#000000">()</font><font color="#000000">.getCommandStack</font><font color="#000000">()</font><font color="#000000">.execute</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ExpandRelationshipCommand</font><font color="#000000">(</font><font color="#000000">getModelCast</font><font color="#000000">()</font><font color="#000000">,&nbsp;</font><font color="#000000">(</font><font color="#000000">Relationship</font><font color="#000000">)&nbsp;</font><font color="#000000">buttonModel.getUserData</font><font color="#000000">()))</font><font color="#000000">;</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>else&nbsp;</b></font><font color="#000000">{</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">getViewer</font><font color="#000000">()</font><font color="#000000">.getEditDomain</font><font color="#000000">()</font><font color="#000000">.getCommandStack</font><font color="#000000">()</font><font color="#000000">.execute</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ContractRelationshipCommand</font><font color="#000000">(</font><font color="#000000">getRelationshipConnection</font><font color="#000000">((</font><font color="#000000">Relationship</font><font color="#000000">)&nbsp;</font><font color="#000000">buttonModel.getUserData</font><font color="#000000">())))</font><font color="#000000">;</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>Some thought needs to be invested into the best manner in which to implement undo and redo, and what information needs to be stored in order to do so. Sometimes a command can involve the execution of another command. This is one case where the developer may wish to avoid using the command stack, instead executing the command directly, as it is not desired that the command be undoable separately from its parent. In this case, the sub-command needs to be stored in order to be able to be undone if the parent command is undone.</p>
+<h3>3.6	Implementing the view</h3>
+<h4>3.6.1	Figures</h4>
+<p>Each part specifies a figure which will represent it on the canvas. GEF utilises Eclipse's Draw2D plugin for its canvas, meaning that figures are defined using Draw2D's drawing capabilities. The figures used in the database editor extend <i>org.eclipse.draw2d.Figure</i>, but it is possible to instead implement the <i>IFigure </i>interface from the same package.</p>
+<p>Most of the figures used in the database editor are based on the CompartmentFigure explained in Daniel Lee's Eclipse Corner article.<a href="#fn3" name="bn3">[3]</a>. As the figures for <i>CollectionEditPart </i>and <i>SingleEditPart </i>- <i>CollectionFigure </i>and <i>SingleFigure </i>respectively - are largely the same, they share a common base class: <i>ElementFigure</i>.</p>
+<img src="images/collection-buttons.png" align="right" alt="Buttons on the CollectionFigure" />
+<p>Draw2D provides a simple and powerful API for producing geometric diagrams. This covers most of what is required in a visual editor. However, introducing custom interaction can be troublesome because it doesn't fit neatly within GEF's framework. Buttons have to be wired in by the user. They could utilise the request process, but given that they have to know which part to send the request to in any case it is just as simple to call a function in the part which carries out the desired action. The lesson is - introduce custom interaction as little as possible!</p>
+<p>The database editor requires buttons in two places. The first is the expand relationship button found in <i>SingleFigure</i>. This notifies <i>SingleEditPart </i>that the button has been pressed, resulting in the expansion of a relationship (using a command - see code above).</p>
+<img src="images/single-buttons.png" align="right" alt="Buttons on the SingleFigure" />
+<p>The second is a two stage process. Each attribute of the persistent object being displayed in a <i>CollectionFigure </i>is represented by a button. When the button is pressed, a list of buttons corresponding to the values of that attribute in all of the objects in the collection is displayed below the button. This is a purely visual change, and so it happens in the figure. When one of the buttons in the list is pressed, <i>CollectionEditPart </i>is notified and the model is told that the selected object ought to be displayed.</p>
+<h4>3.6.2	Layout</h4>
+<p>Layout is a complicated business. The layout policy determines whether parts in the diagram can be moved and resized. The layout can also arrange the parts automatically, whether based on some custom calculation or a best-effort graph layout algorithm.</p>
+<p>The database editor utilises a slightly modified version of the layout manager found in Phil Zoio's Schema Editor example.  It provides the ability to toggle between automated layout, using a graph layout algorithm built into Draw2D, and manual layout, where the user can move parts around the canvas. Since the Schema Editor example was published the graph layout algorithm can now handle graphs which are not fully connected, removing some complexity for the developer.</p>
+<p>The mechanism for toggling between the layouts is not complicated. The <i>ElementDiagramEditPart </i>is assigned <i>DelegatingLayoutManager </i>to manage its layout. That class delegates layout responsibility to either an automatic layout class (<i>GraphLayoutManager</i>) or a manual layout class (<i>GraphXYLayout</i>), depending on the value of an attribute in <i>ElementDiagram</i>. Automatic layout constructs a graph from the diagram, utilises <i>org.eclipse.draw2d.graph.DirectedGraphLayout</i> to calculate the preferred layout and then applies the results to the diagram. Manual layout queries each element of the model to find out where it should be located. When the layout mode is changed, the <i>DelegatingLayoutManager </i>sets the diagram's layout policy to allow or disallow the manual movement of parts on the canvas.</p>
+<h3>3.7	Other components</h3>
+<p>The discussion above is restricted to GEF and its modus operandi. The database editor features a number of components which are involved in presenting GEF in a usable manner: an Eclipse view; the select query wizard; the editor and its entourage of perspective, plugin and input; and the plugin configuration files. These will be explained only as they relate to GEF.</p>
+<h4>3.7.1	The editor</h4>
+<p>The editor extends <i>org.eclipse.gef.ui.parts.GraphicalEditor</i> in order to provide an editor without a palette of tools. This is in spite of dire warnings not to do so in the API, as extending this class (and its relatives with tool palettes) seems to be the custom in all of the examples available for GEF. The main GEF-related task which the editor has to deal with is configuring the <i>org.eclipse.gef.GraphicalViewer</i> which it contains.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#3f5fbf">/**</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;Configure&nbsp;the&nbsp;graphical&nbsp;viewer&nbsp;before&nbsp;it&nbsp;receives&nbsp;contents.</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;</font><font color="#7f9fbf">@see&nbsp;</font><font color="#3f5fbf">org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer()</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*/</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#646464">@Override</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#7f0055"><b>protected&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">configureGraphicalViewer</font><font color="#000000">()&nbsp;{</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>super</b></font><font color="#000000">.configureGraphicalViewer</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">GraphicalViewer&nbsp;viewer&nbsp;=&nbsp;getGraphicalViewer</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">viewer.setEditPartFactory</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ElementEditPartFactory</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">viewer.setRootEditPart</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ScalableFreeformRootEditPart</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">viewer.setKeyHandler</font><font color="#000000">(</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">GraphicalViewerKeyHandler</font><font color="#000000">(</font><font color="#000000">viewer</font><font color="#000000">))</font><font color="#000000">;</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;configure&nbsp;the&nbsp;context&nbsp;menu&nbsp;provider</font><br />
+<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">ContextMenuProvider&nbsp;cmProvider&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ObjectEditorContextMenuProvider</font><font color="#000000">(</font><font color="#000000">viewer,&nbsp;getActionRegistry</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">16</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">viewer.setContextMenu</font><font color="#000000">(</font><font color="#000000">cmProvider</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">17</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">getSite</font><font color="#000000">()</font><font color="#000000">.registerContextMenu</font><font color="#000000">(</font><font color="#000000">cmProvider,&nbsp;viewer</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">18</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<h4>3.7.2	Actions and the context menu</h4>
+<p>In order to make actions available in the context menu, they need to be created and added to the action registry. Actions which are sensitive to the current selection on the canvas should also be registered as selection actions. This registration process happens in <i>ObjectEditor</i>.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#646464">@Override</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#7f0055"><b>protected&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">createActions</font><font color="#000000">()&nbsp;{</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>super</b></font><font color="#000000">.createActions</font><font color="#000000">()</font><font color="#000000">;</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">IAction&nbsp;action&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">HideAction</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">getActionRegistry</font><font color="#000000">()</font><font color="#000000">.registerAction</font><font color="#000000">(</font><font color="#000000">action</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">getSelectionActions</font><font color="#000000">()</font><font color="#000000">.add</font><font color="#000000">(</font><font color="#000000">action.getId</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">action&nbsp;=&nbsp;</font><font color="#7f0055"><b>new&nbsp;</b></font><font color="#000000">ToggleLayoutAction</font><font color="#000000">(</font><font color="#7f0055"><b>this</b></font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">getActionRegistry</font><font color="#000000">()</font><font color="#000000">.registerAction</font><font color="#000000">(</font><font color="#000000">action</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>The next step is to implement an <i>org.eclipse.gef.ContextMenuProvider</i> to be added to the editor's <i>GraphicalViewer</i> when the editor is configured. As the context menu is built each time that the right mouse button is used in the diagram, the provider should check each action to see if it is enabled before adding it to the menu. In the database editor the <i>ObjectEditorContextMenuProvider </i>fills this role.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#3f5fbf">/**</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;Creates&nbsp;context&nbsp;menu&nbsp;items&nbsp;for&nbsp;the&nbsp;editor.</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*&nbsp;</font><font color="#7f9fbf">@see&nbsp;</font><font color="#3f5fbf">org.eclipse.gef.ContextMenuProvider#buildContextMenu(org.eclipse.jface.action.IMenuManager)</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;</font><font color="#3f5fbf">*/</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#646464">@Override</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#7f0055"><b>public&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">buildContextMenu</font><font color="#000000">(</font><font color="#000000">IMenuManager&nbsp;menu</font><font color="#000000">)&nbsp;{</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;Add&nbsp;standard&nbsp;action&nbsp;groups&nbsp;to&nbsp;the&nbsp;menu</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">GEFActionConstants.addStandardActionGroups</font><font color="#000000">(</font><font color="#000000">menu</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#3f7f5f">//&nbsp;Add&nbsp;actions&nbsp;to&nbsp;the&nbsp;menu</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">menu.appendToGroup</font><font color="#000000">(</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">GEFActionConstants.GROUP_UNDO,&nbsp;</font><font color="#3f7f5f">//&nbsp;target&nbsp;group&nbsp;id</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">getAction</font><font color="#000000">(</font><font color="#000000">ActionFactory.UNDO.getId</font><font color="#000000">()))</font><font color="#000000">;&nbsp;</font><font color="#3f7f5f">//&nbsp;action&nbsp;to&nbsp;add</font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">15</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">16</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">IAction&nbsp;action&nbsp;=&nbsp;getAction</font><font color="#000000">(</font><font color="#000000">HideAction.ID</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">17</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>if&nbsp;</b></font><font color="#000000">(</font><font color="#000000">action.isEnabled</font><font color="#000000">())&nbsp;{</font><br />
+<font color="#808080">18</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">menu.appendToGroup</font><font color="#000000">(</font><font color="#000000">GEFActionConstants.GROUP_EDIT,&nbsp;action</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">19</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">20</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">21</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">22</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>To make standard workbench actions - such as redo, undo and delete - available to the user, an <i>org.eclipse.gef.ui.actions.ActionBarContributor</i> must be specified in the plugin file. In the database editor, the <i>ROPActionBarContributor </i>enables the undo, redo and print actions. This also ensures that the standard keyboard shortcuts are available for these actions.</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#7f0055"><b>public&nbsp;class&nbsp;</b></font><font color="#000000">ROPActionBarContributor&nbsp;</font><font color="#7f0055"><b>extends&nbsp;</b></font><font color="#000000">ActionBarContributor&nbsp;</font><font color="#000000">{</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#646464">@Override</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#7f0055"><b>protected&nbsp;</b></font><font color="#7f0055"><b>void&nbsp;</b></font><font color="#000000">buildActions</font><font color="#000000">()&nbsp;{</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">IWorkbenchAction&nbsp;undo&nbsp;=&nbsp;ActionFactory.UNDO.create</font><font color="#000000">(</font><font color="#000000">getPage</font><font color="#000000">()</font><font color="#000000">.getWorkbenchWindow</font><font color="#000000">())</font><font color="#000000">;</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">addRetargetAction</font><font color="#000000">((</font><font color="#000000">RetargetAction</font><font color="#000000">)&nbsp;</font><font color="#000000">undo</font><font color="#000000">)</font><font color="#000000">;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">}</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff"></font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">...</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#000000">}</font></code>
+    
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>Finally, the actions themselves need to be implemented. Actions which depend upon the current selection should extend <i>org.eclipse.gef.ui.actions.SelectionAction</i>; other actions can extend <i>org.eclipse.jface.action.Action</i>. Actions need to indicate whether they are enabled (for the context menu provider) and carry out an action when they are selected. For actions descended from <i>SelectionAction</i>, enablement usually depends upon whether all selected parts are of the right type and in an acceptable state, and execution usually involves sending a request to each selected part and executing the command which is returned via the command stack.</p>
+<h3>3.8	Three tier Cayenne</h3>
+<p>As mentioned earlier, Cayenne classically operates in a two tier configuration. A three tier mode - referred to as remote object persistence or <a href="http://cwiki.apache.org/CAYDOC/remote-object-persistence-guide.html">ROP</a> - has recently been introduced to the project. A three tier setup was chosen for this application in order to demonstrate some of the more advanced features of Cayenne. This section describes how to set up Cayenne in a three tier configuration and then explores the more advanced features which it offers.</p>
+<h4>3.8.1	Setup</h4>
+<img src="images/server-structure.png" alt="Server project structure" align="left" />
+<p>In three tier mode Cayenne runs as a single-servlet web application: a servlet connects to the database and brokers requests from multiple clients. The servlet can be hosted in any number of containers, but a very convenient way to develop a three tier Cayenne application is using Jetty and JettyLauncher. This combination allows the server to be launched and debugged inside Eclipse. The required structure for a JettyLauncher project is detailed on the <a href="http://jettylauncher.sourceforge.net/docs/quickstart.html">JettyLauncher site</a> and demonstrated in the database editor.</p>
+<p>Setting up the servlet is fairly simple. The required libraries are detailed in the Cayenne documentation (be sure to include the library for connecting to your chosen database), as is the servlet specification:</p>
+<div align="left" class="java">
+<table border="0" cellpadding="3" cellspacing="0" bgcolor="#ffffff">
+   <tr>
+  <!-- start source code -->
+   <td nowrap="nowrap" valign="top" align="left">
+    <code>
+<font color="#808080">01</font>&nbsp;<font color="#000000">&lt;web-app&gt;</font><br />
+<font color="#808080">02</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;!--&nbsp;on&nbsp;session&nbsp;timeout&nbsp;server-side&nbsp;DataContext&nbsp;will&nbsp;be&nbsp;deallocated</font><br />
+<font color="#808080">03</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">shared&nbsp;DataChannels&nbsp;will&nbsp;be&nbsp;deallocated&nbsp;when&nbsp;no&nbsp;sessions&nbsp;are&nbsp;using&nbsp;them&nbsp;</font><br />
+<font color="#808080">04</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">--&gt;</font><br />
+<font color="#808080">05</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;session-config&gt;</font><br />
+<font color="#808080">06</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">&lt;session-timeout&gt;60&lt;/session-timeout&gt;</font><br />
+<font color="#808080">07</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;/session-config&gt;</font><br />
+<font color="#808080">08</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><br />
+<font color="#808080">09</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;!--&nbsp;Deploying&nbsp;Cayenne&nbsp;distributed&nbsp;service&nbsp;using&nbsp;Hessian&nbsp;OPP&nbsp;transport&nbsp;--&gt;</font><br />
+<font color="#808080">10</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;servlet&gt;</font><br />
+<font color="#808080">11</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">&lt;servlet-name&gt;rop-browser&lt;/servlet-name&gt;</font><br />
+<font color="#808080">12</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">&lt;servlet-class&gt;org.objectstyle.cayenne.remote.hessian.service.HessianServlet&lt;/servlet-class&gt;</font><br />
+<font color="#808080">13</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;/servlet&gt;</font><br />
+<font color="#808080">14</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;servlet-mapping&gt;</font><br />
+<font color="#808080">15</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">&lt;servlet-name&gt;rop-browser&lt;/servlet-name&gt;</font><br />
+<font color="#808080">16</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#000000">&lt;url-pattern&gt;/rop-browser&lt;/url-pattern&gt;</font><br />
+<font color="#808080">17</font>&nbsp;<font color="#ffffff">&nbsp;&nbsp;</font><font color="#000000">&lt;/servlet-mapping&gt;</font><br />
+<font color="#808080">18</font>&nbsp;<font color="#000000">&lt;/web-app&gt;</font></code>
+   </td>
+  <!-- end source code -->
+   </tr>
+</table>
+</div>
+<p>The map files generated from the Modeler need to be included in the project in a source folder to ensure they are available to the servlet. The servlet also needs to contain the client and server classes generated from Cayenne Modeler. These can be copied from the client project, but linking the Eclipse project for the client application as a dependency is better as it avoids having two copies of the client classes.</p>
+<h4><a name="connect">3.8.2	Connecting to the server</a></h4>
+<p>In terms of programming, using Cayenne in a three tier configuration is almost identical to using it in classic two tier mode; only one minor change is required. Whereas a traditional Cayenne application requests a <i>DataContext </i>via a local method of that class, a three tier application creates a connection to the server, wraps the connection in a <i>DataChannel </i>and then draws a <i>CayenneContext </i>from the channel. However, as both <i>CayenneContext </i>and <i>DataContext </i>implement the <i>ObjectContext </i>interface, the developer can avoid dependency on either a two or three tier configuration by treating the context as an <i>ObjectContext</i>. In both cases Cayenne looks after the actual database connection based on the settings contained in its metadata files.</p>
+<div align="left" class="java">

[... 73 lines stripped ...]


Mime
View raw message