Makumba Specification

[Data Definitions]  [Query Languages]  [JSP tag library: Intro | Listing | Forms] [Business Logics]  [Summary]

Business Logic (BL)

Attributes

Java Server Pages use attributes to keep the state of the application. Makumba builds upon that its own notion of Attributes that keep the read-only state of a makumba task. They represent the "environment" of that makumba task. The typical example is a JSP page during execution, with its HTTP and session parameters as attributes. Since other kinds of attributes are possible, the attribute specification is kept HTTP-independent. Makumba BL code sees the attributes as an org.makumba.Attributes object.

Java handler classes

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 <mak:newForm> 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.

Handler Discovery

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.

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:

criterium Java classes checked for
page name StudentMycvIndexPersonalLogic
caps parts of page/directory name StudentMycvIndexLogic
directory name StudentMycvLogic
parent directory name(s) StudentLogic
Logic

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:

/student=org.eu.best
/makumba=org.makumba
/=test

path Java classes checked for
/student/mycv/index.jsp org.eu.best.MycvIndexLogic
org.eu.best.MycvLogic
org.eu.best.Logic
/makumba/tests/x.jsp org.makumba.TestsXLogic
org.makumba.TestsLogic
org.makumba.Logic
/some.jsp test.SomeLogic
test.Logic

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.

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:

org.eu.best.minerva.StudentHandler extends org.eu.best.StudentHandler

Role of Java handlers

  1. find attributes unknown by pages. e.g.
    <mak:object from="best.Student stud" where="stud=$student"> ...</mak:object>

    If the $student attribute is not known in the page (from a http argument) or in the session, the find{AttributeName}(Dictionary 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.

    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.

    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").

    If the attribute is computed successfully, it is associated with the session (i.e. set as JSP attribute in session scope)

    If not, an exception will be thrown (typically org.makumba.UnauthenticatedException), and the engine will act accordingly (i.e. ask for authentication).

  2. execute action methods in response to makumba forms. See makumba forms and actions below.

  3. ( later: return query parts, as methods. e.g. <mak:value expr="lbg.$title()" /> 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: <mak:value expr="lbg.id"/>-<mak:value expr="lbg.name"/> )

Handler Initialization

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.

checkAttributes 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.

Login

Login is done as a result of a missing attribute (possibly invoked in checkAttributes), when a find{AttributeName} method is called. The missing attribute is the principal that needs to log in.

If the attribute cannot be found due to wrong login information, org.makumba.UnauthenticatedException is usually thrown.

The principal (the person who logs in) can have more members (e.g. group, Lbg, Company representatives). E.g. the findCompany() method will check to see if the authentication (email_address and password) corresponds to any company representative of that company. If yes, it will return that company.

Login can be done in 2 ways:

  1. (Http basic authentication login: will set the attributes $username, $password )
  2. cookie login: done in a page called login.jsp, in the same directory or (if missing) in any of the parents. It should contain at least:
    <mak:login>
    <input type=text name=username>
    <input type=password name=password>
    <input type=submit>
    </mak:login>

    The login form will pass further (as hidden arguments) all the http parameters it got. Note that <mak:login> is only needed upon automatic login (a page displayed when the user requested another page, that needs authentication). If you wish to ask for login manually in a startup page, a normal HTML form is enough.

To cancel out a certain attribute, in order to produce a new login, the logout tag is available

<mak:logout actor="student"/>

You can remove (cancel-out, logout) multiple attributes from the session by using <mak:logout actor="attribute name"> several times and/or by using the star (*) wildcard, e.g.:

<mak:logout actor="demo_*"/> (attributes whose names start with "demo_")
<mak:logout actor="*app"/> (attributes whose names end with "app")
<mak:logout actor="*"/> (all attributes; this "invalidates" the session)

(Later on, logout request might be done in the business logic, with a method deleteAttributes(param) that can accept either a String (with optional '*') or a String[]. )

(Later: to accomodate servers that don't do session tracking, login can be done by a query condition rather than by doing a query (once per session) to find an attribute. This way, it won't need to do a query (to check the authentication) at every access, but that condition will make sure that authentication is done. )

(<mak:object from="best.Student stud" where ="stud.$login()"> ...</mak:object>
then methodBestSudentLogin("stud") will return "stud.auth.email=$username AND stud.auth.password=$password"
This can be used for http authentication with no session tracking. )

(Later: if an attribute has multiple values, a choose{AttributeName}.jsp page is shown. For example, a super user (for that area) can choose to act as any student, Lbg, or company... A student member of more local Vivaldi teams can choose to act for any of the viv teams, etc. )