<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE document PUBLIC "-//MAKUMBA//DTD Documentation V2.0//EN" "document-v20-mak.dtd">
<document>
  <header>
    <title>Java Handler Classes</title>
  </header>
  <body>
  <p>
  Java handler classes are classes that implement the "business logic" of the organisation. Every makumba page will look for a handler, and will call its methods when needed. 
  Check also the &lt;mak:newForm&gt; Java handler classes are classes that implement the "business logic" of the organisation. Every makumba page will look for a handler, and will call its methods when needed. Check also the &lt;mak:newForm&gt; to know which methods are called. If a handler class exists, then some operations cannot be performed if these methods are not defined in the handler class. to know which methods are called. If a handler class exists, then some operations cannot be performed if these methods are not defined in the handler class.
  </p>
  
    <section id="handler">
      <title>Handler Discovery</title>
      <p>
      Each page will determine its handler class on first access, after being compiled. If the class changes on disk, a webapp reload is generally needed for the new class to take effect.
      </p>
  	  <p>
      The handler is 'discovered' by decomposing the full path of the JSP page, and finding a class with a matching name. 
      Decomposition breaks the full path at every capital letter, or forward slash. For example, with the page path /student/mycv/indexPersonal.jsp, the following criteria are applied, in order:
      </p>
      
    
     
     		<table>
   				<tr>
   					<th>criterium</th>
   					<th>Java classes checked for</th>
   				</tr>   				
   				<tr>
   					<td>page name</td>
   					<td>StudentMycvIndexPersonalLogic</td>
   				</tr>
   				   				<tr>
   					<td>caps parts of page/directory name</td>
   					<td>StudentMycvIndexLogic</td>
   				</tr>
   				   				<tr>
   					<td>directory name</td>
   					<td>StudentMycvLogic</td>
   				</tr>
   				   				<tr>
   					<td>parent directory name(s)</td>
   					<td>StudentLogic, Logic</td>
   				</tr>
			</table>

  	  	<p>
      		The class name prefix (e.g. java package name) can be regulated per parts of the site in a file called MakumbaController.properties  which can be found in the CLASSPATH (just like MakumbaDatabase.properties). 
      		For example, the file can contain:
      	</p>
		<p>
			/student=org.eu.best<br/>
			/makumba=org.makumba<br/>
			/=test
		</p>
		
		<table>
   				<tr>
   					<th>path</th>
   					<th>Java classes checked for</th>
   				</tr>   				
   				<tr>
   					<td>/student/mycv/index.jsp</td>
   					<td>org.eu.best.MycvIndexLogic<br/>org.eu.best.MycvLogic<br/>org.eu.best.Logic</td>
   				</tr>				
   				<tr>
   					<td>/makumba/tests/x.jsp</td>
   					<td>org.makumba.TestsXLogic<br/>org.makumba.TestsLogic<br/>org.makumba.Logic</td>
   				</tr>
   				<tr>
   					<td>/some.jsp</td>
   					<td>test.SomeLogic<br/>test.Logic</td>
   				</tr>
			</table>
			
		<p>
		There are good reasons to take into account the name of the response page of a form when looking for the business logic. Still, it is the name of the page that contains the form which matters not the name of the action page.
		It is good practice for both pages to actually have the same handler class.
		</p>
		<p>
		All methods of the handlers are http-independent. Methods are non-static, so the handler classes can use inheritance to their advantage. Still, handler classes are singletons (only one instance of a certain class in a JVM). For example, the validation of a form can be in a class that is closer to the actual JSP application (view level) while the more view-independent methods can be in the parent of that class. For example:
		</p>
		
		<p>
		| org.eu.best.minerva.StudentHandler extends org.eu.best.StudentHandler
		</p>
				
    </section>
     
    <section id="Role">
      <title>Role of Java Handlers</title>
 	  <p>1.<br/>
         <strong>find attributes</strong> find attributes unknown by pages. e.g. </p>
     <source> | &lt;mak:object from="best.Student stud" where="stud=$student"&gt; ...&lt;/mak:object&gt; </source>
     <p> If the $student attribute is not known in the page (from a http argument) or in the session, the find{AttributeName}(<a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/Dictionary.html">Dictionary</a> existingAttributes, Database d, String expression) method is called for the Handler object. 
         In this case findStudent(). The handler has to compute the attribute, based on existing attributes, making DB accesses.
   		<br/><br/>
   		<sub>The find{AttributeName} method's name is constructed literally from the name of the attribute (capitalising only the first letter), so dots and other illegal characters for java identifier names, are not to be used. 
   				Also, one shouldn't use 2 attribute names that differ only in the capitalisation of the first letter.</sub>
   		<br/><br/>
   		For example "lbg.$lbg_order" (in an example elsewhere in the specs), will generate a call findLbg_order(otherAttributes, db) and the Java handler will return the default ordering for LBGs (say "name").
	    <br/><br/>
		If the attribute is computed successfully, it is associated with the session (i.e. set as JSP attribute in session scope)
	    <br/><br/>
		If not, an exception will be thrown (typically org.makumba.UnauthenticatedException), and the engine will act accordingly (i.e. ask for authentication).
        </p> 
        <p>2.<br/> 
        <strong>execute action methods</strong> in response to makumba forms. See makumba forms and actions below.</p>
        <p>3.<br/>
        ( later: return query parts, as methods. e.g. &lt;mak:value expr="lbg.$title()" /&gt; will generate a call to method BestInternalLbgTitle(lbg) which can return an OQL expression "concat(lbg.id, \"-\" lbg.name)" (such methods can be put directly in the Makumba data definitions) 
           For now, OQL only accepts count() and sum(), but that can be easily fixed, till then, the method can be replaced by hand: %lt;mak:value expr="lbg.id"/&gt;-&lt;mak:value expr="lbg.name"/&gt; )</p>
    </section>
     
    <section id="initialization">
      <title>Handler Initialization</title>
      <p>Whenever a handler is used in a new context (i.e. with a different set of attributes, e.g. a new page access), a method called checkAttributes(Attributes a, Database db) is looked for and executed, if it is defined.<br/><br/>
       <sub>checkAttributes</sub> can perform sanity checks for attributes used in the respective logic (in case of mismatches, org.makumba.UnauthorizedException is usually thrown), can load attributes that are absolutely needed for page execution (formerly given by the requiredAttributes() method), etc.
     </p>
    </section>
    <section id="transaction">
      <title>Transaction provider configuration</title>
      <p>
		Most handlers provide a Transaction that can be used to perform addition database operations in the Business Logic. 
		The class of this handler can be configured by providing a getTransactionProvider() String, that returns the fully-qualified name of the transaction provider implementation. 
		For the moment, possible values are <sub>org.makumba.db.makumba.MakumbaTransactionProvider</sub> (native Makumba database layer) and <sub>org.makumba.db.hibernate.HibernateTransactionProvider</sub>(Hibernate-driven database layer)
      </p>
    </section>
  </body>
</document>