# Makumba application example

This is an example for a very simple web application to illustrate the basic princpiles of building web applications with Makumba JSP tag library.

In this example we will build a web application for managing data about our business partners in following steps:

1. Defining data structure - MDD
2. Wrinting JSP pages
   - Listing objects
   - Showing single object
   - Creating new object
   - Editing existing object
   - Fine tuning page layout
3. Business Logic

## MDD - Makumba Data Definition

For explanations please refer to Data Definition section of the specification.

The Makumba Data Definitions (MDDs) can be placed anywhere in the CLASSPATH, in the `dataDefinitions` folder.

    dataDefinitions/organisation/Partner.mdd
    name=not null char[40]       ;Name
    city=char[40]                ;City
    country= ptr general.Country ;Country
    phone=char[20]               ;Phone
    fax=char[40]                 ;Fax
    email=char[40]               ;E-Mail
    homepage=char[50]            ;Home Page on the Internet
    comment=text                 ;Other comments
    personalContacts= set general.Person ; precise personal contacts at the partner

    dataDefinitions/organisation/Country.mdd
    name=char[60]               ;Country
    iso2letterCode=fixed char[2];2-letter ISO code

    dataDefinitions/organisation/Person.mdd
    name=char[60]               ;name
    birthdate=date              ;birthdate

### Changes in the table in the database

To be able to change the table in the database you need to add the following line to the database proprieties <server_name>_<database_engine>_<database_name>.properties, e.g. `example/WEB-INF/classes/localhost_mysql_testdatabase.properties`

    alter#MDD_name=true

