<?xml version="1.0"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
-->

<document>

 <properties>
    <title>Torque ORM Reference - Extending the Base Classes</title>
    <author email="fischer@seitenbau.de">Thomas Fischer</author>
    <author email="leon@opticode.co.za">Leon Messerschmidt</author>
    <author email="jvanzyl@periapt.com">Jason van Zyl</author>
    <author email="seade@backstagetech.com.au">Scott Eade</author>
 </properties>
 
 <body>
  <section name="Extending the Base Classes">
    <p>
      Much of the power of Torque stems from the fact that you can easily add to
      and change the behavior of the generated classes 
      by adding or overriding methods.
    </p>
    <p>
      To keep your own code changes apart from the generated code,
      Torque provides two classes of a kind for each table:
    </p>
    <ul>
      <li>
        The Base... classes are overwritten each time you regenerate
        the classes from the schema and contain all functionality provided by 
        Torque.
      </li>
      <li>
        The non-base classes inherit from their respective Base Classes,
        but are empty initially.
        They are not overwritten if you regenerate the classes from the schema.
        All code which you add to the data model should go into the
        non-base classes.
      </li>
    </ul>
  </section>
  
  
  <section name="Adding Methods to Peers">
 
    <p>
      Adding methods to Peers will be one of the most common things you will do
      while using Torque. 
      For example, if you want to retrieve objects from the database without
      creating a Criteria objects, you would typically add a corresponding 
      method to the Peer class.
    </p>
  
    <p>
      As an example, consider the bookstore example from the Tutorial. 
      If you often retrieve Books by their ISBN number, you would add the 
      following method to the BookPeer class:
    </p>
 
<source><![CDATA[
public static List<Book> doSelectByISBN(String isbn)
{
    Criteria crit = new Criteria();
    crit.add(BookPeer.ISBN, isbn);
    List<Book> books = BookPeer.doSelect(crit);
    return books;
}
]]></source>
    
  </section>
  
  <section name="Adding Methods to the PeerImpl classes">
 
    <p>
      If you use the delegation approach of the Peer/PeerImpl classes
      to exchange the implementation of the Peer classes 
      (e.g. by inserting mocks for component tests), or if you use the
      PeerImpl classes directly (e.g. in a dependency injection framework),
      you can also make the changes/additions to the Peer classes in the
      PeerImpl classes. If you add a method in the first case, you should
      also add a delegation method to the Peer class.
    </p>
    
    <p>
      Since adding delegation methods is cumbersome, we recommend to add code
      to the Peer class instead of the PeerImpl class if you do not have a
      reason to decide otherwise (like one of the above reasons).
    </p>
  
  </section>

  <section name="Adding Methods to Data Objects">
 
    <p>
      By adding methods to Data Objects, you can add additional behaviour
      to the data objects.
      For example, you might want to order authors by their name in memory.
      To do this, you could make the authors implement the Comparable interface
      and add a compareTo Method: 
    </p>

<source><![CDATA[
public class Author
    extends org.apache.torque.test.BaseAuthor implements Comparable<Author>
{
    public int compareTo(Author other)
    {
        // null handling omitted for simplicity
        return getName().compareTo(other.getName());
    }
}
]]></source>

    <p>
      Then you can sort the authors by name by calling the
      Collections.sort method.
    </p>

    <p>
      To change the behavior of the generated classes, you can override
      an existing method in a generated class.
      For example, if you decide to add validation code to an author
      in order not to allow blank author names, you can override the setter
      method for the name:
    </p>

<source><![CDATA[
import org.apache.commons.lang.StringUtils;

public class Author
    extends org.apache.torque.test.BaseAuthor
{
    @Override
    public void setName(String name)
    {
        // accept blank names which are already in the database
        if (!isLoading())
        {
            if (StringUtils.isBlank(name))
            {
                throw new IllegalArgumentException(
                    "author name must not be blank");
            }
        }
        super.setName(name);
    }
}
]]></source>

  </section>
  
  <section name="Adding Methods to Record mappers">
 
    <p>
      Adding methods to or overriding methods in the RecordMapper class 
      will not often occur in practice. Still, it can be done and should
      be done if the need arises.
    </p>

  </section>
  
 </body>
</document>
