Changeset 3715


Ignore:
Timestamp:
Sep 11, 2007, 1:13:16 PM (14 years ago)
Author:
Nicklas Nordborg
Message:

References #746 and #554. Added new new UML file for MagicDraw? 12.5. Updated documentation about
how to use MagicDraw?. Transfered some of the old data layer documentation to docbook.

Location:
trunk
Files:
10 added
1 deleted
6 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/doc/src/docbook/developerdoc/api_overview.xml

    r3675 r3715  
    158158  </sect1>
    159159
    160   <sect1 id="api_overview.data_api">
     160  <sect1 id="api_overview.data_api" chunked="1">
    161161    <title>The database schema and the Data Layer API</title>
    162162
    163163    <para>
    164       This documentation is only available in the old format.
    165       See <ulink url="http://base.thep.lu.se/chrome/site/doc/development/overview/data/index.html"
     164      This section gives an overview of the entire data layer API.
     165      The figure below show how different modules relate to each other.
     166    </para>
     167   
     168    <note>
     169      All information has not yet been transfered from the old documentation.
     170      The old documentation is available at
     171      <ulink url="http://base.thep.lu.se/chrome/site/doc/development/overview/data/index.html"
    166172        >http://base.thep.lu.se/chrome/site/doc/development/overview/data/index.html</ulink>
    167     </para>
    168    
     173    </note>
     174   
     175    <figure id="data_api.figures.overview">
     176      <title>Data layer overview</title>
     177      <screenshot>
     178        <mediaobject>
     179          <imageobject>
     180            <imagedata
     181              fileref="figures/uml/datalayer.overview.png" format="PNG" />
     182          </imageobject>
     183        </mediaobject>
     184      </screenshot>
     185    </figure>
     186
     187    <sect2 id="data_api.basic">
     188      <title>Basic classes and interfaces</title>
     189     
     190      <para>
     191        This document contains information about the basic classes and interfaces in this package.
     192        They are important since all data-layer classes must inherit from one of the already
     193        existing abstract base classes or implement one or more of the
     194        existing interfaces. They contain code that is common to all classes,
     195        for example implementations of the <methodname>equals()</methodname>
     196        and <methodname>hashCode()</methodname> methods or how to link with the owner of an
     197        item.
     198      </para>
     199     
     200      <sect3 id="data_api.basic.uml">
     201        <title>UML diagram</title>
     202       
     203        <figure id="data_api.figures.basic">
     204          <title>Basic classes and interfaces</title>
     205          <screenshot>
     206            <mediaobject>
     207              <imageobject>
     208                <imagedata
     209                  fileref="figures/uml/datalayer.basic.png" format="PNG" />
     210              </imageobject>
     211            </mediaobject>
     212          </screenshot>
     213        </figure>
     214      </sect3>
     215     
     216      <sect3 id="data_api.basic.classes">
     217        <title>Classes</title>
     218       
     219        <variablelist>
     220        <varlistentry>
     221          <term><classname>BasicData</classname></term>
     222          <listitem>
     223            <para>
     224            The root class. It overrides the <methodname>equals()</methodname>,
     225            <methodname>hashCode()</methodname> and <methodname>toString()</methodname> methods
     226            from the <classname>Object</classname> class. It also defines the
     227            <varname>id</varname> and <varname>version</varname> properties.
     228            All data layer classes must inherit from this class or one of it's subclasses.
     229            </para>
     230          </listitem>
     231        </varlistentry>
     232       
     233        <varlistentry>
     234          <term><classname>OwnedData</classname></term>
     235          <listitem>
     236            <para>
     237            Extends the <classname>BasicData</classname> class and adds
     238            an <varname>owner</varname> property. The owner is a required link to a
     239            <classname>UserData</classname> object, representing the user that
     240            is the owner of the item.
     241            </para>
     242          </listitem>
     243        </varlistentry>
     244
     245        <varlistentry>
     246          <term><classname>SharedData</classname></term>
     247          <listitem>
     248            <para>
     249            Extends the <classname>OwnedData</classname> class and adds
     250            properties (<varname>itemKey</varname> and <varname>projectKey</varname>)
     251            that holds access permission information for an item.
     252            Access permissions are held in <classname>ItemKeyData</classname> and/or
     253            <classname>ProjectKeyData</classname> objects. These objects only exists if
     254            the item has been shared.
     255            </para>
     256          </listitem>
     257        </varlistentry>
     258
     259        <varlistentry>
     260          <term><classname>CommonData</classname></term>
     261          <listitem>
     262            <para>
     263            This is a convenience class for items that extends the <classname>SharedData</classname>
     264            class and implements the <interfacename>NameableData</interfacename> and
     265            <interfacename>RemoveableData</interfacename> interfaces. This is one of
     266            the most common situations.
     267            </para>
     268          </listitem>
     269        </varlistentry>
     270
     271        <varlistentry>
     272          <term><classname>AnnotatedData</classname></term>
     273          <listitem>
     274            <para>
     275            This is a convenience class for items that can be annotated.
     276            Annotations are held in <classname>AnnotationSetData</classname> objects.
     277            The annotation set only exists if annotations has been created for the item.
     278            </para>
     279          </listitem>
     280        </varlistentry>
     281        </variablelist>
     282       
     283      </sect3>
     284     
     285      <sect3 id="data_api.basic.interfaces">
     286        <title>Interfaces</title>
     287       
     288        <variablelist>
     289        <varlistentry>
     290          <term><classname>IdentifiableData</classname></term>
     291          <listitem>
     292            <para>
     293            All items are identifiable, which means that they have a unique <varname>id</varname>.
     294            The id is unique for all items of a specific type (ie. class). The id is number
     295            that is automatically generated by the database and has no other meaning
     296            outside of the application. The <varname>version</varname> property is used for
     297            detecting and preventing concurrent modifications to an item.
     298            </para>
     299          </listitem>
     300        </varlistentry>
     301       
     302        <varlistentry>
     303          <term><classname>OwnableData</classname></term>
     304          <listitem>
     305            <para>
     306            An ownable item is an item which has an owner. The owner is represented as a
     307            required link to a <classname>UserData</classname> object.
     308            </para>
     309          </listitem>
     310        </varlistentry>       
     311
     312        <varlistentry>
     313          <term><classname>ShareableData</classname></term>
     314          <listitem>
     315            <para>
     316            A shareable item is an item which can be shared to other users, groups or projects.
     317            Access permissions are held in <classname>ItemKeyData</classname> and/or
     318            <classname>ProjectKeyData</classname> objects.
     319            </para>
     320          </listitem>
     321        </varlistentry>
     322             
     323        <varlistentry>
     324          <term><classname>NameableData</classname></term>
     325          <listitem>
     326            <para>
     327            A nameable item is an item that has a name (required) and a description
     328            (optional). The name doesn't have to be unique, except in a few special
     329            cases (for example, the name of a file).
     330            </para>
     331          </listitem>
     332        </varlistentry>
     333       
     334        <varlistentry>
     335          <term><classname>RemovableData</classname></term>
     336          <listitem>
     337            <para>
     338            A removable item is an item that can be flagged as removed. This doesn't
     339            remove the information about the item from the database, but can be used by
     340            client applications to hide items that the user is not interested in.
     341            A trashcan function can be used to either restore or permanently
     342            remove items that has the flag set.
     343            </para>
     344          </listitem>
     345        </varlistentry>
     346               
     347        <varlistentry>
     348          <term><classname>SystemData</classname></term>
     349          <listitem>
     350            <para>
     351            A system item is an item which has an additional id in the form of string. A system id
     352            is required when we need to make sure that we can get a specific item without
     353            knowing the numeric id. Example of such items are the root user and the everyone group.
     354            A system id is generally constructed like:
     355            <constant>net.sf.basedb.core.User.ROOT</constant>. The system id:s are defined in the
     356            core layer by each item class.
     357            </para>
     358          </listitem>
     359        </varlistentry>
     360
     361        <varlistentry>
     362          <term><classname>DiskConsumableData</classname></term>
     363          <listitem>
     364            <para>
     365            This interface is used by items which occupies a lot of disk space and
     366            should be part of the quota system, for example files. The required
     367            <classname>DiskUsageData</classname> contains information about the size,
     368            location, owner etc. of the item.
     369            </para>
     370          </listitem>
     371        </varlistentry>
     372       
     373        <varlistentry>
     374          <term><classname>AnnotatableData</classname></term>
     375          <listitem>
     376            <para>
     377            This interface is used by items which can be annotated. Annotations are name/value
     378            pairs that are attached as extra information to an item. All annotations are
     379            contained in an <classname>AnnotationSetData</classname> object.
     380            </para>
     381          </listitem>
     382        </varlistentry>
     383       
     384        <varlistentry>
     385          <term><classname>ExtendableData</classname></term>
     386          <listitem>
     387            <para>
     388            This interface is used by items which can have extra administrator-defined
     389            columns. The functionality is similar to annotations. It is not as flexible,
     390            since it is a global configuration, but has better performance. BASE will
     391            generate extra database columns to store the data in the tables for items that
     392            can be extended.
     393            </para>
     394          </listitem>
     395        </varlistentry>
     396       
     397        <varlistentry>
     398          <term><classname>BatchableData</classname></term>
     399          <listitem>
     400            <para>
     401            This interface is a tagging interface which is used by items that needs batch
     402            functionality in the core.
     403            </para>
     404          </listitem>
     405        </varlistentry>
     406        </variablelist>
     407
     408      </sect3>
     409    </sect2>
     410   
     411    <sect2 id="data_api.authentication">
     412      <title>User authentication and access control</title>
     413     
     414      <para>
     415         This section gives an overview of user authentication and
     416         how groups, roles and projects are used for access control
     417         to items.
     418      </para>
     419     
     420      <sect3 id="data_api.authentication.uml">
     421        <title>UML diagram</title>
     422       
     423        <figure id="data_api.figures.authentication">
     424          <title>User authentication and access control</title>
     425          <screenshot>
     426            <mediaobject>
     427              <imageobject>
     428                <imagedata
     429                  fileref="figures/uml/datalayer.authentication.png" format="PNG" />
     430              </imageobject>
     431            </mediaobject>
     432          </screenshot>
     433        </figure>
     434      </sect3>
     435     
     436      <sect3 id="data_api.authentication.users">
     437        <title>Users and passwords</title>     
     438     
     439        <para>
     440          The <classname>UserData</classname> class holds information about users.
     441          We keep the passwords in a separate table and use proxies to avoid loading
     442          password data each time a user is loaded to minimize security risks. It is
     443          only if the password needs to be changed that the <classname>PasswordData</classname>
     444          object is loaded. The one-to-one mapping between user and password is controlled
     445          by the password class, but a cascade attribute on the user class makes sure
     446          that the password is deleted when a user is deleted.
     447        </para>
     448      </sect3>
     449
     450      <sect3 id="data_api.authentication.groups">
     451        <title>Groups, roles and projects</title>     
     452     
     453        <para>
     454          The <classname>GroupData</classname>, <classname>RoleData</classname> and
     455          <classname>ProjectData</classname> classes holds information about groups, roles
     456          and projects respectively. A user may be a member of any number of groups,
     457          roles and/or projects. The membership in a project comes with an attached
     458          permission values. This is the highest permission the user has in the
     459          project. No matter what permission an item has been shared with the
     460          user will not get higher permission. Groups may be members of other groups and
     461          also in projects.
     462        </para>
     463       
     464      </sect3>
     465     
     466      <sect3 id="data_api.authentication.keys">
     467        <title>Keys</title>     
     468     
     469        <para>
     470          The <classname>KeyData</classname> class and it's subclasses
     471          <classname>ItemKeyData</classname>, <classname>ProjectKeyData</classname> and
     472          <classname>RoleKeyData</classname>, are used to store information about access
     473          permissions to items. To get permission to manipulate an item a user must have
     474          access to a key giving that permission. There are three types of keys:
     475        </para>
     476       
     477        <variablelist>
     478        <varlistentry>
     479          <term><classname>ItemKey</classname></term>
     480          <listitem>
     481            <para>
     482            Is used to give a user or group access to a specific item. The item
     483            must be a <interfacename>ShareableData</interfacename> item.
     484            The permissions are usually set be the owner of the item. Once created an
     485            item key cannot be changed. This allows the core to reuse a key if the
     486            permissions match exactly, ie. for a given set of users/groups/permissions
     487            there can be only one item key object.
     488            </para>
     489          </listitem>
     490        </varlistentry>
     491
     492        <varlistentry>
     493          <term><classname>ProjectKey</classname></term>
     494          <listitem>
     495            <para>
     496            Is used to give members of a project access to a specific item. The item
     497            must be a <interfacename>ShareableData</interfacename> item. Once created a
     498            project key cannot be changed. This allows the core to reuse a key if the
     499            permissions match exactly, ie. for a given set of projects/permissions
     500            there can be only one project key object.
     501            </para>
     502          </listitem>
     503        </varlistentry>
     504
     505        <varlistentry>
     506          <term><classname>RoleKey</classname></term>
     507          <listitem>
     508            <para>
     509            Is used to give a user access to all items of a specific type, ie.
     510            <constant>READ</constant> all <constant>SAMPLES</constant>. The installation
     511            will make sure that there already exists a role key for each type of item, and
     512            it is not possible to add new or delete existing keys. Unlike the other two types
     513            this key can be modified.
     514            </para>
     515           
     516            <para>
     517            A role key is also used to assign permissions to plug-ins. If a plug-in has
     518            been specified to use permissions the default is to deny everything.
     519            The mapping to the role key is used to grant permissions to the plugin.
     520            The <varname>granted</varname> value gives the plugin access to all items
     521            of the related item type regardless of if the user that is running the plug-in has the
     522            permission or not. The <varname>denied</varname> values denies access to all
     523            items of the related item type even if the logged in user has the permission.
     524            Permissions that are not granted nor denied are checked against the
     525            logged in users regular permissions. Permissions to items that are
     526            not linked are always denied.
     527            </para>
     528          </listitem>
     529        </varlistentry>
     530        </variablelist>
     531       
     532      </sect3>
     533
     534      <sect3 id="data_api.authentication.permissions">
     535        <title>Permissions</title>
     536       
     537        <para>
     538          The <varname>permission</varname> property appearing in many classes is an
     539          integer values describing the permission:
     540        </para>
     541       
     542        <informaltable>
     543        <tgroup cols="2">
     544          <colspec colname="value" />
     545          <colspec colname="permission" />
     546          <thead>
     547            <row>
     548              <entry>Value</entry>
     549              <entry>Permission</entry>
     550            </row>
     551          </thead>
     552          <tbody>
     553            <row>
     554              <entry>1</entry>
     555              <entry>Read</entry>
     556            </row>
     557            <row>
     558              <entry>3</entry>
     559              <entry>Use</entry>
     560            </row>
     561            <row>
     562              <entry>7</entry>
     563              <entry>Restricted write</entry>
     564            </row>
     565            <row>
     566              <entry>15</entry>
     567              <entry>Write</entry>
     568            </row>
     569            <row>
     570              <entry>31</entry>
     571              <entry>Delete</entry>
     572            </row>
     573            <row>
     574              <entry>47 (=32+15)</entry>
     575              <entry>Set owner</entry>
     576            </row>
     577            <row>
     578              <entry>79 (=64+15)</entry>
     579              <entry>Set permissions</entry>
     580            </row>
     581            <row>
     582              <entry>128</entry>
     583              <entry>Create</entry>
     584            </row>
     585            <row>
     586              <entry>256</entry>
     587              <entry>Denied</entry>
     588            </row>
     589          </tbody>
     590        </tgroup>
     591        </informaltable>
     592       
     593        <para>
     594          The values are constructed so that
     595          <constant>READ</constant> -&gt;
     596          <constant>USE</constant> -&gt;
     597          <constant>RESTRICTED_WRITE</constant> -&gt;
     598          <constant>WRITE</constant> -&gt;
     599          <constant>DELETE</constant>
     600          are chained in the sense that a higher permission always implies the lower permissions
     601          also. The <constant>SET_OWNER</constant> and <constant>SET_PERMISSION</constant>
     602          both implies <constant>WRITE</constant> permission. The <constant>DENIED</constant>
     603          permission is only valid for role keys, and if specified it overrides all
     604          other permissions.               
     605        </para>
     606       
     607        <para>
     608          When combining permission for a single item the permission codes for the different
     609          paths are OR-ed together. For example a user has a role key with <constant>READ</constant>
     610          permission for <constant>SAMPLES</constant>, but also an item key with <constant>USE</constant>
     611          permission for a specific sample. Of course, the resulting permission for that
     612          sample is <constant>USE</constant>. For other samples the resulting permission is
     613          <constant>READ</constant>.
     614        </para>
     615       
     616        <para>
     617          If the user is also a member of a project which has <constant>WRITE</constant>
     618          permission for the same sample, the user will have <constant>WRITE</constant>
     619          permission when working with that project.
     620        </para>
     621       
     622        <para>
     623          The <constant>RESTRICTED_WRITE</constant> permission is in most cases the same
     624          as the <constant>WRITE</constant> permission. So far the <constant>RESTRICTED_WRITE</constant>
     625          permission is only given to users to their own <classname>UserData</classname>
     626          object so they can change their address and other contact information,
     627          but not quota, expiration date and other administrative information.
     628        </para>
     629      </sect3>
     630    </sect2>
     631
     632    <sect2 id="data_api.wares">
     633      <title>Hardware and software</title>
     634    </sect2>
     635   
     636    <sect2 id="data_api.reporters">
     637      <title>Reporters</title>
     638    </sect2>
     639
     640    <sect2 id="data_api.quota">
     641      <title>Quota and disk usage</title>
     642    </sect2>
     643
     644    <sect2 id="data_api.sessions">
     645      <title>Client, session and settings</title>
     646    </sect2>
     647
     648    <sect2 id="data_api.files">
     649      <title>Files and directories</title>
     650    </sect2>
     651
     652    <sect2 id="data_api.protocols">
     653      <title>Protocols</title>
     654    </sect2>
     655
     656    <sect2 id="data_api.parameters">
     657      <title>Parameters</title>
     658    </sect2>
     659
     660    <sect2 id="data_api.annotations">
     661      <title>Annotations</title>
     662    </sect2>
     663
     664    <sect2 id="data_api.plugins">
     665      <title>Plug-ins, jobs and job agents</title>
     666    </sect2>
     667   
     668    <sect2 id="data_api.biomaterials">
     669      <title>Biomaterials</title>
     670    </sect2>
     671
     672    <sect2 id="data_api.plates">
     673      <title>Array LIMS - plates</title>
     674    </sect2>
     675
     676    <sect2 id="data_api.arrays">
     677      <title>Array LIMS - arrays</title>
     678    </sect2>
     679
     680    <sect2 id="data_api.rawdata">
     681      <title>Hybridizations and raw data</title>
     682    </sect2>
     683
     684    <sect2 id="data_api.experiments">
     685      <title>Experiments and analysis</title>
     686    </sect2>
     687   
     688    <sect2 id="data_api.misc">
     689      <title>Other classes</title>
     690    </sect2>
     691
    169692  </sect1>
    170693 
  • trunk/doc/src/docbook/developerdoc/core_ref.xml

    r3688 r3715  
    315315    <sect2 id="core_ref.rules.datalayer">
    316316      <title>Data-layer rules</title>
     317
    317318      <para>
    318         This documentation is only available in the old format.
    319         See <ulink url="http://base.thep.lu.se/chrome/site/doc/development/coding/data/index.html"
    320           >http://base.thep.lu.se/chrome/site/doc/development/coding/data/index.html</ulink>
     319        The coding guidelines for this package has been slightly modified from the
     320        the general coding guidelines. Here is a short list with the changes.
    321321      </para>
    322     </sect2>   
     322     
     323      <sect3 id="core_ref.rules.datalayer.methodorder">
     324        <title>Attributes and methods order</title>
     325        <para>
     326          Inside a class, attributes and methods should be organised in related groups,
     327          ie. the private attribute is together with the getter and setter methods that uses
     328          that attribute. This makes it easy to re-use existing code with copy-and-paste
     329          operations.
     330        </para>
     331         
     332        <programlisting>
     333public static int long MAX_ADDRESS_LENGTH = 255;
     334private String address;
     335/**
     336   @hibernate.property column="`address`" type="string" length="255" not-null="false"
     337*/
     338public String getAddress()
     339{
     340   return address;
     341}
     342public void setAddress(String address)
     343{
     344   this.address = address;
     345}
     346
     347private int row;
     348/**
     349   @hibernate.property column="`row`" type="int"
     350*/
     351public int getRow()
     352{
     353   return row;
     354}
     355public void setRow(int row)
     356{
     357   this.row = row;
     358}       
     359</programlisting>
     360        </sect3>
     361       
     362        <sect3 id="core_ref.rules.datalayer.classnames">
     363          <title>Class and interface names</title>
     364        <para>
     365          Class names should follow the general guidelines, but should in most
     366          cases end with <classname>Data</classname>.
     367        </para>
     368        <programlisting>
     369public class SampleData
     370   extends CommonData
     371   implements DiskConsumableData
     372{
     373   ...
     374}
     375</programlisting>
     376      </sect3>
     377      <sect3 id="core_ref.rules.datalayer.basicclasses">
     378        <title>Extend/implement the basic classes and interfaces</title>
     379        <para>
     380          Each data-class must inherit from one of the already existing abstract base classes.
     381          They contain code that is common to all classes, for example implementations of
     382          the <methodname>equals()</methodname> and <methodname>hashCode()</methodname>
     383          methods or how to link with the owner of an item. For information about
     384          which classes/interfaces that can be used see <xref linkend="data_api.basic" />.
     385        </para>
     386      </sect3>
     387
     388      <sect3 id="core_ref.rules.datalayer.constructor">
     389        <title>Define a public no-argument constructor</title>
     390        <para>
     391          Always define a public a no-argument constructor. No other constructors are needed.
     392          If we want to use other persistence mechanisms or serializability in the future
     393          this type of constructor is probably the most compatible. The constructor should
     394          be empty and not contain any code. Do not initialise properties or create new objects
     395          for internal use. Most of the time the object is loaded by
     396          Hibernate and Hibernate will ensure that it is properly initialised by calling
     397          all setter methods.
     398        </para>
     399
     400        <para>
     401          For example, a many-to-many relation usually has a <interfacename>Set</interfacename>
     402          or a <interfacename>Map</interfacename> to hold the links to the other objects. Do not
     403          create a new <classname>HashSet</classname> or <classname>HashMap</classname>
     404          in the constructor. Wait until the get method is called and only create a new
     405          object if Hibernate hasn't already called the setter method with it's own object.
     406          See the code example below. There is also more information about this in
     407          <xref linkend="core_ref.rules.datalayer.manytomany" />.
     408        </para>
     409       
     410        <programlisting>
     411// From GroupData.java
     412public GroupData()
     413{}
     414
     415private Set&lt;UserData&gt; users;
     416public Set&lt;UserData&gt; getUsers()
     417{
     418   if (users == null) users = new HashSet&lt;UserData&gt;();
     419   return users;
     420}
     421</programlisting>
     422
     423        <para>
     424        See also:
     425        </para>
     426       
     427        <itemizedlist>
     428        <listitem>
     429          <para>
     430          "Hibernate in action", chapter 3.2.3 "Writing POJOs", page 67-69
     431          </para>
     432        </listitem>
     433        <listitem>
     434          <para>
     435          Hibernate user documentation: <ulink
     436            url="http://www.hibernate.org/hib_docs/reference/en/html/persistent-classes.html#persistent-classes-pojo-constructor">4.1.1.
     437            Implement a no-argument constructor</ulink>
     438          </para>
     439        </listitem>
     440        </itemizedlist>
     441
     442      </sect3>
     443
     444      <sect3 id="core_ref.rules.datalayer.identity">
     445        <title>Object identity</title>
     446        <para>
     447          We use database identity to compare objects, ie. two objects are considered
     448          equal if they are of the same class and have the same id, thus representing the
     449          same database row. All this stuff is implemented by the BasicData class. Therefore
     450          it is required that all classes are subclasses of this class. It is recommended
     451          that the <methodname>equals()</methodname> or <methodname>hashCode()</methodname>
     452          methods are not overridden by any of the subclasses. We would have liked to make
     453          them final, but then the proxy feature of Hibernate would not work.
     454        </para>
     455       
     456        <warning>
     457          <title>Avoid mixing saved and unsaved objects</title>
     458          <para>
     459            The approch used for object identity may give us a problem if we mix objects
     460            which hasn't been saved to the database, with objects loaded from the database.
     461            Our recommendation is to avoid that, and save any objects to the database before
     462            adding them to sets, maps or any other structure that uses the
     463            <methodname>equals()</methodname> and <methodname>hashCode()</methodname> methods.
     464          </para>
     465          <para>
     466            To be more specific, the problem arises because the following two rules for
     467            hascodes are contradicting when the hashcode is based on the database id:
     468          </para>
     469          <orderedlist>
     470          <listitem>
     471            <para>
     472            The hash code of an object mustn't change
     473            </para>
     474          </listitem>
     475          <listitem>
     476            <para>
     477            Equal objects must have equal hash code
     478            </para>
     479          </listitem>
     480          </orderedlist>
     481          <para>
     482            For objects in the database, the hash code is based on the id. For new objects,
     483            which doesn't have an id yet, we fall back to the system hash code. But, what
     484            happens when we save the new object to the database? If nobody has asked for
     485            the hash code it is safe to use the id, otherwise we must stick with the system
     486            hash code. Now, imagine that we load the same object from the database in
     487            another Hibernate session. What will now happen? The loaded object will have
     488            it's hash code based on the id but the original object is still using the
     489            system hash code, which most likely is not the same as the id. Yet, the
     490            <methodname>equals()</methodname> method returns true. This is a violation
     491            of the contract for the equals method. If these two objects are used in a set
     492            it may cause unexpected behaviour. Therefore, do not put new objects in a
     493            set, or other collection, that calls the <methodname>hashCode()</methodname>
     494            method before the object is saved to the database.         
     495          </para>
     496        </warning>
     497       
     498        <para>
     499        See also:
     500        </para>
     501        <itemizedlist>
     502        <listitem>
     503          <para>
     504          "Hibernate in action", chapter 3.4 "Understanding object identity", page 87-90
     505          </para>
     506        </listitem>
     507        <listitem>
     508          <para>
     509          "Hibernate in action", chapter 4.1.4 "The scope of object identity", page 119-121
     510          </para>
     511        </listitem>
     512        <listitem>
     513          <para>
     514          "Hibernate in action", chapter 4.1.6 "Implementing equals() and hashCode(), page 122-126
     515          </para>
     516        </listitem>
     517        <listitem>
     518          <para>
     519          Hibernate user documentation: <ulink
     520            url="http://www.hibernate.org/hib_docs/reference/en/html/persistent-classes.html#persistent-classes-equalshashcode">4.3. Implementing equals() and hashCode()</ulink>
     521          </para>
     522        </listitem>
     523        </itemizedlist>
     524      </sect3>
     525
     526      <sect3 id="core_ref.rules.datalayer.nofinal">
     527        <title>No final methods</title>
     528        <para>
     529          No methods should be tagged with the <constant>final</constant> keyword. This is a
     530          requirement to be able to use the proxy feature of Hibernate, which we need for
     531          performance reasons.
     532        </para>
     533
     534        <para>
     535        See also:
     536        </para>
     537        <itemizedlist>
     538        <listitem>
     539          <para>
     540          Hibernate user documentation: <ulink
     541            url="http://www.hibernate.org/hib_docs/reference/en/html/persistent-classes.html#persistent-classes-pojo-final">4.1.3. Prefer non-final classes</ulink>
     542          </para>
     543        </listitem>
     544        <listitem>
     545          <para>
     546          Hibernate user documentation: <ulink
     547            url="http://www.hibernate.org/hib_docs/reference/en/html/performance.html#performance-fetching-proxies">19.1.3. Single-ended association proxies</ulink>
     548          </para>
     549        </listitem>
     550        </itemizedlist>
     551
     552      </sect3>
     553
     554      <sect3 id="core_ref.rules.datalayer.cache">
     555        <title>Second-level cache</title>
     556        <para>
     557          To gain performance we use the second-level cache of Hibernate. It is a transparent
     558          feature that doesn't affect the code in any way. The second-level cache is configured
     559          in the <filename>hibernate.cfg.xml</filename> and <filename>ehcache.xml</filename>
     560          files and not in the individual class mapping files. BASE is shipped with a standard
     561          configuration, but different deployment scenarios may have to fine-tune the cache
     562          settings for that particular hardware/software setup. It is beyond the scope of
     563          this document to discuss this issue.
     564        </para>
     565       
     566        <para>
     567          The second-level cache is suitable for objects that are rarely modified but
     568          are often needed. For example, we do not expect the user information represented
     569          by the <classname>UserData</classname> object to change very often, but it is
     570          displayed all the time as the owner of various items.
     571        </para>
     572       
     573        <para>
     574          It is required that one thinks a bit of the usage of a class before coming
     575          up with a good caching strategy. We have to answer the following questions:
     576        </para>
     577       
     578        <orderedlist>
     579        <listitem>
     580          <para>
     581          Should objects of this class be cached at all?
     582          </para>
     583        </listitem>
     584        <listitem>
     585          <para>
     586          How long timeout should we use?
     587          </para>
     588        </listitem>
     589        <listitem>
     590          <para>
     591          How many objects should we keep in memory or on disk?
     592          </para>
     593        </listitem>
     594        </orderedlist>
     595       
     596        <para>
     597          The first question is the most important. Good candidates are classes with few
     598          objects that change rarely, but are read often. Also, objects which are linked
     599          to by many other objects are good candidates. The <classname>UserData</classname>
     600          class is an example which matches all three requirements. The <classname>LabelData</classname>
     601          class is an example which fulfils the first two. The <classname>BioMaterialEventData</classname>
     602          class is on the other hand a bad cache candidate, since it is not linked to any
     603          other object than a <classname>BioMaterialData</classname> object.
     604        </para>
     605       
     606        <para>
     607          The answer to the second question depends on how often an object is modified.
     608          For most objects this time is probably several days or months, but we would
     609          not gain much by keeping objects in the cache for so long. Suddenly, the
     610          information has changed and we won't risk that old information is kept that
     611          long. We have set the timeout to 1 hour for all classes so far, and we don't
     612          recommend a longer timeout. The only exception is for immutable objects, that
     613          cannot be changed at all, which may have an infinite timeout.
     614        </para>
     615       
     616        <para>
     617          The answer to the third question depends a lot on the hardware (available memory).
     618          With lots of memory we can afford to cache more objects. Caching to disk is not
     619          really necessary if the database is on the same machine as the web server, but
     620          if it is on another machine we have to consider the network delay to connect
     621          to the database versus the disk access time. The default configuration does not
     622          use disk cache.
     623        </para>
     624
     625        <para>
     626        See also:
     627        </para>
     628        <itemizedlist>
     629        <listitem>
     630          <para>
     631          "Hibernate in action", chapter 5.3 "Caching theory and practice", page 175-194.
     632          </para>
     633        </listitem>
     634        <listitem>
     635          <para>
     636          Hibernate user documentation: <ulink
     637            url="http://www.hibernate.org/hib_docs/reference/en/html/performance.html#performance-cache">19.2. The Second Level Cache</ulink>
     638          </para>
     639        </listitem>
     640        </itemizedlist>
     641
     642      </sect3>
     643
     644      <sect3 id="core_ref.rules.datalayer.proxies">
     645        <title>Proxies</title>
     646       
     647        <para>
     648          Proxies are also used to gain performance, and they may have some impact on
     649          the code. Proxies are created at runtime (by Hibernate) as a subclass of the
     650          actual class but are not populated with data until some method of the object
     651          is called. The data is loaded from the database the first time a method other
     652          than <methodname>getId()</methodname> is called. Thus, we can avoid loading
     653          data that is not needed at a particular time.
     654        </para>
     655       
     656        <para>
     657          There can be a problem with using the <code>instanceof</code> operator with proxies
     658          and the table-per-class-hierarchy mapping. For example, if we have the abstract
     659          class <classname>Animal</classname> and subclasses <classname>Cat</classname>
     660          and <classname>Dog</classname>. The proxy of an <classname>Animal</classname> is a
     661          runtime generated subclass of <classname>Animal</classname>, since we do not know if it
     662          is a <classname>Cat</classname> or <classname>Dog</classname>. So,
     663          <code>x instanceof Dog</code> and <code>x instanceof Cat</code> would both return
     664          false. If we hadn't used a proxy, at least one of them would always be true.
     665        </para>
     666       
     667        <para>
     668          Proxies are only used when a not-null object is linked with many-to-one or
     669          one-to-one from another object. If we ask for a specific object by id, or by a
     670          query, we will never get a proxy. Therefore, it only makes sense to enable
     671          proxies for classes that can be linked from other classes. One-to-one links on
     672          the primary key where null is allowed silently disables the proxy feature,
     673          since Hibernate doesn't know if there is an object or not without querying
     674          the database.
     675        </para>
     676       
     677        <bridgehead>Proxy vs. cache</bridgehead>
     678        <para>
     679          The goal of a proxy and the second-level cache are the same: to avoid hitting the
     680          database. It is perfectly possible to enable both proxies and the cache for a
     681          class. Then we would start with a proxy and as soon as a method is called Hibernate
     682          would look in the second-level cache. Only if it is not there it would be loaded
     683          from the database. But, do we really need a proxy in the first place? Well, I think
     684          it might be better to use only the cache or only proxies. But, this also makes it
     685          even more important that the cache is configured correctly so there is a high
     686          probability that the object is already in the cache.
     687        </para>
     688       
     689        <para>
     690          If a class has been configured to use the second-level cache, we recommend
     691          that proxies are disabled. For child objects in a parent-child relationship proxies
     692          should be disabled, since they have no other links to them than from the parent.
     693          If a class can be linked as many-to-one from several other classes it makes sense
     694          to enable proxies. If we have a long chain of many-to-one relations it may also make
     695          sense to enable proxies at some level, even if the second-level cache is used.
     696          In that case we only need to create one proxy instead of looking up several objects
     697          in the cache. Also, think about how a particular class most commonly will be used
     698          in a client application. For example, it is very common to display the name of the
     699          owner of an item, but we are probably not interested in displaying quota
     700          information for that user. So, it makes sense to put users in the second-level
     701          cache and use proxies for quota information.
     702        </para>
     703       
     704        <warning>
     705          <title>Batchable classes and stateless sessions</title>
     706          <para>
     707            Starting with Hibernate 3.1 there is a new stateless session feature. A
     708            stateless session has no first-level cache and doesn't use the second-level
     709            cache either. This means that if we load an item with a stateless session
     710            Hibernate will always traverse many-to-one and one-to-one associations and
     711            load those objects as well, unless they are configured to use proxies.
     712          </para>
     713         
     714          <para>
     715            Stateless sessions are used by batchable items (reporters, raw data and features)
     716            since they are many and we want to use as little memory as possible. Here it
     717            is required that proxies are enabled for all items that are linked from any of
     718            the batchable items, ie. <classname>RawBioAssay</classname>,
     719            <classname>ReporterType</classname>, <classname>ArrayDesignBlock</classname>, etc.
     720          </para>
     721         
     722          <para>
     723            On the other hand, the proxies created from a stateless session cannot later
     724            be initialised. We have to get the ID from the proxy and the load the object
     725            using the regular session. This also means that a batchable class shouldn't
     726            use proxies.
     727          </para>
     728        </warning>
     729       
     730        <para>
     731          Here is a table which summarises different settings for the second-level cache,
     732          proxies, batch fetching and many-to-one links. Batch fetching and many-to-one links
     733          are discussed later in this document.
     734        </para>
     735       
     736        <para>
     737          First, decide if the second-level cache should be enabled or not. Then, if
     738          proxies should be enabled or not. The table then gives a reasonable setting for
     739          the batch size and many-to-one mappings. NOTE! The many-to-one mappings are
     740          the links from other classes to this one, not links from this class.
     741        </para>
     742       
     743        <para>
     744          The settings in this table are not absolute rules. In some cases there might
     745          be a good reason for another combination. Please, write a comment about why
     746          the recommendations were not followed.
     747        </para>
     748       
     749        <table id="core_ref.rules.datalayer.cacheproxysettings">
     750          <title>Choosing cache and proxy settings</title>
     751          <tgroup cols="4">
     752            <colspec colname="cache" />
     753            <colspec colname="proxy" />
     754            <colspec colname="batchsize" />
     755            <colspec colname="outerjoin" />
     756           
     757            <thead>
     758              <row>
     759                <entry>Global configuration</entry>
     760                <entry namest="proxy" nameend="batchsize">Class mapping</entry>
     761                <entry>Many-to-one mapping</entry>
     762              </row>
     763              <row>
     764                <entry>Cache</entry>
     765                <entry>Proxy</entry>
     766                <entry>Batch-size</entry>
     767                <entry>Outer-join</entry>
     768              </row>
     769            </thead>
     770            <tbody>
     771              <row>
     772                <entry>no</entry>
     773                <entry>no*</entry>
     774                <entry>yes</entry>
     775                <entry>true</entry>
     776              </row>
     777              <row>
     778                <entry>yes</entry>
     779                <entry>no*</entry>
     780                <entry>no</entry>
     781                <entry>false</entry>
     782              </row>
     783              <row>
     784                <entry>no</entry>
     785                <entry>yes</entry>
     786                <entry>yes</entry>
     787                <entry>false</entry>
     788              </row>
     789              <row>
     790                <entry>yes</entry>
     791                <entry>yes</entry>
     792                <entry>no</entry>
     793                <entry>false</entry>
     794              </row>
     795            </tbody>
     796          </tgroup>
     797        </table>
     798       
     799        <para>
     800          * = Do not use this setting for classes which are many-to-one linked from a batchable
     801          class. Always use this setting for batchable classes. See warning above!
     802        </para>
     803       
     804        <para>
     805        See also:
     806        </para>
     807        <itemizedlist>
     808        <listitem>
     809          <para>
     810          "Hibernate in action", chapter 4.4.6 "Selecting a fetching strategy in mappings", page 146-147
     811          </para>
     812        </listitem>
     813        <listitem>
     814          <para>
     815          "Hibernate in action", chapter 6.4.1 "Polymorphic many-to-one associations", page 234-236
     816          </para>
     817        </listitem>
     818        <listitem>
     819          <para>
     820          Hibernate user documentation: <ulink
     821            url="http://www.hibernate.org/hib_docs/reference/en/html/performance.html#performance-fetching-proxies">19.1.3. Single-ended association proxies</ulink>
     822          </para>
     823        </listitem>
     824        </itemizedlist>
     825       
     826      </sect3>
     827     
     828      <sect3 id="core_ref.rules.datalayer.hibernate">
     829        <title>Hibernate mappings</title>
     830       
     831        <para>
     832          We use Javadoc tags to specify the database mapping needed by Hibernate.
     833          The tags are processed by XDoclet at build time which generates the XML-based
     834          Hibernate mapping files.
     835        </para>
     836       
     837        <note>
     838          <title>XDoclet doesn't support all mappings</title>
     839          <para>
     840          The XDoclet that we use was developed to generate mapping files for
     841          Hibernate 2.x. Since then, Hibernate has released several 3.x versions,
     842          and the mapping file structure has changed. Some changes can be handled by
     843          generating a corresponding 2.x mapping and then converting it to a 3.x
     844          mapping at build time using simple search-and-replace operations.
     845          One such case is to update the DTD reference to the 3.0 version instead of
     846          the 2.0 version. Other changes can't use this approach. Instead we have to
     847          provide extra mappings inside an XML files. This is also needed if we need
     848          to use some of the new 3.x features that has no 2.x counterpart.
     849          </para>
     850        </note>
     851       
     852        <simplesect id="core_ref.rules.datalayer.class">
     853          <title>Class mapping</title>
     854         
     855          <programlisting>
     856/**
     857   This class holds information about any data...
     858   @author Your name
     859   @version 2.0
     860   @hibernate.class table="`Anys`" lazy="false" batch-size="10"
     861   @base.modified $Date: 2007-08-17 09:18:29 +0200 (Fri, 17 Aug 2007) $
     862*/
     863public class AnyData
     864   extends CommonData
     865{
     866   // Rest of class code...
     867}
     868</programlisting>
     869         
     870          <para>
     871            The class declaration must contain a <code>@hibernate.class</code> Javadoc entry
     872            where Hibernate can find the name of the table where items of this type are stored.
     873            The table name should generally be the same as the class name, without the ending
     874            <code>Data</code> and in a plural form. For example <classname>UserData</classname>
     875            --&gt; <code>Users</code>. The back-ticks (`) around the table name tells Hibernate
     876            to enclose the name in whatever the actual database manager uses for such things
     877            (back-ticks in MySQL, quotes for an ANSI-compatible database).
     878          </para>
     879         
     880          <important>
     881            <title>Specify a value for the lazy attribute</title>
     882            <para>
     883              The lazy attribute enables/disables proxies for the class. Do not forget
     884              to specify this attribute since the default value is true. If proxies are
     885              enabled, it may also make sense to specify a batch-size attribute. Then
     886              Hibernate will load the specified number of items in each SELECT statement
     887              instead of loading them one by one. It may also make sense to specify a
     888              batch size when proxies are disabled, but then it would probably be even
     889              better to use eager fetching by setting <code>outer-join="true"</code>
     890              (see many-to-one mapping).
     891            </para>
     892
     893            <para>
     894              Classes that are linked with a many-to-one association from a batchable
     895              class must specify <code>lazy="true"</code>. Otherwise the stateless session
     896              feature of Hibernate may result in a large number of SELECT:s for the same
     897              item, or even circular loops if two or more items references each other.
     898            </para>
     899          </important>
     900         
     901          <important>
     902            <title>Remember to enable the second-level cache</title>
     903            <para>
     904              Do not forget to configure settings for the second-level cache if this
     905              should be enabled. This is done in the <filename>hibernate.cfg.xml</filename>
     906              and <filename>ehcache.xml</filename>.
     907            </para>
     908          </important>
     909       
     910          <para>
     911          See also:
     912          </para>
     913         
     914          <itemizedlist>
     915          <listitem>
     916            <para>
     917            "Hibernate in action", chapter 3.3 "Defining the mapping metadata", page 75-87
     918            </para>
     919          </listitem>
     920          <listitem>
     921            <para>
     922            Hibernate user documentation: <ulink
     923              url="http://www.hibernate.org/hib_docs/reference/en/html/mapping.html#mapping-declaration-class">5.1.3. class</ulink>
     924            </para>
     925          </listitem>
     926          </itemizedlist>
     927         
     928        </simplesect>
     929       
     930        <simplesect id="core_ref.rules.datalayer.property">
     931          <title>Property mappings</title>
     932         
     933          <para>
     934            Properties such as strings, integers, dates, etc. are mapped with
     935            the <code>@hibernate.property</code> Javadoc tag. The main purpose
     936            is to define the database column name. The column names should
     937            generally be the same as the get/set method name without the get/set prefix,
     938            and with upper-case letters converted to lower-case and an underscore inserted.
     939            Examples:
     940          </para>
     941         
     942          <itemizedlist>
     943          <listitem>
     944            <para>
     945              <methodname>getAddress()</methodname>
     946              --&gt; <code>column="`address`"</code>
     947            </para>
     948          </listitem>
     949          <listitem>
     950            <para>
     951              <methodname>getLoginComment()</methodname>
     952              --&gt; <code>column="`login_comment`"</code>
     953            </para>
     954          </listitem>
     955          </itemizedlist>
     956         
     957          <para>
     958            The back-ticks (`) around the column name tells Hibernate to enclose
     959            the name in whatever the actual database manager uses for such things
     960            (back-ticks in MySQL, quotes for an ANSI-compatible database).
     961          </para>
     962         
     963          <bridgehead>String properties</bridgehead>
     964         
     965          <programlisting>
     966public static int long MAX_STRINGPROPERTY_LENGTH = 255;
     967private String stringProperty;
     968/**
     969   Get the string property.
     970   @hibernate.property column="`string_property`" type="string"
     971      length="255" not-null="true"
     972*/
     973public String getStringProperty()
     974{
     975   return stringProperty;
     976}
     977public void setStringProperty(String stringProperty)
     978{
     979   this.stringProperty = stringProperty;
     980}
     981</programlisting>
     982
     983          <para>
     984            Do not use a greater value than 255 for the length attribute. Some databases
     985            has that as the maximum length for character columns (ie. MySQL). If you need
     986            to store longer texts use <code>type="text"</code> instead. You can then skip
     987            the length attribute. Most databases will allow up to 65535 characters or more
     988            in a text field. Do not forget to specify the <code>not-null</code> attribute.
     989          </para>
     990         
     991          <para>
     992            You should also define a public constant <constant>MAX_STRINGPROPERTY_LENGTH</constant>
     993            containing the maximum allowed length of the string.
     994          </para>
     995         
     996          <bridgehead>Numerical properties</bridgehead>
     997         
     998          <programlisting>
     999private int intProperty;
     1000/**
     1001   Get the int property.
     1002   @hibernate.property column="`int_property`" type="int" not-null="true"
     1003*/
     1004public int getIntProperty()
     1005{
     1006   return intProperty;
     1007}
     1008public void setIntProperty(int intProperty)
     1009{
     1010   this.intProperty = intProperty;
     1011}
     1012</programlisting>
     1013
     1014          <para>
     1015            It is also possible to use <classname>Integer</classname>, <classname>Long</classname>
     1016            or <classname>Float</classname> objects instead of <classname>int</classname>,
     1017            <classname>long</classname> and <classname>float</classname>. We have only used it
     1018            if null values have some meaning.
     1019          </para>
     1020
     1021        <bridgehead>Boolean properties</bridgehead>
     1022        <programlisting>
     1023private boolean booleanProperty;
     1024/**
     1025   Get the boolean property.
     1026   @hibernate.property column="`boolean_property`"
     1027      type="boolean" not-null="true"
     1028*/
     1029public boolean isBooleanProperty()
     1030{
     1031   return booleanProperty;
     1032}
     1033public void setBooleanProperty(boolean booleanProperty)
     1034{
     1035   this.booleanProperty = booleanProperty;
     1036}
     1037</programlisting>
     1038        <para>
     1039          It is also possible to use a <classname>Boolean</classname> object instead of
     1040          <classname>boolean</classname>. It is only required if you absolutely need
     1041          null values to handle special cases.
     1042        </para>
     1043       
     1044        <bridgehead>Date values</bridgehead>
     1045       
     1046        <programlisting>
     1047private Date dateProperty;
     1048/**
     1049   Get the date property. Null is allowed.
     1050   @hibernate.property column="`date_property`" type="date" not-null="false"
     1051*/
     1052public Date getDateProperty()
     1053{
     1054   return dateProperty;
     1055}
     1056public void setDateProperty(Date dateProperty)
     1057{
     1058   this.dateProperty = dateProperty;
     1059}
     1060</programlisting>
     1061       
     1062        <para>
     1063          Hibernate defines several other date and time types. We have decided to use
     1064          the <code>type="date"</code> type when we are only interested in the date and
     1065          the <code>type="timestamp"</code> when we are interested in both the date
     1066          and time.
     1067        </para>
     1068       
     1069        <para>
     1070        See also:
     1071        </para>
     1072       
     1073        <itemizedlist>
     1074          <listitem>
     1075            <para>
     1076            "Hibernate in action", chapter 3.3.2 "Basic property and class mappings", page 78-84
     1077            </para>
     1078          </listitem>
     1079          <listitem>
     1080            <para>
     1081            "Hibernate in action", chapter 6.1.1 "Built-in mapping types", page 198-200
     1082            </para>
     1083          </listitem>
     1084          <listitem>
     1085            <para>
     1086            Hibernate user documentation: <ulink
     1087              url="http://www.hibernate.org/hib_docs/reference/en/html/mapping.html#mapping-declaration-property">5.1.9. property</ulink>
     1088            </para>
     1089          </listitem>
     1090          <listitem>
     1091            <para>
     1092            Hibernate user documentation: <ulink
     1093              url="http://www.hibernate.org/hib_docs/reference/en/html/mapping.html#mapping-types-basictypes">5.2.2. Basic value types</ulink>
     1094            </para>
     1095          </listitem>
     1096          </itemizedlist>
     1097         
     1098        </simplesect>
     1099       
     1100        <simplesect id="core_ref.rules.datalayer.manytoone">
     1101          <title>Many-to-one mappings</title>
     1102         
     1103          <programlisting>
     1104private OtherData other;
     1105/**
     1106   Get the other object.
     1107   @hibernate.many-to-one column="`other_id`" not-null="true" outer-join="false"
     1108*/
     1109public OtherData getOther()
     1110{
     1111   return other;
     1112}
     1113public void setOther(OtherData other)
     1114{
     1115   this.other = other;
     1116}
     1117</programlisting>
     1118         
     1119        <para>
     1120          We create a many-to-one mapping with the <code>@hibernate.many-to-one</code> tag.
     1121          The most important attribute is the <code>column</code> attribute which specifies the name of
     1122          the database column to use for the id of the other item. The back-ticks (`)
     1123          around the column name tells Hibernate to enclose the name in whatever the
     1124          actual database manager uses for such things (back-ticks in MySQL, quotes for
     1125          an ANSI-compatible database).
     1126        </para>
     1127       
     1128        <para>
     1129          We also recommend that the <code>not-null</code> attribute is specified. Hibernate
     1130          will not check for null values, but it will generate table columns that allow
     1131          or disallow null values. See it as en extra safety feature while debugging.
     1132          It is also used to determine if Hibernate uses <code>LEFT JOIN</code> or
     1133          <code>INNER JOIN</code> in SQL statements.
     1134        </para>
     1135       
     1136        <para>
     1137          The <code>outer-join</code> attribute is important and affects how the
     1138          cache and proxies are used. It can take three values: <constant>auto</constant>,
     1139          <constant>true</constant> or <constant>false</constant>. If the value is
     1140          <constant>true</constant> Hibernate will always use a join to load the linked
     1141          object in a single select statement, overriding the cache and proxy settings.
     1142          This value should only be used if the class being linked has disabled both
     1143          proxies and the second-level cache, or if it is a link between a child
     1144          and parent in a parent-child relationship. A false value is best when
     1145          we expect the associated object to be in the second-level cache or proxying
     1146          is enabled. This is probably the most common case. The auto setting uses a
     1147          join if proxying is disabled otherwise it uses a proxy. Since we always
     1148          know if proxying is enabled or not, this setting is not very useful. See
     1149          <xref linkend="core_ref.rules.datalayer.cacheproxysettings" /> for the
     1150          recommended settings.
     1151        </para>
     1152       
     1153        <para>
     1154          See also:
     1155        </para>
     1156         
     1157        <itemizedlist>
     1158          <listitem>
     1159            <para>
     1160            "Hibernate in action", chapter 3.7 "Introducing associations", page 105-112
     1161            </para>
     1162          </listitem>
     1163          <listitem>
     1164            <para>
     1165            "Hibernate in action", chapter 4.4.5-4.4.6 "Fetching strategies", page 143-151
     1166            </para>
     1167          </listitem>
     1168          <listitem>
     1169            <para>
     1170            "Hibernate in action", chapter 6.4.1 "Polymorphic many-to-one associations", page 234-236
     1171            </para>
     1172          </listitem>
     1173          <listitem>
     1174            <para>
     1175            Hibernate user documentation: <ulink
     1176              url="http://www.hibernate.org/hib_docs/reference/en/html/mapping.html#mapping-declaration-manytoone">5.1.10. many-to-one</ulink>
     1177            </para>
     1178          </listitem>
     1179          </itemizedlist>
     1180         
     1181        </simplesect>
     1182       
     1183        <simplesect id="core_ref.rules.datalayer.manytomany">
     1184          <title>Many-to-many and one-to-many mappings</title>
     1185         
     1186          <para>
     1187            There are many variants of mapping many-to-many or one-to-many, and it is
     1188            not possible to give examples of all of them. In the code these mappings
     1189            are represented by <classname>Set</classname>:s, <classname>Map</classname>:s,
     1190            <classname>List</classname>:s, or some other collection object. The most
     1191            important thing to remember is that (in our application) the collections
     1192            are only used to maintain the links between objects. They are not used
     1193            for returning objects to client applications, as is the case with the
     1194            many-to-one mapping.
     1195          </para>
     1196         
     1197          <para>
     1198            For example, if we want to find all members of a group we do not use the
     1199            <code>GroupData.getUsers()</code> method, instead we will execute a database query
     1200            to retrieve them. The reason for this design is that the logged in user may
     1201            not have access to all users and we must add a permission checking filter
     1202            before returning the user objects to the client application. Using a query
     1203            will also allow client applications to specify sorting and filtering options
     1204            for the users that are returned.
     1205          </para>
     1206         
     1207          <programlisting>
     1208// RoleData.java
     1209private Set&lt;UserData&gt; users;
     1210/**
     1211   Many-to-many from roles to users
     1212   @hibernate.set table="`UserRoles`" lazy="true"
     1213   @hibernate.collection-key column="`role_id`"
     1214   @hibernate.collection-many-to-many column="`user_id`"
     1215      class="net.sf.basedb.core.data.UserData"
     1216*/
     1217public Set&lt;UserData&gt; getUsers()
     1218{
     1219   if (users == null) users = new HashSet&lt;UserData&gt;();
     1220   return users;
     1221}
     1222void setUsers(Set&lt;UserData&gt; users)
     1223{
     1224   this.users = users;
     1225}
     1226</programlisting>
     1227         
     1228          <para>
     1229            As you can see this mapping is a lot more complicated than what we have
     1230            seen before. The most important thing is the <code>lazy</code> attribute.
     1231            It tells Hibernate to delay the loading of the related objects until the set
     1232            is accessed. If the value is false or missing, Hibernate will load all objects
     1233            immediately. There is almost never a good reason to specify something other
     1234            than <code>lazy="true"</code>.
     1235          </para>
     1236         
     1237          <para>
     1238            Another important thing to remember is that the get method must always return
     1239            the same object that Hibernate passed to the set method. Otherwise, Hibernate
     1240            will not be able to detect changes made to the collection and as a result
     1241            will have to delete and then recreate all links. To ensure that the collection
     1242            object is not changed we have made the <methodname>setUsers()</methodname> method
     1243            package private, and the <methodname>getUsers()</methodname> will create a
     1244            new <classname>HashSet</classname> for us only if Hibernate didn't pass one
     1245            in the first place.
     1246          </para>
     1247         
     1248          <para>
     1249            Let's also have a look at the reverse mapping:
     1250          </para>
     1251         
     1252          <programlisting>
     1253// UserData.java
     1254private Set&lt;RoleData&gt; roles;
     1255/**
     1256   Many-to-many from users to roles
     1257   @hibernate.set table="`UserRoles`" lazy="true"
     1258   @hibernate.collection-key column="`user_id`"
     1259   @hibernate.collection-many-to-many column="`role_id`"
     1260      class="net.sf.basedb.core.data.RoleData"
     1261*/
     1262Set&lt;RoleData&gt; getRoles()
     1263{
     1264   return roles;
     1265}
     1266void setRoles(Set&lt;RoleData&gt; roles)
     1267{
     1268   this.roles = roles;
     1269}
     1270</programlisting>
     1271
     1272          <para>
     1273            The only real difference here is that both the setter and the getter methods
     1274            are package private. This is required because Hibernate will get confused if
     1275            we modify both ends. Thus, we are forced to always add/remove users to/from
     1276            the set in the <classname>GroupData</classname> object. The methods in the
     1277            <classname>RoleData</classname> class are never used by us.
     1278            Note that we do not have to check for null and create a new set since Hibernate
     1279            will handle null values as an empty set.
     1280          </para>
     1281         
     1282          <para>
     1283            So, why do we need the second collection at all? It is never accessed
     1284            except by Hibernate, and since it is lazy it will always be "empty".
     1285            The answer is that we want to use the relation in HQL statements.
     1286            For example:
     1287          </para>
     1288         
     1289          <programlisting>
     1290SELECT ... FROM GroupData grp WHERE grp.users ...
     1291SELECT ... FROM UserData usr WHERE usr.groups ...
     1292</programlisting>
     1293         
     1294          <para>
     1295            Without the inverse mapping, it would not have been possible to execute
     1296            the second HQL statement. The inverse mapping is also important in
     1297            parent-child relationships, where it is used to cascade delete the children
     1298            if a parent is deleted.
     1299          </para>
     1300
     1301          <warning>
     1302            <title>Do not use the inverse="true" setting</title>
     1303            <para>
     1304              Hibernate defines an <code>inverse="true"</code> setting that can be used with
     1305              the <code>@hibernate.set</code> tag. If specified, Hibernate will ignore
     1306              changes made to that collection. However, there is one problem with specifying
     1307              this attribute. Hibernate doesn't delete entries in the association table,
     1308              leading to foreign key violations if we try to delete a user. The only
     1309              solutions are to skip the <code>inverse="true"</code> attribute or to
     1310              manually delete the object from all collections on the non-inverse end.
     1311              The first alternative is the most efficient since it only requires a
     1312              single SQL statement. The second alternative must first load all associated
     1313              objects and then issue a single delete statement for each association.
     1314            </para>
     1315           
     1316            <para>
     1317              In the "Hibernate in action" book they have a very different design
     1318              where they recommend that changes are made in both collections. We don't
     1319              have to do this since we are only interested in maintaining the links,
     1320              which is always done in one of the collections.
     1321            </para>
     1322          </warning>
     1323
     1324          <bridgehead>Parent-child relationships</bridgehead>
     1325
     1326          <para>
     1327            When one or more objects are tightly linked to some other object we talk
     1328            about a parent-child relationship. This kind of relationship becomes important
     1329            when we are about to delete a parent object. The children cannot exist
     1330            without the parent so they must also be deleted. Luckily, Hibernate can
     1331            do this for us if we specify a <code>cascade="delete"</code> option for the link.
     1332            This example is a one-to-many link between client and help texts.
     1333          </para>
     1334
     1335          <programlisting>
     1336// ClientData.java
     1337private Set&lt;HelpData&gt; helpTexts;
     1338/**
     1339   This is the inverse end.
     1340   @see HelpData#getClient()
     1341   @hibernate.set lazy="true" inverse="true" cascade="delete"
     1342   @hibernate.collection-key column="`client_id`"
     1343   @hibernate.collection-one-to-many class="net.sf.basedb.core.data.HelpData"
     1344*/
     1345Set&lt;HelpData&gt; getHelpTexts()
     1346{
     1347   return helpTexts;
     1348}
     1349
     1350void setHelpTexts(Set&lt;HelpData&gt; helpTexts)
     1351{
     1352   this.helpTexts = helpTexts;
     1353}
     1354
     1355// HelpData.java
     1356private ClientData client;
     1357/**
     1358   Get the client for this help text.
     1359   @hibernate.many-to-one column="`client_id`" not-null="true"
     1360      update="false" outer-join="false" unique-key="uniquehelp"
     1361*/
     1362public ClientData getClient()
     1363{
     1364   return client;
     1365}
     1366public void setClient(ClientData client)
     1367{
     1368   this.client = client;
     1369}
     1370</programlisting>
     1371
     1372          <para>
     1373            This show both sides of the one-to-many mapping between parent and children.
     1374            As you can see the <code>@hibernate.set</code> doesn't specify a table,
     1375            since it is given by the <code>class</code> attribute of the
     1376            <code>@hibernate.collection-one-to-many</code> tag.
     1377          </para>
     1378         
     1379          <para>
     1380            In a one-to-many mapping, it is always the "one" side that handles the
     1381            link so the "many" side should always be mapped with <code>inverse="true"</code>.
     1382          </para>
     1383
     1384          <bridgehead>Maps</bridgehead>
     1385         
     1386          <para>
     1387            Another type of many-to-many mapping uses a <interfacename>Map</interfacename>
     1388            for the collection. This kind of mapping is needed when the association between
     1389            two objects needs additional data to be kept as part of the association.
     1390            For example, the permission (stored as an integer value) given to users that
     1391            are members of a project. Note that you should use a <interfacename>Set</interfacename>
     1392            for mapping the inverse end.
     1393          </para>
     1394         
     1395          <programlisting>
     1396// ProjectData.java
     1397private Map&lt;UserData, Integer&gt; users;
     1398/**
     1399   Many-to-many mapping between projects and users including permission values.
     1400   @hibernate.map table="`UserProjects`" lazy="true"
     1401   @hibernate.collection-key column="`project_id`"
     1402   @hibernate.index-many-to-many column="`user_id`"
     1403      class="net.sf.basedb.core.data.UserData"
     1404   @hibernate.collection-element column="`permission`" type="int" not-null="true"
     1405*/
     1406public Map&lt;UserData, Integer&gt; getUsers()
     1407{
     1408   if (users == null) users = new HashMap&lt;UserData, Integer&gt;();
     1409   return users;
     1410}
     1411void setUsers(Map&lt;UserData, Integer&gt; users)
     1412{
     1413   this.users = users;
     1414}
     1415
     1416// UserData.java
     1417private Set&lt;ProjectData&gt; projects;
     1418/**
     1419   This is the inverse end.
     1420   @see ProjectData#getUsers()
     1421   @hibernate.set table="`UserProjects`" lazy="true"
     1422   @hibernate.collection-key column="`user_id`"
     1423   @hibernate.collection-many-to-many column="`project_id`"
     1424      class="net.sf.basedb.core.data.ProjectData"
     1425*/
     1426Set&lt;ProjectData&gt; getProjects()
     1427{
     1428   return projects;
     1429}
     1430void setProjects(Set&lt;ProjectData&gt; projects)
     1431{
     1432   this.projects = projects;
     1433}
     1434</programlisting>
     1435       
     1436        <para>
     1437          See also:
     1438        </para>
     1439       
     1440        <itemizedlist>
     1441          <listitem>
     1442            <para>
     1443            "Hibernate in action", chapter 3.7 "Introducing associations", page 105-112
     1444            </para>
     1445          </listitem>
     1446          <listitem>
     1447            <para>
     1448            "Hibernate in action", chapter 6.2 "Mapping collections of value types", page 211-220
     1449            </para>
     1450          </listitem>
     1451          <listitem>
     1452            <para>
     1453            "Hibernate in action", chapter 6.3.2 "Many-to-many associations", page 225-233
     1454            </para>
     1455          </listitem>
     1456          <listitem>
     1457            <para>
     1458            Hibernate user documentation: <ulink
     1459              url="http://www.hibernate.org/hib_docs/reference/en/html/collections.html">Chapter 6. Collection Mapping</ulink>
     1460            </para>
     1461          </listitem>
     1462          <listitem>
     1463            <para>
     1464            Hibernate user documentation: <ulink
     1465              url="http://www.hibernate.org/hib_docs/reference/en/html/example-parentchild.html">Chapter 21. Example: Parent/Child</ulink>
     1466            </para>
     1467          </listitem>
     1468          </itemizedlist>
     1469       
     1470
     1471        </simplesect>
     1472       
     1473        <simplesect id="core_ref.rules.datalayer.onetoone">
     1474          <title>One-to-one mappings</title>
     1475         
     1476          <para>
     1477            A one-to-one mapping can come in two different forms, depending on if both
     1478            objects should have the same id or not. We start with the case were the objects
     1479            can have different id:s and the link is done with an extra column in one of
     1480            the tables. The example is from the mapping between hybridizations and
     1481            arrayslides.
     1482          </para>
     1483         
     1484          <programlisting>
     1485// HybridizationData.java
     1486private ArraySlideData arrayslide;
     1487/**
     1488   Get the array slide
     1489   @hibernate.many-to-one column="`arrayslide_id`" not-null="false" unique="true"
     1490*/
     1491public ArraySlideData getArraySlide()
     1492{
     1493   return arrayslide;
     1494}
     1495public void setArraySlide(ArraySlideData arrayslide)
     1496{
     1497   arrayslide.setHybridization(this);
     1498   this.arrayslide = arrayslide;
     1499}
     1500
     1501// ArraySlideData.java
     1502private HybridizationData hybridization;
     1503/**
     1504   Get the hybridization
     1505   @hibernate.one-to-one property-ref="arraySlide"
     1506*/
     1507public HybridizationData getHybridization()
     1508{
     1509   return hybridization;
     1510}
     1511void setHybridization(HybridizationData hybridization)
     1512{
     1513   this.hybridization = hybridization;
     1514}         
     1515</programlisting>
     1516         
     1517          <para>
     1518            As you can see, we use the many-to-one mapping on with a <code>unique="true"</code>
     1519            option for the hybridization. This will force the database to only allow the
     1520            same array slide to be linked once. Also note that since, <code>not-null="false"</code>,
     1521            null values are allowed and it doesn't matter which end of the relation that
     1522            is inserted first into the database.
     1523          </para>
     1524          <para>
     1525            For the array slide end we use a <code>@hibernate.one-to-one</code>
     1526            mapping and specify the name of the property on the other end that we are
     1527            linking to. Also, note that the we can only change the link with the
     1528            <methodname>HybridizationData.setArraySlide()</methodname> method, and that
     1529            this method also updates the other end.
     1530          </para>
     1531
     1532          <para>
     1533            The second form of a one-to-one mapping is used when both objects must
     1534            have the same id (primary key). The example is from the mapping between users
     1535            and passwords.
     1536          </para>
     1537         
     1538          <programlisting>
     1539// UserData.java
     1540/**
     1541   @hibernate.id column="`id`" generator-class="foreign"
     1542   @hibernate.generator-param name="property" value="password"
     1543*/
     1544public int getId()
     1545{
     1546   return super.getId();
     1547}
     1548private PasswordData password;
     1549/**
     1550   Get the password.
     1551   @hibernate.one-to-one class="net.sf.basedb.core.data.PasswordData"
     1552      cascade="all" outer-join="false" constrained="true"
     1553*/
     1554public PasswordData getPassword()
     1555{
     1556   if (password == null)
     1557   {
     1558      password = new PasswordData();
     1559      password.setUser(this);
     1560   }
     1561   return password;
     1562}
     1563void setPassword(PasswordData user)
     1564{
     1565   this.password = password;
     1566}
     1567
     1568// PasswordData.java
     1569private UserData user;
     1570/**
     1571   Get the user.
     1572   @hibernate.one-to-one class="net.sf.basedb.core.data.UserData"
     1573*/
     1574public UserData getUser()
     1575{
     1576   return user;
     1577}
     1578void setUser(UserData user)
     1579{
     1580   this.user = user;
     1581}
     1582</programlisting>
     1583         
     1584          <para>
     1585            In this case, we use the <code>@hibernate.one-to-one</code> mapping
     1586            in both classes. The <code>constrained="true"</code> tag in <classname>UserData</classname>
     1587            tells Hibernate to always insert the password first, and then the user. The makes it
     1588            possible to use the (auto-generated) id for the password as the id
     1589            for the user. This is controlled by the mapping for the <methodname>UserData.getId()</methodname>
     1590            method, which uses the <code>foreign</code> id generator. This generator will look
     1591            at the password property, ie. call <methodname>getPassword().getId()</methodname>
     1592            to find the id for the user. Also note the initialisation code and <code>cascade="all"</code>
     1593            tag in the <methodname>UserData.getPassword()</methodname> method. This is need
     1594            to avoid <classname>NullPointerException</classname>:s and to make sure everything
     1595            is created and deleted properly.
     1596          </para>
     1597         
     1598          <para>
     1599            See also:
     1600          </para>
     1601         
     1602        <itemizedlist>
     1603          <listitem>
     1604            <para>
     1605            "Hibernate in action", chapter 6.3.1 "One-to-one association", page 220-225
     1606            </para>
     1607          </listitem>
     1608          <listitem>
     1609            <para>
     1610            Hibernate user documentation: <ulink
     1611              url="http://www.hibernate.org/hib_docs/reference/en/html/mapping.html#mapping-declaration-onetoone">5.1.11. one-to-one</ulink>
     1612            </para>
     1613          </listitem>
     1614          </itemizedlist>
     1615         
     1616        </simplesect>
     1617       
     1618      </sect3>
     1619
     1620      <sect3 id="core_ref.rules.datalayer.documentation">
     1621        <title>Documentation</title>
     1622
     1623        <para>
     1624          The data layer code needs documentation. A simple approach is used for
     1625          Javadoc documentation
     1626        </para>
     1627       
     1628        <simplesect id="core_ref.rules.datalayer.documentation.class">
     1629          <title>Class documentation</title>
     1630          <para>
     1631            The documentation for the class doesn't have to be very lengthy. A single
     1632            sentence is usually enough. Provide tags for the author, version, last modification date
     1633            and a reference to the corresponding class in the <package>net.sf.basedb.core</package>
     1634            package.
     1635          </para>
     1636         
     1637          <programlisting>
     1638/**
     1639   This class holds information about any items.
     1640
     1641   @author Your name
     1642   @version 2.0
     1643   @see net.sf.basedb.core.AnyItem
     1644   @base.modified $Date: 2007-08-17 09:18:29 +0200 (Fri, 17 Aug 2007) $
     1645   @hibernate.class table="`Anys`" lazy="false"
     1646*/
     1647public class AnyData
     1648   extends CommonData
     1649{
     1650...
     1651}
     1652</programlisting>
     1653         
     1654        </simplesect>
     1655       
     1656        <simplesect id="core_ref.rules.datalayer.documentation.method">
     1657          <title>Method documentation</title>
     1658         
     1659          <para>
     1660          Write a short one-sentence description for all public getter methods. You do not
     1661          have document the parameters or the setter methods, since it would just be a
     1662          repetition. Methods defined by interfaces are documented in the interface class.
     1663          You should not have to write any documentation for those methods.
     1664          </para>
     1665         
     1666          <para>
     1667            For the inverse end of an association, which has only package private methods,
     1668            write a notice about this and provide a link to to non-inverse end.
     1669          </para>
     1670         
     1671          <programlisting>
     1672// UserData.java
     1673private String address;
     1674/**
     1675   Get the address for the user.
     1676   @hibernate.property column="`address`" type="string" length="255"
     1677*/
     1678public String getAddress()
     1679{
     1680   return address;
     1681}
     1682public void setAddress(String address)
     1683{
     1684   this.address = address;
     1685}
     1686
     1687private Set&lt;GroupData&gt; groups;
     1688/**
     1689   This is the inverse end.
     1690   @see GroupData#getUsers()
     1691   @hibernate.set table="`UserGroups`" lazy="true" inverse="true"
     1692   @hibernate.collection-key column="`user_id`"
     1693   @hibernate.collection-many-to-many column="`group_id`"
     1694      class="net.sf.basedb.core.data.GroupData"
     1695*/
     1696Set&lt;GroupData&gt; getGroups()
     1697{
     1698   return groups;
     1699}
     1700void setGroups(Set&lt;GroupData&gt; groups)
     1701{
     1702   this.groups = groups;
     1703}
     1704</programlisting>
     1705         
     1706        </simplesect>
     1707       
     1708        <simplesect id="core_ref.rules.datalayer.documentation.field">
     1709          <title>Field documentation</title>
     1710          <para>
     1711            Write a short one-sentence description for <code>public static final</code>
     1712            fields. Private fields does not have to be documented.
     1713          </para>
     1714         
     1715          <programlisting>
     1716/**
     1717   The maximum length of the name of an item that can be
     1718   stored in the database.
     1719   @see #setName(String)
     1720*/
     1721public static int MAX_NAME_LENGTH = 255;
     1722</programlisting>
     1723
     1724        </simplesect>
     1725       
     1726        <simplesect id="core_ref.rules.datalayer.documentation.uml">
     1727          <title>UML diagram</title>
     1728         
     1729          <para>
     1730            Groups of related classes should be included in an UML-like
     1731            diagram to show how they are connected and work together.
     1732            For example we group together users, groups, roles, etc. into an
     1733            authentication UML diagram. It is also possible that a single class
     1734            may appear in more than one diagram. For more information about
     1735            how to create UML diagrams see
     1736            <xref linkend="documentation.magicdraw" />.
     1737          </para>
     1738        </simplesect>
     1739
     1740       
     1741      </sect3>
     1742
     1743    </sect2>
    3231744    <sect2 id="core_ref.rules.itemclass">
    3241745      <title>Item-class rules</title>
  • trunk/doc/src/docbook/developerdoc/documentation.xml

    r3681 r3715  
    2727-->
    2828
    29 <chapter id="write_docbook_doc">
     29<chapter id="documentation">
    3030  <?dbhtml dir="write_doc"?>
    3131  <title>Write documentation</title>
    32   <para>
    33     This chapter is for those who intent to contribute to the BASE2 documentation. The chapter
    34     contains explanations of how the documentation is organized, what the different parts is
    35     about and other things that will make it easier to know where to insert new text.
    36   </para>
    37   <para>
    38     The documentation is written with the docbook standard, which is a bunch of defined XML
    39     elements and XSLT style sheets that are used to format the text. Later on in this chapter
    40     is a reference, over those docbook elements that are recommended to use when writing BASE2
    41     documentation. Further information about docbook can be found in the on-line version of
    42     O'Reilly's
    43     <ulink url="http://www.docbook.org/tdg/en/html/">DocBook: The Definitive Guide</ulink>
    44     by Norman Walsh and Leonard Muellner.
    45   </para>
    46 
    47   <sect1 id="write_docbook_doc.layout">
     32
     33  <sect1 id="documentation.docbook">
     34    <title>User, administrator and developer documentation with Docbook</title>
     35
     36    <para>
     37      This chapter is for those who intent to contribute to the BASE2 user documentation.
     38      The chapter contains explanations of how the documentation is organized, what the
     39      different parts is about and other things that will make it easier to know
     40      where to insert new text.
     41    </para>
     42    <para>
     43      The documentation is written with the docbook standard, which is a bunch of defined XML
     44      elements and XSLT style sheets that are used to format the text. Later on in this chapter
     45      is a reference, over those docbook elements that are recommended to use when writing BASE2
     46      documentation. Further information about docbook can be found in the on-line version of
     47      O'Reilly's
     48      <ulink url="http://www.docbook.org/tdg/en/html/">DocBook: The Definitive Guide</ulink>
     49      by Norman Walsh and Leonard Muellner.
     50    </para>
     51   
     52
     53  <sect2 id="docbook.layout">
    4854    <title>Documentation layout</title>
    4955    <para>
     
    96102      </varlistentry>
    97103    </variablelist>
    98   </sect1>
    99 
    100 
    101   <sect1 id="write_docbook_doc.begin">
     104  </sect2>
     105
     106
     107  <sect2 id="docbook.begin">
    102108    <title>Getting started</title>
    103109    <para>
     
    105111      rules and standards, to have in mind.
    106112    </para>
    107     <sect2 id="write_docbook_doc.begin.sourcefiles">
     113    <sect3 id="docbook.begin.sourcefiles">
    108114      <title>Organization of source files</title>
    109115      <para>
     
    117123        file which joins the index files from the different parts together.
    118124      </para>
    119       <figure id="write_docbook_doc.figures.fileorganization">
     125      <figure id="docbook.figures.fileorganization">
    120126        <title>The organization of documentation files</title>
    121127        <screenshot>
     
    127133        </screenshot>
    128134      </figure>
    129       <sect3 id="write_docbook_doc.begin.sourcefiles.newfile">
     135      <sect4 id="docbook.begin.sourcefiles.newfile">
    130136        <title>Create new chapter/file</title>
    131137        <para>
     
    144150              <para>
    145151                Begin to write the chapter's body, here is an example:
    146                 <example id="write_docbook_doc.examples.chapterbody">
     152                <example id="docbook.examples.chapterbody">
    147153                  <title>Example of a chapter</title>
    148154<programlisting>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
     
    199205                documentation part.
    200206              </para>
    201               <example id="write_docbook_doc.examples.include_chapter">
     207              <example id="docbook.examples.include_chapter">
    202208                <title>Include a chapter</title>
    203209<programlisting>&lt;part id="userdoc"&gt;
     
    232238          Now it's only to go ahead with the documentation writing.
    233239        </para>
    234       </sect3>
    235     </sect2>
     240      </sect4>
     241    </sect3>
    236242   
    237     <sect2 id="write_docbook_doc.begin.chunking">
     243    <sect3 id="docbook.begin.chunking">
    238244      <title>Controlling chunking</title>
    239245      <para>
     
    263269      <programlisting>&lt;sect1 id="sect.with.large.sect2" chunked="1"&gt;</programlisting>
    264270   
    265     </sect2>
     271    </sect3>
    266272   
    267     <sect2 id="write_docbook_doc.begin.id">
     273    <sect3 id="docbook.begin.id">
    268274      <title>
    269275        The
     
    339345        </variablelist>
    340346      </para>
    341     </sect2>
    342     <sect2 id="write_docbook_doc.begin.helptext">
     347    </sect3>
     348    <sect3 id="docbook.begin.helptext">
    343349      <title>Mark help texts</title>
    344350      <para>
     
    410416        </variablelist>
    411417      </para>
    412       <example id="write_docbook_doc.examples.helptexttag">
     418      <example id="docbook.examples.helptexttag">
    413419        <title>How to use the help text tag</title>
    414420<programlisting>&lt;sect1&gt;
     
    423429      </example>
    424430     
    425       <sect3 id="write_docbook_doc.begin.helptext.nohelp">
     431      <sect4 id="docbook.begin.helptext.nohelp">
    426432        <title>Skip parts of a help text</title>
    427433        <para>
     
    435441        </para>     
    436442        <programlisting>&lt;nohelp&gt;see &lt;xref linkend="chapter11" /&gt;&lt;/nohelp&gt;</programlisting>
    437       </sect3>
     443      </sect4>
    438444     
    439       <sect3 id="write_docbook_doc.begin.helptext.link">
     445      <sect4 id="docbook.begin.helptext.link">
    440446      <title>Link to other help texts</title>
    441447     
     
    470476          help text section. The links will not show up in the HTML or PDF version.
    471477        </para>
    472       </sect3>
     478      </sect4>
    473479     
    474       <sect3 id="write_docbook_doc.begin.helptext.import">
     480      <sect4 id="docbook.begin.helptext.import">
    475481      <title>Import help texts into BASE</title>
    476482
     
    492498cd build/test
    493499./run.sh TestHelp</programlisting>
    494       </sect3>
     500      </sect4>
    495501     
    496     </sect2>
    497     <sect2 id="write_docbook_doc.begin.generate">
     502    </sect3>
     503    <sect3 id="docbook.begin.generate">
    498504      <title>Generate output</title>
    499505
    500       <sect3 id="write_docbook_doc.begin.generate.requirements">
     506      <sect4 id="docbook.begin.generate.requirements">
    501507        <title>Requirements</title>
    502508        <para>
     
    516522          </para>
    517523        </note>
    518       </sect3>
    519       <sect3 id="write_docbook_doc.begin.generate.compile">
     524      </sect4>
     525      <sect4 id="docbook.begin.generate.compile">
    520526        <title>Compile - generate output files</title>
    521527        <para>
     
    529535          BASE 2.
    530536        </para>
    531       </sect3>
    532     </sect2>
    533   </sect1>
    534 
    535   <sect1 id="write_docbook_doc.usedtags">
    536     <title>Elements to use</title>
     537      </sect4>
     538    </sect3>
     539  </sect2>
     540
     541  <sect2 id="docbook.usedtags">
     542    <title>Docbook tags to use</title>
    537543    <para>
    538544      The purpose with this section is to give an overview of those docbook elements that are
     
    545551      or other references.
    546552    </para>
    547     <sect2 id="write_docbook_doc.usedtags.text">
     553    <sect3 id="docbook.usedtags.text">
    548554      <title>Text elements</title>
    549555      <para>
     
    571577                <para>
    572578                  See
    573                   <xref linkend="write_docbook_doc.examples.chapterbody" />
     579                  <xref linkend="docbook.examples.chapterbody" />
    574580                </para>
    575581              </entry>
     
    581587              </entry>
    582588              <entry>
    583                 <xref linkend="write_docbook_doc.examples.chapterbody" />
     589                <xref linkend="docbook.examples.chapterbody" />
    584590                shows how this can be implemented
    585591              </entry>
     
    599605              <entry>
    600606                See
    601                 <xref linkend="write_docbook_doc.begin.id" />
     607                <xref linkend="docbook.begin.id" />
    602608              </entry>
    603609            </row>
     
    609615              <entry>
    610616                See
    611                 <xref linkend="write_docbook_doc.begin.id" />
     617                <xref linkend="docbook.begin.id" />
    612618              </entry>
    613619            </row>
     
    619625              <entry>
    620626                See
    621                 <xref linkend="write_docbook_doc.begin.id" />
     627                <xref linkend="docbook.begin.id" />
    622628              </entry>
    623629            </row>
     
    640646      </informaltable>
    641647
    642       <sect3 id="write_docbook_doc.usedtags.text.keywords">
     648      <sect4 id="docbook.usedtags.text.keywords">
    643649        <title>Code elements</title>
    644650        <para>
     
    695701                <entry>
    696702                  See
    697                   <xref linkend="write_docbook_doc.examples.methodimpl" />
     703                  <xref linkend="docbook.examples.methodimpl" />
    698704                </entry>
    699705              </row>
     
    705711                <entry>
    706712                  See
    707                   <xref linkend="write_docbook_doc.examples.methodimpl" />
     713                  <xref linkend="docbook.examples.methodimpl" />
    708714                </entry>
    709715              </row>
     
    715721                <entry>
    716722                  See
    717                   <xref linkend="write_docbook_doc.examples.methodimpl" />
     723                  <xref linkend="docbook.examples.methodimpl" />
    718724                </entry>
    719725              </row>
     
    725731                <entry>
    726732                  See
    727                   <xref linkend="write_docbook_doc.examples.methodimpl" />
     733                  <xref linkend="docbook.examples.methodimpl" />
    728734                </entry>
    729735              </row>
     
    735741                <entry>
    736742                  See
    737                   <xref linkend="write_docbook_doc.examples.methodimpl" />
     743                  <xref linkend="docbook.examples.methodimpl" />
    738744                </entry>
    739745              </row>
     
    745751                <entry>
    746752                  See
    747                   <xref linkend="write_docbook_doc.examples.methodimpl1" />
     753                  <xref linkend="docbook.examples.methodimpl1" />
    748754                </entry>
    749755              </row>
     
    755761                <entry>
    756762                  See
    757                   <xref linkend="write_docbook_doc.examples.methodimpl1" />
     763                  <xref linkend="docbook.examples.methodimpl1" />
    758764                </entry>
    759765              </row>
     
    765771                <entry>
    766772                  See
    767                   <xref linkend="write_docbook_doc.examples.methodimpl1" />
     773                  <xref linkend="docbook.examples.methodimpl1" />
    768774                </entry>
    769775              </row>
     
    774780          Follow one of the examples below to insert a method definition in the document.
    775781        </para>
    776         <example id="write_docbook_doc.examples.methodimpl">
     782        <example id="docbook.examples.methodimpl">
    777783          <title>
    778784            Method with no arguments and a return value
     
    787793&hellip;</programlisting>
    788794        </example>
    789         <example id="write_docbook_doc.examples.methodimpl1">
     795        <example id="docbook.examples.methodimpl1">
    790796          <title>
    791797            Method with arguments and no return value
     
    812818        </example>
    813819       
    814       </sect3>
    815       <sect3 id="write_docbook_doc.usedtags.text.gui">
     820      </sect4>
     821      <sect4 id="docbook.usedtags.text.gui">
    816822        <title>Gui elements</title>
    817823        <para>
     
    885891        </informaltable>
    886892        <para>
    887           <xref linkend="write_docbook_doc.examples.guielements" />
     893          <xref linkend="docbook.examples.guielements" />
    888894          shows how the menu choice in figure
    889           <xref linkend="write_docbook_doc.figures.menuchoice" />
     895          <xref linkend="docbook.figures.menuchoice" />
    890896          can be described.
    891897        </para>
    892         <figure id="write_docbook_doc.figures.menuchoice">
     898        <figure id="docbook.figures.menuchoice">
    893899          <title>Menu choice</title>
    894900          <screenshot>
     
    902908          </screenshot>
    903909        </figure>
    904         <example id="write_docbook_doc.examples.guielements">
     910        <example id="docbook.examples.guielements">
    905911          <title>Describe a menu choice</title>
    906912<programlisting>&hellip;         
     
    920926          </para>
    921927        </example>
    922       </sect3>
    923     </sect2>
    924     <sect2 id="write_docbook_doc.usedtags.images">
     928      </sect4>
     929    </sect3>
     930    <sect3 id="docbook.usedtags.images">
    925931      <title>Images and figures</title>
    926932      <para>
     
    931937      </para>
    932938
    933       <example id="write_docbook_doc.examples.screenshot">
     939      <example id="docbook.examples.screenshot">
    934940        <title>Screen-shot in the documentation</title>
    935941        <para>
     
    937943          is implemented with the following code
    938944        </para>
    939 <programlisting>&lt;figure id="write_docbook_doc.figures.menuchoice"&gt;
     945<programlisting>&lt;figure id="docbook.figures.menuchoice"&gt;
    940946  &lt;title&gt;The home page&lt;/title&gt;
    941947  &lt;screenshot&gt;
     
    10131019        </para>
    10141020      </warning>
    1015     </sect2>
    1016     <sect2 id="write_docbook_doc.usedtags.examples">
     1021    </sect3>
     1022    <sect3 id="docbook.usedtags.examples">
    10171023      <title>Examples and program listing</title>
    10181024      <para>
     
    10471053        </itemizedlist>
    10481054      </note>
    1049       <example id="write_docbook_doc.examples.example">
     1055      <example id="docbook.examples.example">
    10501056        <title>Example in the documentation</title>
    10511057        <para>
     
    10771083&hellip;</programlisting>
    10781084      </example>     
    1079     </sect2>
    1080     <sect2 id="write_docbook_doc.usedtags.admonitions">
     1085    </sect3>
     1086    <sect3 id="docbook.usedtags.admonitions">
    10811087      <title>Admonitions</title>
    10821088      <para>
     
    11341140        </tgroup>
    11351141      </informaltable>
    1136     </sect2>
    1137     <sect2 id="write_docbook_doc.usedtags.lists">
     1142    </sect3>
     1143    <sect3 id="docbook.usedtags.lists">
    11381144      <title>Lists</title>
    11391145      <para>
     
    11861192      </informaltable>
    11871193      <para>The example below shows how to create a list for term definition in the text.</para>
    1188       <example id="write_docbook_doc.examples.variablelist">
     1194      <example id="docbook.examples.variablelist">
    11891195        <title>Example how to write a variable list</title>
    11901196<programlisting>&hellip;
     
    12091215&lt;/variablelist&gt;</programlisting>
    12101216      </example>
    1211     </sect2>
     1217    </sect3>
    12121218   
    1213     <sect2 id="write_docbook_doc.usedtags.links">
     1219    <sect3 id="docbook.usedtags.links">
    12141220      <title>Link elements</title>
    12151221      <para></para>
     
    12541260        </tgroup>
    12551261      </informaltable>
    1256       <example id="write_docbook_doc.examples.links">
     1262      <example id="docbook.examples.links">
    12571263        <title>Links</title>
    12581264<programlisting>&hellip;
    1259 &lt;xref linkend="write_docbook_doc.usedtags.links" /&gt;
    1260 &lt;link linkend="write_docbook_doc.usedtags.links"&gt;Link to this section&lt;/link&gt;
     1265&lt;xref linkend="docbook.usedtags.links" /&gt;
     1266&lt;link linkend="docbook.usedtags.links"&gt;Link to this section&lt;/link&gt;
    12611267&lt;ulink url="http://base.thep.lu.se"&gt;Base2's homepage&lt;/ulink&gt;
    12621268&hellip;</programlisting>
     
    12711277        </para>
    12721278      </example>
     1279    </sect3>
     1280  </sect2>
     1281 
     1282  </sect1>
     1283 
     1284  <sect1 id="documentation.magicdraw">
     1285    <title>Create UML diagrams with MagicDraw</title>
     1286
     1287    <para>
     1288      UML or UML-like diagrams are used to document the relationship of
     1289      classes in the Core API. To create the diagrams we use the community edition (version 12.5)
     1290      of a program called MagicDraw. This is a Java program and it should be possible
     1291      to run it on any platform which has at least a Java 1.5 runtime.
     1292      To get more information about MagicDraw and to download the program
     1293      go to their website:
     1294      <ulink url="http://www.magicdraw.com/">http://www.magicdraw.com/</ulink>
     1295    </para>
     1296   
     1297
     1298    <sect2 id="magicdraw.organisation">
     1299      <title>Organisation</title>
     1300     
     1301      <para>
     1302        All classes and diagrams are in a single UML file. It can be
     1303        found at <filename>&lt;base-dir&gt;/doc/src/uml/base.mdzip</filename>
     1304      </para>
     1305     
     1306      <para>
     1307        Everything in MagicDraw has been organised into packages and
     1308        modules. At the top we have the <code>Core layer</code> and
     1309        the <code>Data layer</code>. The <code>Java</code> moduled is
     1310        for classes that related to the Java programming language, such
     1311        as <code>Map</code> and <code>Set</code> that are not pre-defined
     1312        by MagicDraw.
     1313      </para>
     1314     
     1315      <figure id="magicdraw.figures.organisation">
     1316        <title>MagicDraw organisation</title>
     1317        <screenshot>
     1318          <mediaobject>
     1319            <imageobject>
     1320              <imagedata
     1321                fileref="figures/magicdraw/organisation.png" format="PNG" />
     1322            </imageobject>
     1323          </mediaobject>
     1324        </screenshot>
     1325      </figure>
    12731326    </sect2>
     1327   
     1328    <sect2 id="magicdraw.classes">
     1329      <title>Classes</title>
     1330        <para>
     1331          New classes should be added to one of the subpackages inside
     1332          the <code>Data layer/Classes</code> or <code>Core layer/Classes</code>
     1333          modules. It is very simple:
     1334        </para>
     1335         
     1336        <orderedlist>
     1337        <listitem>
     1338          <para>
     1339          Select the subpackage in the overview and click with the right mouse button.
     1340          </para>
     1341        </listitem>
     1342        <listitem>
     1343          <para>
     1344          Select the
     1345          <menuchoice>
     1346            <guimenu>New element</guimenu>
     1347            <guimenuitem>Class</guimenuitem>
     1348          </menuchoice>
     1349          menu item in the menu that pops up.
     1350          </para>
     1351        </listitem>
     1352        <listitem>
     1353          <para>
     1354          The overview will expand to add a new class. Enter the name of the class
     1355          and press enter.
     1356          </para>
     1357        </listitem>
     1358        </orderedlist>
     1359       
     1360        <sect3 id="magicdraw.classes.data">
     1361          <title>Data layer classes</title>
     1362         
     1363          <para>
     1364            If you added a class to the data layer you also need to
     1365            record some important information.
     1366          </para>
     1367
     1368          <itemizedlist>
     1369          <listitem>
     1370            <para>
     1371            The database table the data is stored in
     1372            </para>
     1373          </listitem>
     1374          <listitem>
     1375            <para>
     1376            If the second-level cache is enabled or not
     1377            </para>
     1378          </listitem>
     1379          <listitem>
     1380            <para>
     1381            If proxies are enabled or not
     1382            </para>
     1383          </listitem>
     1384          <listitem>
     1385            <para>
     1386            The superclass
     1387            </para>
     1388          </listitem>
     1389          <listitem>
     1390            <para>
     1391            Implemented interfaces
     1392            </para>
     1393          </listitem>
     1394          <listitem>
     1395            <para>
     1396            Simple properties, ie. strings, numbers, dates
     1397            </para>
     1398          </listitem>
     1399          <listitem>
     1400            <para>
     1401            Associations to other classes
     1402            </para>
     1403          </listitem>
     1404          </itemizedlist>
     1405
     1406          <para>
     1407            To achive this we have slightly altered the meaning of some UML symbols.
     1408            For example we use the access modified symbols (+, ~ and -) to indicate
     1409            if a property is updatable or not.
     1410          </para>
     1411
     1412          <sect4 id="magicdraw.classes.data.tags">
     1413            <title>Setting tagged values</title>
     1414           
     1415            <para>
     1416              Some of the information needed is specified as <emphasis>tagged values</emphasis>
     1417              that can be attached to a class.
     1418              Double-click on the new class to bring up it's properties dialog
     1419              box. Switch to the <guilabel>Tags</guilabel> configuration page.
     1420              We have defined the following tags:
     1421            </para>
     1422             
     1423            <variablelist>
     1424            <varlistentry>
     1425              <term><guilabel>table</guilabel></term>
     1426              <listitem>
     1427                <para>
     1428                The name of the database table where the items should be stored.
     1429                </para>
     1430              </listitem>
     1431            </varlistentry>
     1432            <varlistentry>
     1433              <term><guilabel>cache</guilabel></term>
     1434              <listitem>
     1435                <para>
     1436                The number of items to store in the second-level cache of Hibernate.
     1437                Only specify a value if caching should be enabled.
     1438                </para>
     1439              </listitem>
     1440            </varlistentry>
     1441            <varlistentry>
     1442              <term><guilabel>proxy</guilabel></term>
     1443              <listitem>
     1444                <para>
     1445                A boolean flag to indicate if proxies should be used or not.
     1446                </para>
     1447              </listitem>
     1448            </varlistentry>
     1449            <varlistentry>
     1450              <term><guilabel>extends</guilabel></term>
     1451              <listitem>
     1452                <para>
     1453                Select the superclass of this class.
     1454                </para>
     1455              </listitem>
     1456            </varlistentry>
     1457            <varlistentry>
     1458              <term><guilabel>implements</guilabel></term>
     1459              <listitem>
     1460                <para>
     1461                Specify which interfaces the class implements. To save space
     1462                we use the following one-letter abbreviations:
     1463                </para>
     1464               
     1465                <itemizedlist>
     1466                <listitem><para>A = AnnotatableData</para></listitem>
     1467                <listitem><para>B = BatchableData</para></listitem>
     1468                <listitem><para>D = DiskConsumableData</para></listitem>
     1469                <listitem><para>E = ExtendableData</para></listitem>
     1470                <listitem><para>F = FileAttachableData</para></listitem>
     1471                <listitem><para>N = NameableData</para></listitem>
     1472                <listitem><para>O = OwnableData</para></listitem>
     1473                <listitem><para>R = RemoveableData</para></listitem>
     1474                <listitem><para>S = ShareableData</para></listitem>
     1475                <listitem><para>T = SystemData</para></listitem>
     1476                </itemizedlist>
     1477              </listitem>
     1478            </varlistentry>
     1479            </variablelist>
     1480           
     1481            <figure id="magicdraw.figures.classtags">
     1482              <title>Setting tagged values</title>
     1483              <screenshot>
     1484                <mediaobject>
     1485                  <imageobject>
     1486                    <imagedata
     1487                      fileref="figures/magicdraw/classtags.png" format="PNG" />
     1488                  </imageobject>
     1489                </mediaobject>
     1490              </screenshot>
     1491            </figure>
     1492          </sect4>
     1493         
     1494          <sect4 id="magicdraw.classes.data.properties">
     1495            <title>Specifying simple properties for a class</title>
     1496            <para>
     1497              Simple properties are strings, numbers, dates, etc. that are part of an object.
     1498              Properties are entered as attributes of the class. The easiest way to enter
     1499              properties are by typing directly in a diagram. It can also be done
     1500              from the <guilabel>Attributes</guilabel> configuration page.
     1501            </para>
     1502           
     1503            <para>
     1504              Each attribute must have information about:
     1505            </para>
     1506           
     1507            <itemizedlist>
     1508            <listitem>
     1509              <para>
     1510              The name of the attribute, ie. the name of the get/set method without the
     1511              get or set part and starting with a lowercase letter.
     1512              </para>
     1513            </listitem>
     1514            <listitem>
     1515              <para>
     1516              The data type: enter or select the Java object type in the
     1517              <guilabel>Type</guilabel> selection list.
     1518              </para>
     1519            </listitem>
     1520            <listitem>
     1521              <para>
     1522              If null values are allowed or not: specify a multiplicity of 1 if a
     1523              non-null value is required.
     1524              </para>
     1525            </listitem>
     1526            <listitem>
     1527              <para>
     1528              If it is modifiable or not. From the <guilabel>Visibility</guilabel>
     1529              list, select one of the following:
     1530              </para>
     1531             
     1532              <itemizedlist>
     1533              <listitem>
     1534                <para>
     1535                public (+): the attribute is modifiable. This translates to public get and set methods.
     1536                </para>
     1537              </listitem>
     1538              <listitem>
     1539                <para>
     1540                package (~): the attribute can only be set once. This translates to public get and set methods
     1541                and an <code>update="false"</code> tag in the Hibernate mapping.
     1542                </para>
     1543              </listitem>
     1544              <listitem>
     1545                <para>
     1546                private (-): the attribute is private (will this ever be used?).
     1547                This translates to package private get and set methods.
     1548                </para>
     1549              </listitem>
     1550              </itemizedlist>
     1551             
     1552            </listitem>
     1553            </itemizedlist>
     1554     
     1555            <figure id="magicdraw.figures.attributes">
     1556              <title>Class attributes</title>
     1557              <screenshot>
     1558                <mediaobject>
     1559                  <imageobject>
     1560                    <imagedata
     1561                      fileref="figures/magicdraw/attributes.png" format="PNG" />
     1562                  </imageobject>
     1563                </mediaobject>
     1564              </screenshot>
     1565            </figure>         
     1566          </sect4>
     1567         
     1568          <sect4 id="magicdraw.classes.data.associations">
     1569            <title>Associations to other classes</title>
     1570
     1571            <para>
     1572              Associations to other classes are easiest created from
     1573              a diagram view by drawing an <guilabel>Association</guilabel>
     1574              link between the two classes. The ends should be given a name,
     1575              multiplicity and visibility should be selected. For the visibility
     1576              we use the same options as for attributes, but with a slightly different
     1577              interpretation.
     1578            </para>
     1579           
     1580            <itemizedlist>
     1581            <listitem>
     1582              <para>
     1583              public (+): the association is modifiable. This translates to public get and
     1584              set methods for many-to-one associations. Many-to-many associations must have a
     1585              package private set method since the set or map must never be replaced.
     1586              </para>
     1587            </listitem>
     1588 
     1589            <listitem>
     1590              <para>
     1591              package (~): same as public but the association cannot be changed once it has
     1592              been created. For many-to-one associations an <code>update="false"</code> tag in
     1593              the Hibernate mapping should be used. For many-to-many association there is
     1594              no corresponding tag. It will be the responsibility of the core to make sure
     1595              no modifications are done.
     1596              </para>
     1597            </listitem>
     1598           
     1599            <listitem>
     1600              <para>
     1601              private (-): this is the inverse end of an association. Only used for one-to-many
     1602              and many-to-many associations and translates to package private get and set
     1603              methods.
     1604              </para>
     1605            </listitem>
     1606            </itemizedlist>
     1607           
     1608            <para>
     1609              If the association involves a join table (many-to-many) the name of that
     1610              table should be entered as a tagged value to the association.
     1611            </para>
     1612           
     1613            <para>
     1614              If the association have values attached to it, use the
     1615              <guilabel>Association class</guilabel> link type and enter information about
     1616              the values in the attached class.
     1617            </para>         
     1618
     1619          </sect4>
     1620
     1621          <para>
     1622            A lot more can be said about this, but
     1623            it is probably better to have a look at already existing diagrams if you have
     1624            any questions. The authentication overview shown below is one of the most
     1625            complex diagrams that involves many different links.
     1626          </para>
     1627         
     1628          <figure id="magicdraw.figures.realexample">
     1629            <title>Authentication UML diagram</title>
     1630            <screenshot>
     1631              <mediaobject>
     1632                <imageobject>
     1633                  <imagedata
     1634                    fileref="figures/uml/datalayer.authentication.png" format="PNG" />
     1635                </imageobject>
     1636              </mediaobject>
     1637            </screenshot>
     1638          </figure>
     1639         
     1640        </sect3>
     1641       
     1642        <sect3 id="magicdraw.classes.core">
     1643          <title>Core layer classes</title>
     1644          <para>
     1645          TODO
     1646          </para>
     1647        </sect3>
     1648       
     1649      </sect2>
     1650     
     1651      <sect2 id="magicdraw.diagrams">
     1652        <title>Diagrams</title>
     1653
     1654        <sect3 id="magicdraw.diagrams.create">
     1655          <title>Create a new diagram</title>
     1656         
     1657          <para>
     1658            New diagrams should be added to one of the subpackages inside
     1659            the <code>Data layer/Diagrams</code> or <code>Core layer/Diagrams</code>
     1660            modules. It is very simple:
     1661          </para>
     1662 
     1663          <orderedlist>
     1664          <listitem>
     1665            <para>
     1666            Select the subpackage in the overview and click with the right mouse button.
     1667            </para>
     1668          </listitem>
     1669          <listitem>
     1670            <para>
     1671            Select the
     1672            <menuchoice>
     1673              <guimenu>New diagram</guimenu>
     1674              <guimenuitem>Class diagram</guimenuitem>
     1675            </menuchoice>
     1676            menu item in the menu that pops up.
     1677            </para>
     1678          </listitem>
     1679          <listitem>
     1680            <para>
     1681            The overview will expand to add a new diagram. A new empty diagram
     1682            frame is also opened on the right part of the screen. Enter the name of the diagram
     1683            and press enter.
     1684            </para>
     1685          </listitem>
     1686          </orderedlist>
     1687 
     1688          <note>
     1689            <title>Only class diagrams are fully supported</title>
     1690            <para>
     1691              The community edition of MagicDraw only has full support for
     1692              class diagrams. The other diagram types has limitations, in the number of
     1693              objects that can be created.
     1694            </para>
     1695          </note>
     1696         
     1697          <para>
     1698            To display a class in a diagram, simply select the class in the overview
     1699            and drag it into to the diagram.
     1700          </para>
     1701        </sect3>
     1702
     1703        <sect3 id="magicdraw.diagrams.appearance">
     1704          <title>Visual appearance and style</title>
     1705           
     1706          <para>
     1707            We have defined several different display style for classes. To set a
     1708            style for a class right click on it in a diagram and select the
     1709            <menuchoice><guimenuitem>Symbol properties</guimenuitem></menuchoice>
     1710            menu item. In the bottom of the
     1711            popup, use the <guilabel>Apply style</guilabel> selection list to select
     1712            one of the predefined styles.
     1713          </para>
     1714           
     1715          <itemizedlist>
     1716          <listitem>
     1717            <para>
     1718            Data class: Use this style for all primary data classes in a diagram. It will
     1719            display all info that we are interested in.
     1720            </para>
     1721          </listitem>
     1722          <listitem>
     1723            <para>
     1724            External class: Use this style for related classes that are actaully part of
     1725            another diagram. This style will hide all information except the class name.
     1726            This style can be used for both data layer and core layer classes.
     1727            </para>
     1728          </listitem>
     1729          <listitem>
     1730            <para>
     1731            Association class: Use this style for classes that hold information
     1732            related to an association between two other classes. Classes with this
     1733            style are displayed in a different color. This style can be used for both
     1734            data layer and core layer classes.
     1735            </para>
     1736          </listitem>
     1737          </itemizedlist>     
     1738        </sect3>
     1739
     1740        <sect3 id="magicdraw.diagrams.save">
     1741          <title>Save diagram as image</title>
     1742          <para>
     1743            When the diagram is complete, save it as a PNG image in the
     1744            <filename class="directory">&lt;base-dir&gt;/doc/src/docbook/figures/uml</filename>
     1745            directory.
     1746          </para>
     1747        </sect3>
     1748      </sect2>     
     1749     
    12741750  </sect1>
     1751 
    12751752</chapter>
  • trunk/doc/src/docbook/developerdoc/index.xml

    r3675 r3715  
    3333  <include file="api_overview.xml"/>
    3434  <include file="javadoc.xml"/>
    35   <include file="write_docbook_doc.xml"/>
     35  <include file="documentation.xml"/>
    3636  <include file="core_ref.xml"/>
    3737</part>
  • trunk/lib/docbook/custom-styles/docbook/plain/xsl/customized.chunked.xsl

    r3378 r3715  
    1919<xsl:param name="chunk.fast" select="1" />
    2020<xsl:param name="toc.max.depth" select="4"/>
    21 <xsl:param name="toc.section.depth" select="3" />
     21<xsl:param name="toc.section.depth" select="2" />
    2222<xsl:param name="generate.section.toc.level" select="1" />
    2323<xsl:param name="generate.toc">
Note: See TracChangeset for help on using the changeset viewer.