(you should comment it after the changes: #alter#MDD_name=true)

In order to create the table or make the MDD changes available, just reload Tomcat (or any engine that implement Java Servlet API).

## JSP - Java Server Pages

For explanation please refer to Makumba JSP tags section of the specification.

### Listing objects

Page `partnerList.jsp` will be showing the list of all partners, each entry with:

- brief summary (name and city)
- link to a page with more detailed information

    example/parnerList.jsp
    <%@ taglib uri="http://www.makumba.org/presentation" prefix="mak" %>

    <h2>Partners:</h2>

    <mak:list from="organisation.Partner p">
       <dt><a href="partner.jsp?partner=<mak:value expr="p"/>">
                    <mak:value expr="p.name"/>
       </a>,
       <i><mak:value expr="p.city"/></i> </dt>
    	<dd><mak:list from="p.personalContacts c" separator="<br>">
    		<mak:value expr="c.name"/>
    	</mak:list></dd>
    </mak:list>

    <hr>
    [<a href="partnerNew.jsp">New partner entry</a>]

If we are starting with an empty database it will be at first rendered to:

## Partners:

[New partner entry]
But once we enter some data it will look more like:

## Partners:

PlasticWing Airlines, Cambridge
  John Doe
  John Smith
Pasta al'Dente s.p.a, Turin
  Benny Andersson
  Bjorn Ulvaeus
Some Company Ltd., Somewherewille
  Robert Wells
ACME gadgets, Death Walley
Protect gamblers, Las Vegas
  Frida
  Agneta
  Cher

[New partner entry]
For additional options see the specification of mak:list and mak:value.

### Object details

Page `partner.jsp` will be showing all fields of `organisation.Partner` objects.

    example/partners.jsp
    <%@ taglib uri="http://www.makumba.org/presentation" prefix="mak" %>

    <mak:object from="organisation.Partner p" where="p=$partner">
        <h2><mak:value expr="p.name"/></h2>

        <mak:value expr="p.city"/>,
          <mak:value expr="p.country.name"/>
        Home Page: <b><mak:value expr="p.homepage"/></b>
        <p>
        You can send them an email to: <mak:value expr="p.email"/><br>
        Call me: <b><mak:value expr="p.phone"/></b><br>
        Comment: <mak:value expr="p.comment"/>
        <p>
        <a href="partnerEdit.jsp?partner=<mak:value expr="p"/>">edit</a>
    </mak:object>

    <hr>
    [<a href="partnerList.jsp">List them all</a>]

Is rendered to:

## Some company Ltd.

Somewherewille, Bangladesh
Home Page: http://www.example.com

You can send them an email to: info@example.com
Call me: +1 23 456789
Comment: They are very rich!!!

edit

[List them all]
Note that OQL expression `p.country.name` was evaluated to "Bangladesh" automagically. Makumba joined the Partner and Country tables when performing the query, and can make even more sophisticated table joins when needed.

For additional options see the specification of mak:object and mak:value.

### New object creation

Page `partnerNew.jsp` will require only the basic info when creating a new object:

    example/partnerNew.jsp
    <%@ taglib uri="http://www.makumba.org/presentation" prefix="mak" %>

    <h2>New partner</h2>

    <mak:newForm type="organisation.Partner" action="partnerList.jsp">
       Name: <mak:input name="name"/> <br>

       City: <mak:input name="city"/> <br>
       Country: <mak:input name="country"/> <a href="countryNew.jsp">Add countries</a><br>
       <input type="submit" value="Create">
    </mak:newForm>

    <hr>
    [<a href="partnerList.jsp">Back to list</a>]

## New partner

Name:
City:
Country:
Add countries

[Back to list]
The user can decide to omit city and country information as well, but due to the `not null` attribute of field `name` in the MDD, Makumba will not create a new object unless some name is specified.

Page `countryNew.jsp` looks almost the same as `partnerNew.jsp`:

    example/countryNew.jsp
    <%@ taglib uri="http://www.makumba.org/presentation" prefix="mak" %>

    <h2>New country</h2>

    <mak:newForm type="general.Country" action="partnerList.jsp">
       Name: <mak:input field="name"/> <br>
       ISO code: <mak:input field="iso2letterCode" size="5"/><br>
       <input type="submit" value="Add">
    </mak:newForm>

    <hr>
    [<a href="partnerList.jsp">Back to list</a>]

## New country

Name:
ISO code:

[Back to list]

For additional options see the specification of mak:newForm and mak:input.

### Editing existing objects

In `partnerEdit.jsp` we could edit all (non-fixed) fields, but here we decided to not support editing of some fields (Field `name` in this case)

    example/partnerEdit.jsp
    <%@ taglib uri="http://www.makumba.org/presentation" prefix="mak" %>

    <mak:object from="organisation.Partner p" where="p=$partner">
       <h2>Edit <mak:value expr="p.name"/></h2>
       <mak:editForm object="p" action="partnerList.jsp">

          City: <mak:input field="city"/> <br>
          Country: <mak:input field="country"/>
            <a href="countryNew.jsp">Add countries</a><br>

          Home Page: <mak:input field="homepage"/>
          <p>
          Email: <mak:input field="email"/><br>
          Phone: <mak:input field="phone"/><br>
          Comment: <mak:input field="comment"/><br>
          <input type="submit" value="Save">
       </mak:editForm>

       <mak:deleteLink object="p" action="partnerList.jsp">Delete this</mak:deleteLink>

    </mak:object>

    <hr>
    [<a href="partnerList.jsp">Back to list</a>]

## Edit Some Company Ltd.

City:
Country:
Add countries
Home Page:

Email:
Phone:
Comment: They are very rich!!!

Delete this

[Back to list]

For additional options see the specification of mak:editForm, mak:input and mak:deleteLink.

### Fine-tuning layout

Always make things work first, then bother with details.

In order to keep your code as clean as possible, we advise you to break it down into small, human-managable files and include them in your pages with <jsp:include /> directive, eg:

    <jsp:include page="header.jsp"/>

You can also take some size of the .jsp files and improve their readability by seperating the layout specification into seperate Cascading Style Sheets.

## BL - Business Logic

Makumba protects the changes in the database thus to be able to add, edit and remove records you have to define the respective methods.

For this example you will need to define the following methods in, for example, Logic.java. See how makumba looks for the handlers.

`public void on_newPartner(Dictionary d, Attributes a, Database db) {}`
`public void on_editPartner(Pointer p, Dictionary d, Attributes a, Database db) {}`
`public void on_newCountry(Dictionary d, Attributes a, Database db) {}`
`public void on_deletePartner(Pointer p, Attributes a, Database db) {}`

Do not forget that you have to compile after changing a java file.

More about business logic