Kauri Documentation
Book Index

# 1 Documentation Home

## 1.1 Kauri 0.4 Documentation

Welcome to the Kauri documentation.

Check our documentation service for other releases and off-line/printable (e.g. pdf) Daisy-books.

### 1.1.1 First Experience

If this is your first visit and contact with the project you probably want to start off with either one of our introduction trails:

• Getting started will help you take the most basic steps to download and install Kauri for you, and follows up by showing the typical development setup. It ends with the generation of a hello-world sample project.  This is the shortest track to an environment for further self-exploration and toying around.
• The  Step by step Tutorial takes a more guided approach. And while we do recommend trying out all the steps along the way on an installed Kauri, you might choose to just read it through to get a better feel of what this is all about.

### 1.1.2 The core

After these you should be set to integrate whatever back-end system into your own module to effectively disclose it via your own REST-full interface. For 'classic' RDBMS stuff, you will find some inspiration in the section on  JPA database resources.

### 1.1.3 Front-end development

Bridging the gap from web-service to web-sites these sections are recommended:

• The  Prototyping section offers an approach that allows front- and back-end developers to collaborate in parallel rather then consecutively on the same project.
• From there you'll find natural links into the technical details for building display ( templates) and interactivity ( forms) screens.
• The Representation builder shows how an MVC like model is supported on top of the previous techniques.

### 1.1.4 Miscellaneous Modules

A number of typical non-functional requirements in web development get their special attention here:

As well as a practical approach to the issue of dealing with  Temporary Resources in a REST oriented environment.

### 1.1.5 Deployment and Administration

Towards deployment the relevant sections are those about:

Revisiting the   configuration section might make sense as well.

### 1.1.6 Reference Sections

Most of the sections mentioned above have detailed explanations on exact use (included detailed syntax samples) at the end. This list just helps you access those reference sub-sections directly:

## 1.2 Known Issues

Post release reported issues you should know about:

#### 0.4-RC2

There is a glitch in the pom.xml of the archetypes.  When you are Creating a Kauri project using the archetype you should modify the pom.xml after generation so it shows the correct matching/shipped restlet version:  (ie 6950, not 6565)

<version.restlet>svn6950</version.restlet>

# 2 Getting started

## 2.1 Welcome

New to Kauri? Ready to start playing with it?  Then, this section of the documentation is for you.

We recommend reading it completely: just keep following the "Next" link in the browse-section on the right-hand side of this page.  In the process you will be guided through

• finding and trying our samples,
• setting up your developer environment, and
• starting off your first try-out-project.

The idea here is to actively get you going and leave you with a basic setup for your further exploration.

## 2.2 Installing Kauri

### 2.2.1 Installing the Java JDK

If you have Java installed, you can skip this section.

Kauri is Java-based web application framework. To run it you need to install Sun Java version 5 or higher. To check which Java version you have installed, excute:

java -version

If you want to develop Kauri applications, be sure to download the JDK, not just the JRE.

Set an environment variable JAVA_HOME pointing to your Java installation. You can again check everything is fine by executing:

Unix

The property name follows the syntax groupId!artifactId. In the property value you can refer to the directory containing the wiring.xml file using ${kauri.config.basedir}. ### 2.8.1 Try it Starting from a blank project archetype, assuming it is built, start it using the additional -s parameter: [Windows] %KAURI_HOME%\bin\kauri -s module-source-locations.properties [Linux]$KAURI_HOME/bin/kauri -s module-source-locations.properties


Surf to

http://localhost:8888/resources/helloworld.html

and notice the displayed text.

Now modify the helloworld.html file, which you can find at:

module1/src/main/kauri/resources/helloworld.html

If you refresh in your browser, you should see the results immediately, without doing "mvn install" nor restarting Kauri.

## 2.9 Static resources

This section assumes you have a blank project created from the project archetype.

The default project as created by the project archetype will automatically make all files below

module1/src/main/kauri/resources/*

available in the URL space at

http://localhost:8888/resources/*

This works because all requests for /resources are routed to a static file server component which reads the files from the corresponding src/main/kauri/resources directory. The routing configuration can be found in the file:

module1/src/main/kauri/router.groovy

which contains a line like:

directory(uri: "/resources", root: "module:/resources/")

The module:/ protocol allows to read the resources in the Kauri module. In the source tree these are the files from src/main/kauri, in the compiled jar these are in the KAURI-INF subdirectory.

You could try adding another routing like this:

directory(uri: "/resources2", root: "module:/resources/")

and verify that you can access:

http://localhost:8888/resources2/helloworld.html

Note: when running in source mode this will work immediately, otherwise you'll have to run "mvn install" and restart Kauri first.

## 2.10 Dynamic resources

Dynamic resources can be created in several ways. One is using the Restlet API, another one is using the more standard and somewhat higher-level JAX-RS API. In the examples below, we will use JAX-RS.

### 2.10.1 Examples

#### 2.10.1.1 Hello World

Suppose we want to create a "Hello, world!" resource. A resource is implemented by creating a Java class, which we call a resource class.

Assuming you created a project where the default router configuration and REST-service mounts are present, you can do so by creating a Java class, for example at:

module1/src/main/java/com/mycompany/module1/HelloWorldResource.java

The name and package of the class do not matter, you can take anything you like.

The HelloWorldResource.java can be implemented as follows:

package com.mycompany.module1;

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;

@Path("helloworld")
public class HelloWorldResource {

@GET
@Produces("text/html")
public String get() {
return "<html><body>Hello, world!</body></html>";
}
}

The JAX-RS API makes extensive use of annotations. By adding the annotation @Path("helloworld"), the resource will be available at this path in the URI space. GET-requests will be handled by the get() method because it has an @GET annotation. The method could have had any other name. There are no interfaces to implement, nor method naming conventions to be followed. Using these annotations, you can easily turn any Java object into a Web resource.

Your module jar will be automatically scanned for classes with JAX-RS annotations, so there is no central configuration to update (see also the notes on router configuration further on).

If you add the above class to your project, build it using "mvn install", and (re)start Kauri, you can access the resource at:

http://localhost:8888/helloworld

#### 2.10.1.2 Personalized hello

Let us make the sample somewhat more interesting, by saying "Hello, {your name}!". For this, we want to address this personalized hello-resource using an URI path like "hello/Steven". The listing below shows how this is done.

package com.mycompany.module1;

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.PathParam;

@Path("hello/{name}")
public class HelloWorldResource {

@GET
@Produces("text/html")
public String get(@PathParam("name") String name) {
return "<html><body>Hello," + name + "!</body></html>";
}
}

To see this in action, recompile the project using "mvn install" and restart Kauri. Then go to:

http://localhost:8888/hello/Steven

The special syntax using the curly braces {} in the @Path annotation follows a specification called URI templates.

#### 2.10.1.3 Hello via a template

Instead of using string concatenation to build the HTML, let us use a template instead.

The resource class becomes:

package com.mycompany.module1;

import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.PathParam;

import org.kauriproject.representation.build.KauriRepresentation;

@Path("hello/{name}")
public class HelloWorldResource {

@GET
@Produces("text/html")
public KauriRepresentation get(@PathParam("name") String name) {
Map<String, Object> data = new HashMap<String, Object>();
data.put("name", name);
return new KauriRepresentation("hello", data);
}
}

The template file should be defined at:

src/main/kauri/templates/hello.xml

The name of the template corresponds to the first argument of the KauriRepresentation constructor, plus xml extension.

Its content could be as follows:

<?xml version="1.0"?>
<html>
<body>Hello, ${name}!</body> </html> ### 2.10.2 About JAX-RS in Kauri #### 2.10.2.1 Decentralized URI management, routing When using JAX-RS, the URI space is built by adding @Path annotations to individual classes. This is a decentralized approach to specifying the URI space: there is no central configuration file listing all the URIs (or URI patterns). By default, Kauri will automatically scan the module jar file for all classes having @Path annotations, and make them available in the URI space. The routing towards these JAX-RS resources is, as for the static resources, configured in: module1/src/main/kauri/router.groovy the relevant part is:  jaxRs(uri: "") { jaxRsResource(scanPackages: "*") jaxRsProvider(scanPackages: "*") jaxRsGroovyScripts(path: "groovy-jax-rs") } See also the jaxRs instruction reference documentation. #### 2.10.2.2 About the objects returned from resource methods In the examples above, the get() method returned either a String object or a KauriRepresentation object. If the return object is String, then the JAX-RS system itself knows how to create the response representation from this. But the method can in fact return any kind of object, thus also your own "business objects" like Product, Order or User. JAX-RS has a mechanism of pluggable MessageBodyWriters that know how to convert a certain kind of object to a stream of bytes. See the JAX-RS API for more information on this. Registering these writers in Kauri is done through the jaxRs instruction in the routing configuration (router.groovy). For the template sample, we returned a KauriRepresentation object. This is a special case, as it extends from Restlet's Representation class. The JAX-RS implementation of Restlet treats these in a special way, or better does not treat them at all, it simply passes them through to Restlet. The KauriRepresentation is a special kind of representation: in fact, it only specifies a logical name for the representation to use (in the example above, "hello"), and based upon a configuration, this logical name is mapped to the actual representation to use. By default, this name is mapped onto a template to execute. See the representation builder for more information on this system. # 3 Step by step: Kauri prototyping and application building ## 3.1 How to use this tutorial ### 3.1.1 Do as you go In this step-by-step tutorial you will build a first Kauri application to manage a simple blog of entries and categories. It is by no means a reference guide or complete feature overview. We do assume you follow the steps in a hands-on fashion: trying things out described in each step as we go along. This approach assumes you have downloaded and installed Kauri properly (see instructions for download and getting started) ### 3.1.2 Only read Alternatively you can just read through the concepts and samples to get a first glimpse of what Kauri is about, leaving the hands-on experience for later. The resulting "tutorial-myblog" project is included as a sample in the distribution. ## 3.2 Generate the project structure. ### 3.2.1 Creation of a template application #### 3.2.1.1 Generation of the project structure With maven, Java and Kauri installed we can get started by using the maven archetype to create a standard Kauri application project layout. The binary distribution holds a handy script "kauri-project-template" to trigger this archetype based project generation: [Windows] c:\path\to\kauri-<version>\bin\kauri-project-template [Linux] /home/you/kauri-<version>/bin/kauri-project-template.sh in the script you'll have to choose: Choose archetype: 1: local -> kauri-archetype-basic (A Kauri project with one module) 2: local -> kauri-archetype-prototyping (A Kauri project with typical setup to start prototyping) Choose a number: (1/2):  Pick 2 to create a prototyping application. Then press 'N' to grab the opportunity to modify the defaults into the values suggested below: Confirm properties configuration: groupId: com.mycompany artifactId: myapp version: 1.0-SNAPSHOT package: com.mycompany Y: : N Define value for groupId: com.mycompany: : org.kauriproject.tutorial.myblog Define value for artifactId: myapp: : myblog Define value for version: 1.0-SNAPSHOT: : Define value for package: com.mycompany: : org.kauriproject.tutorial.myblog Confirm properties configuration: groupId: org.kauriproject.tutorial.myblog artifactId: myblog version: 1.0-SNAPSHOT package: org.kauriproject.tutorial.myblog Y: : Running this command generates a complete project structure. This tutorial will touch upon the relevant elements of that as we go along. A full description is in the Kauri Project Structure. In the odd event you are running Kauri from your own source-code-checkout, you can call maven directly to create the archetype. The exact howto is explained in Using the archetype The directory layout for the application will be created in a newly created subdirectory at the "working" directory location. (i.e. your position at the time of running the script.) #### 3.2.1.2 Compile and startup the application Once the application is created, we should be able to compile it: cd ./myblog mvn install And also start it up (in prototype mode) <KAURI_HOME>/kauri run -s module-source-locations.properties -p prototype Once you've done this, the newly created application is running by default on port 8888. By surfing to http://localhost:8888, you should see this page: #### 3.2.1.3 Import your application in your development environment Use eclipse to set some (classpath) variables for your IDE: Eclipse: mvn eclipse:eclipse Idea: mvn idea:idea After this, you can import your newly created application in the IDE you use. ## 3.3 Wire-framing with templates ### 3.3.1 Drawing a first wire-frame #### 3.3.1.1 Introduction The first thing we want to address in this project is the overall behaviour of the web application: "Which pages link to where, what will be on which pages, how end-users will interact." In web-designer and information-architect circles this work is often tackled through so called wire-frames. In Kauri we foster this approach and throw in our to help speed up the process and to keep these prototyping steps as a basis for future work. Indeed rather then throwing these design-time files away, we will extend them during next phases and foresee an active role for them in the actual implementation. ##### 3.3.1.1.1 Templating During the wire framing phases itself these techniques allow you to benefit from envisioned reuse. An early opinion on visual consistency, slight variants and reuse of graphical elements can be captured in the templating language right away: making the creation of the wireframe snappier and taking considerably more active steps towards further functional development. ##### 3.3.1.1.2 Page naming & auto-routing Likewise, a nowadays common sensitivity for the URIs (and which parts it is composed off) is easily layed down in the folder and file names picked up by our 'pages' routing-support. Both of these are already activated in the generated project. If you haven't started your project yet, do so now [linux]$ kauri.sh run -s module-source-location.properties -p prototype

[windows]
> kauri.bat run -s module-source-location.properties -p prototype

This keeps your project running, and (through the -s option) hooked to the source-files as you edit them: simply refreshing in the browser will show the effects of any changes immediately.

#### 3.3.1.2 Which pages do we want?

And how will they be addressable (and indexed by search engines)?

It really doesn't matter if the sense for "cool URIs" comes from an opportunistic SEO drive or a more fundamental vision or REST awareness.

##### 3.3.1.2.1 User Stories

Being a web-site in the works our 'myblog' project will have the archetypical "home/index"  page serving as an entry point (that was easy).  We want it to show the first x lines/paragraphes of the last 3 entries in the blog, each having a permalink pointer behind the title, and behind a 'read more>>' link.

That should lead to an entry-detail page that shows the full contents of the blog-entry (and some meta-data as author, tags/categories/keywords, publication/creation date-time.  Browsing through these entry-detail pages will be done through previous-next links on the page.

The tags should be listed on the home page, and provide links to overview-pages that will list all entries associated to that tag. The list here will look like the list on the home page.  In fact both (all) lists of entries should be sorted on publication-date (descending) and have some paging ability (ie. be cut off to say length 20, and provide a link to 'older entries')

We foresee (of course) a management interface to add new entries, and control old ones (edit, unpublish, remove).

##### 3.3.1.2.2 URIs

Based on this minimalistic analysis we get the following list of template-pages we need to provide

NAME

@URI_TEMPLATE

=Description

home

@ /
@ /index.html?page.before=YYYY-MM-DDTHH:MM:SSZ&page.size=20

= entry-point, links to tags, older entries and details of listed entry

entry

@ /entry/{pubdate_key}/{title_for_seo}

= detail for specific blog entry, links to previous, next

tag

@ /tag/{name}?page.before=YYYY-MM-DDTHH:MM:SSZ&page.size=20

= list of entries with that tag

@ /manage?page.before=YYYY-MM-DDTHH:MM:SSZ&page.size=20

= list of entries with options to remove/edit/unpublish/

entry-form

@ /manage/new
@ /manage/{pubdate-key}

= form to create new or update existing entry

Note the usage of the {name} placeholders in the URI-paths. These indicate the ROLE or semantics of that part of the path.  This notation comes from the uri-templates specification which is used throughout the system to describe how the URI of requests should be matched, interpreted and routed.

By using these literally (i.e. with the { and } characters in there!) as the names for the folders and files on disk the 'pages' router in Kauri will automatically promote these pathnames-on-disk into active uri-templates.  It will thus match patterns rather then actual literals, and provide the recognized parts to the template logic as ready variables.

So in our case since the uri-template: /entry/{pubdate_key}/{title} will match a family of request-URIs like: /entry/2010-08-04T07:01:00/about-page-routing.  To obtain this we simply provide the following in our project:

[myblog]/src/main/kauri
+-- pages
+-- entry
+-- {pubdate_key}         # Yes, your folder name holds the { and } characters
+-- {title}..xml       # Yes, your file-name holds two periods.

About the double-period notation: the contract is this: the second extension is removed from the actual uri-template. This trick allows to provide an extension to your file that makes it recognizable to your development tools (an xml template file to be opened in your xml editor) without having it ripple through in the URI-scheme. Check out the pages router for a full description of how file-system paths are translated into uri-templates.  The double-period ..xml thus indicates that the path will have no extension.

In the {title}..xml template we will be able to use the matched names as variables. So for the sample request URI we mentioned above we will get something like:

variable

value

pubdate_key

'2010-08-04T07:01:00'

title

##### 3.3.1.2.3 Benefits

Recognizing these 'uri-templates' upfront reduces the work to be done: Only single template-pages need to be developed, not a set of individual individual (copy-pasted and then ill-synced) sample instance pages

More benefit to this approach is in the fields documentation and project-management:  Marking {roles} in the paths/names of these templates communicates in a natural way (ie. built-into the project source code) more of the design-time insight to the further development process.

#### 3.3.1.3 What is on these Templates?

So, we are ready to lay out the 'paths' and create the distinct templates, but not without some more consideration for elegance and efficiency to actually fill them up.

The previous section described how recognized templates can be captured using the built-in uri-templating: a simple mechanism to catch all same-looking pages into one {role}-named template. The next analysis effort is in recognizing the recurring zones, bits and pieces in these templates.

Like in the previous section, this will result in

•  further work-optimization during the wire-framing (avoiding copy-paste)
•  higher visual consistency across the site
•  unambiguous communication of which pieces are intentionally looking alike.

Looking at our my-blog sample we see the different pages should have a lot in common.  The diagram below graphically represents the important relations between these templates:

• <<inherit>> relations show how the templates implementing end-user facing page-impressions should all derive from one common layout
• <<includes>> relations show bits of html snippets that should be reused in different pages
• <<linksTo>> relations show how one page will link to another

To capture this Kauri's templating language naturally provides the t:inherit (reusable general layouts) and t:insert (reusable snippets) statements.

See the reference, starting of at the basic rules for all syntax details of the template language.

#### 3.3.1.4 Do It Yourself

With the above thinking done, we can fully list the template files we need to create:  (we shortened some names for convenience)

main-module/src/main/kauri/
|-- pages
|   |-- entry
|   |   -- {key}
|   |       -- {title}..xml
|   |-- index.html.xml
|   |-- manage
|   |   -- {key}..xml
|   |-- manage..xml
|   -- tag
|       -- {tag}..xml
-- templates
|-- layout
|   |-- footer.xml
|   -- layout.xml
-- snippet
-- entry-list.xml

We separate the 'pages' from the 'templates'.  The pages are the ones that are end-user-facing. They get a URI assigned to them which makes them publicly accessible.
Even if those too just use the template language, we keep them separate from the strictly internal templates that help out managing the reusable layout and recurring snippets.

Don't delete or change any of the generated files yet.
Just create the missing ones, and fill those with some basic XML that makes them avoid errors:

<?xml version="1.0"?>
<html xmlns:t="http://kauriproject.org/template">
TODO
--
preferably enhanced with some idea of what this particular page should show
</html>

As we go along these files will be further enhanced and more details of templating and routing will be touched upon.  For now we'll just show the basic principles that make up the essence of the wire-framing job:

1. Learn how the layout inheritance works (and introducing header and footer)
2. Learn how template inclusion works
3. Putting down the links between the various pages.
4. Show how the matched part of uri-templates is made available in the templating.
##### 3.3.1.4.1 Inherit and extend a common layout

This first part is really easy because it is already in use by the generated templates:  pages/index.html.xml declares an inheritance on templates/layout/layout.xml. It does so in the first line:

<html t:inherit="module:/templates/layout/layout.xml" xmlns:t="http://kauriproject.org/template">

This layout.xml template declares the general layout structure and leaves room for so called 'blocks' that can be overridden in the templates that inherit from this template.  These just provide blocks with matching names that will replace the ones from the parent.
You can see how the layout.xml declares the blocks named title and content. And how the matching blocks in the index.html.xml page actually replace those.

To satisfy the various <<inherit>> relations in the diagram above we just apply the same layout to all the actual end-user-facing pages. This is what you do:

1. add the above inheritance declaration (t:inherit="module:/templates/layout/layout.xml") to the root element of all the templates in the pages directory (not to the ones in templates)
2. then move the earlier TODO text into a <t:block name="content"> ... </t.block>

Don't worry too much about the path starting with the pseudo-protocol:  module:/ for pointing to the layout-master-template.  It is explained in our section about uri-resolving.
For now it suffices to know that these absolute references a reresolved against the root of the kauri-resources of your module. (in your module source files that means, relative to [module]/src/main/kauri)

You can simply use relative paths as well for the t:inherit attribute. But depending on their position the reference to template/layout/layout.xml would need to be prefixed with one or more ../
In this case the 'absolute' version is more appropriate.

As a sample, here is how pages/entry/{key}/{title}..xml should look for now:

<?xml version="1.0"?>
<html t:inherit="module:/templates/layout/layout.xml" xmlns:t="http://kauriproject.org/template">

<t:init>
<t:variable name="page_title"  value="TODO: should become the title of the entry"/>
</t:init>

<t:block name="title">${page_title}</t:block> <t:block name="content"> <h1>${page_title}</h1>
TODO entry detail page
</t:block>
</html>

Notice how we also override the title block and how the ${...} syntax is used as a placeholder for expression evaluation during template execution. This allows to define the page_title once and inject its value • both in the header/title of the page • and in the h1 element in the content-body. More details about inheriting templates (like why use <t:init>) is in the Template inheritance section. ##### 3.3.1.4.2 Include re-useable template-snippets Next we realize the <<includes>> relations from the diagram above. Just drop in a <t:include> with appropriate src attribute: i.e. pointing to the template-file you want to include. For the layout.xml page we push out the header/footer sections to different XML files. <?xml version="1.0"?> <html xmlns:t="http://kauriproject.org/template"> <head> <title><t:block name="title">[title]</t:block></title> <link rel="stylesheet" type="text/css" href="${publicUri('service:/main/static/css/main.css')}"/>
<script type="text/javascript" src="${publicUri('service:/main/static/js/basic.js')}"/> <t:block name="extraHeaders"/> </head> <body> <t:block name="header"><t:include src="header.xml" /></t:block> <t:block name="content"/> <t:block name="footer"><t:include src="footer.xml" /></t:block> </body> </html> Being a master-layout page it is wise to wrap the include statements into separate blocks so inheriting pages can choose to override in any way. A similar include should be used for reusing the list of entries on the index, tag-overview and management pages. On those pages you can just leave a:  <t:include src="/templates/snippet/entry-list.xml" /> somewhere in the content-block (i.e. <t:block name="content">) The snippet-file itself can then look like this for now: <?xml version="1.0"?> <div xmlns:t="http://kauriproject.org/template"> <!-- we will need to think about injecting title and data for this list to produce --> <h2>TODO injected title</h2> <ul class="entry-list" > <t:variable name="permalink" value="${publicUri('service:/main/entry/some-key/some-title')}" />
<li>
<a href="${permalink}" >TODO some-entry-title</a><br /> TODO some entry summary<br /> <a href="${permalink}" >read more >></a>
</li>
</ul>

</div>

You should see this dummy list now included on the various pages where you added the <t:include> directive.

##### 3.3.1.4.3 Linking your pages in a module-reuse-world

Marked in the above sample we introduce an unfamiliar way to link up the pages in your design.

${publicUri('service:/main/entry/some-key/some-title')}  What is going on? Well two things in fact. The first observation is that we can't simply use relative links in this entry-list page. Since it will be embedded inside different pages we cannot be sure that the base path of those will always be the same, and thus that we can pin down the correct relative path towards the detail pages. In our example the usage inside the manage..xml template would suggest a relative permalink to "entry/**" while the inclusion in tag/{tag}..xml would need "../entry/**" to work properly. By switching to an absolute reference "/entry/**" we can easily service both usage scenario's. Only we can't be sure about / being the actual public URI that points to the root of the service we are building. Therefor we ask the framework (who does now about this configuration aspect at run-time) explicitly to translate our URI into a public reference with the publicUri function. People familiar with other component based web app frameworks should not be too surprised about this. The actual mount-point for the various public services in your module is covered in the wiring.xml file. This got generated in the first step, and is at [myblog-root]/conf/kauri/wiring.xml. Which services your module is providing is declared in the spring-bean xml files inside src/main/kauri/spring/** using the export-restservice tag described in the Spring config reference In short: you can ignore this publicUri() technique only: • if the usage context of the template guarantees that relative URI's will work • if the usage context of the module guarantees that / will surely be your entry-point. "Being sure" about these aspects translates into documenting it and describing it as known limitations of your template and/or module. So back to work: With this understanding you should be able to put down the various <<linksTo>> relations foreseen in the analysis diagram. ##### 3.3.1.4.4 Grab the matched part of a uri-template Finally we are ready to abuse the dynamic parts introduced by the uri-template technique. By creating the template at pages/tag/{tag}..xml we are sure to match any /tag/my-topic. Now here is how we can use the actual matched {tag} in our template: <?xml version="1.0"?> <html t:inherit="/templates/layout/layout.xml" xmlns:t="http://kauriproject.org/template"> <t:init> <t:variable name="tag" value="${request.attributes.tag}"/>
<t:variable name="page_title" value="Entries for topic ${tag}"/> </t:init> <t:block name="title">$page_title</t:block>
<t:block name="content">
<h1>${page_title}</h1> <t:include src="/templates/snippet/entry-list.xml" /> </t:block> </html> The internal routing and matching will make the matched {tag} part from the uri-template available as a request-attribute with the matching name. #### 3.3.1.5 Conclusion Kauri offers more then the simple-read-static-files support from your average file-system or bare bones web-server. By using the built-in pages-router and the template language the initial design phases of new projects (the so called wire-framing) can both • be more efficient itself as well as • be of higher quality for later follow up. The resulting work shows more visible traces of recognized recurring visual elements and uri-patterns. Since all of this runs in 'source' mode no project builds or service restarts are required. The typical fast round-trip of the designer-cycle template-save-and-test-in-browser is maintained. Finally the wire-framing work doesn't need to be thrown away and redone in a more dynamic language. The same files can be extended and kept live (and thus up to date) as development continues. This is especially important in environments where development of one part is in parallel with the analysis and design work on new sections and modules. ## 3.4 Prototype a data-service with JSON ### 3.4.1 Introduction Up to now we've been using Kauri to build up the pages that will make up the 'web-site' part of our application. The application interface for the end-user interactions. Our ambition however is to build a 'web-service' as well. Targeted for machine-machine consumption, this will deliver controlled access to the unformatted data structures (representations in json or XML format). Still in prototyping mode, Kauri offers a simple mechanism to sketch the messages to be exchanged in these RESTful data-services. Rather then stepping directly into entity-relation modeling or development of the database back-end we will just draft out some json structures in simple text files. These function as 'sample' data for simulating the actual persistence features of the eventual production web-service our application needs. This makes it possible to further enhance our wire-frame-templates making them really data-aware and dynamic: suitable for actual deploy time use. Even better: this way of working helps define the URI space and the expected exchange messages to and from the persistent service. We will use this prototyping mode to create blog posts (entries). On top of this mock service (driven by our json samples) we will complete our templates and interactive pages. Later, we will explain how in production mode, the actual persistence service can be build, and swapped in. #### 3.4.1.1 Location of the JSON mockup data The JSON files should be put in the /mockdata directory of the Kauri folder. By using the maven archetype for creation of our application, there is allready a /persons directory present with an example json file 1.json. Change that into something that better fits our needs: -- myblog |-- conf |-- main-module |-- src |-- main |-- kauri |-- mockdata |-- entry |-- 2010-08-24T14:46:32.json |-- 2010-06-30T12:13:00.json #### 3.4.1.2 Creation of the JSON data As hinted above we will create two sample files representing some simple blog posts. The flexibility of the json notation allows us to easily provide additional fields to these samples as we go along. For starters we should provide (title, content, summary, key/creation-date) The names of the files will be used as identifiers for the entities. Suggested sample: { "title": "Lily sees the light ... almost!", "summary": "This should just grab something like the first 100 characters from the content by default." "content": "<p>This is <b>the second day</b> of the very well organized .... (a lot more text)" } { "title": "A NoSQL Summer: Belgium/Ghent edition", "summary": "<p>A NOSQL Summer is a network of local reading groups, that will decipher and discuss "content": "<p>A NOSQL Summer is a network of local reading groups, that will decipher and discuss .... more more more" } #### 3.4.1.3 Checking the service At this point you should restart your running Kauri-instance to let it pick up these new sample files. To check whether you've put the files at the right place and if the router's configured correctly (this should be the case if you've created your template application with the Maven archetype), try surfing to the following URIs http://localhost:8888/data/entry/ http://localhost:8888/data/entry/2010-08-24T14:46:32  The response should contain the contents of the corresponding json files. You can check what the server actually responded (like HTTP headers and stuff) with a tool like Firebug or the development tools of Chrome. Finally you can also create new content into this service through standard PUT operations. To do this from your browser you'll typically need some add-on like the excellent "Poster add-on" for firefox or its "Google Poster" counterpart for Chrome. You can create or update the entities in the simulated persistence service. Check out the images for some samples to try out: ## 3.5 Pulling and displaying data #### Pulling data Now that we have created the data, we can pull it and display it in the pages. The complete URI to pull a certain blog item is: http://localhost:8888/data/items/1. To get all items it is: http://localhost:8888/data/items. ##### Getting mock data resources Let's first focus on the bask part of the url, which is of structure (* = 0 or more occurences, ? = 0 or 1 occurence): /entityname(/id/propertyname)*(/id)? ###### Example /items/1 will return the entity with ID 1 (i.e. entity in file mockdata/items/1.json) /items/ will return a JSON array containing all 'items' entities (i.e. all entities in directory mockdata/items/) There are lot more possibilities with these structures, check the DB resources pages in our manual if you want to know more about it. ##### The URI explained The complete URI to get item with ID 1 is http://localhost:8888/data/items/1. Notice the /data part which prefixes the entity name (items) and ID (1). Where does that come from? On the one hand, there's the mounting of services which happens in wiring.xml:  <artifact id="module1" groupId="org.kauriproject" artifactId="module1" version="1.0-SNAPSHOT"> <mount name="data" path="/data"/> </artifact>  This mounts the data service on URI path /data. More about wiring is to be found in this section. On the other hand, there's the spring configuration of services in services.xml. In the structure of your blog application, you'll however find 3 services.xml files. The common one will allways be used, whatever mode you are using. The one in directory /prototype will be used in case of prototyping mode (like we are at this moment). The other one will be used when switching to production mode. The difference between the 2 is what we are using as data service. In prototyping mode we want to use our mockup (JSON) data, and not a database. That is what's defined in prototyping/services.xml:  <bean id="data" class="org.kauriproject.dbresources.mock.DbMockFinder"> <constructor-arg ref="restletContext"/> <constructor-arg ref="module"/> <constructor-arg value="mockdata"/> </bean> When we will startup Kauri in production mode, the production/services.xml is used, and another data service is loaded. #### Structure of our pages folder and naming of the pages In our router we can find some configuration that routes everything not explicitly configured elsewhere in the router, is routed via pages.  mode(uri: "", when: "all,-prototype") { pages(root: "pages") } So if we'd like an URI layout • http://localhost:8888/items/1.html to display entity with 1 • http://localhost:8888/items/all.html to display all entities we can realize this by structuring our pages folder as follows: -- myblog |-- conf |-- module1 |-- src |-- main |-- kauri |-- pages |-- items |-- {id}.html.xml |-- all.html.xml Because of the configuration of the router, the file paths are usable as URI templates. Beacuse of this, we can use request attributes as variables in the filenames. This explains the filename {id}.html.xml. So if we browse to url /1.html we will we routed to the page {id}.html.xml and the '1' will be used as the value for request parameter ID. By using the pages router, each .html you browse to, will be routed to the corresponding .html.xml file on your filesystem. This is because the page templates are in fact xml files, and not html files. #### How to insert data in your pages ##### Create a page to display one blog item: /pages/{id}.html.xml We will use Kauri Template language to display our data in the pages. Read this section in the manual if you'd like more detail. We'll create a page to display the content of one blog item, this is the page template situated at /pages/{id}.html.xml. Tha blog item we need is pulled by using t:variable with the correct src attribute, in which we use {request.attributes.id} to get the request attribute ID: <t:variable name="item" src="service:/data/items/${request.attributes.id}" overwrite="false" accept="application/json"/>

When doing this the blog item is available as a variable with name 'item':

<?xml version="1.0"?>
<html t:inherit="module:/templates/layout.xml"
xmlns:t="http://kauriproject.org/template">

<t:init>
<t:variable name="item" src="service:/data/items/${request.attributes.id}" overwrite="false" accept="application/json"/> </t:init> <t:block name="title">${item.title}</t:block>

<t:block name="content">
<h2>${item.title}</h2> <h3>${item.date}</h3>

<p>${item.content}</p> </t:block> </html> Test this by browsing to following URL: http://localhost:8888/items/1. You should see this page: Remark that the we can display the item but our content which contains HTML is escaped. We want this variable to be displayed as html, so we have to use the t:insert instruction for that one: <p><t:insert value="${item.content}" mode="xml"/></p>
##### Create a page to display all blog items: /pages/all.html.xml

To display all blog items:

1. use the service:/data/items uri to pull all blog items
2. use the t:forEach to iterate the array of items
<?xml version="1.0"?>
<html t:inherit="module:/templates/layout.xml"
xmlns:t="http://kauriproject.org/template">

<t:init>
<!-- In prototype mode, the template is executed directly, and pulls in
the data it needs itself. In production mode, the data will be
supplied from the resource class (PersonResource).
-->
<t:variable name="items" src="service:/data/items" overwrite="false" accept="application/json"/>
</t:init>

<t:block name="title">Blog items</t:block>

<t:block name="content">

<t:forEach var="item" in="${items}"> <h2>${item.title}</h2>
<h3>${item.date}</h3> <p><t:insert value="${item.content}" mode="xml"/></p>

<hr/>
</t:forEach>

</t:block>

</html>

After doing this, browsing to url http://localhost:8888/items/all.html gives us a list of all blog items available in our JSON files:

If you make changes to the JSON files in the data directory of your application, you won't see those changes immediately in your browser. That is because a copy of that directory is made at startup of the application, and that one is used. When you restart the application, the data folder wil be copied.

## 3.6 Adding data via a form

#### Enable the use of forms in your application

Because we used the archetype to create our application the following is present in wiring.xml:

    <artifact id="forms" groupId="org.kauriproject" artifactId="kauri-forms-framework" >
<mount name="main" path="/kauri/forms"/>
<inject-restservice name="jquery" ref="jquery:main"/>
</artifact>

<artifact id="module1" groupId="org.kauriproject" artifactId="module1" version="1.0-SNAPSHOT">
<inject-restservice name="forms" ref="forms:main"/>
<inject-restservice name="jquery" ref="jquery:main"/>

<mount name="main" path=""/>
<mount name="data" path="/data"/>
</artifact>

This makes the forms module services are ready for use in our module1.

Each page which is using the Kauri forms needs some scripts includes. This (and other stuff) is done by letting our template inherit from layout.xml:

<html t:inherit="module:/templates/layout.xml" xmlns:t="http://kauriproject.org/template">

This layout.xml includes headerlinks.xml, which includes all necessary scripts:

    <t:include src="service:/forms/templates/snippet/headerlinks.xml"/>

At this time, just remember to let your template inherit from the layout.xml

#### Make a form to edit an existing blog item

We'll start with making a page to enables us to edit an existing blog item.  Therefore, we again need a uri with template : {id}-edit.html.xml. This makes it possible to call urls /items/1-edit.html, /items/2-edit.html etc.

In the Kauri forms framework, everything is configured in Javascript, via what we call a 'form configuration object'. If wanted, you can choose to write no HTML at all and let the HTML be generated for your. That is what we will do.

You just define the members of your form, what types are coupled to these members, and what sort of control you want to use for this member. What do we want to edit a blog item:

• title : a string displayed in a text-control
• content: string displayed in a textarea-control
• publication date: a date pickable from a datepicker
• ID: an integer displayed in a disabled text-control

There is no Kauri wysiwyg editor available for plugin at this moment. That's why we use a textarea control at first. In the next step we'll show how to plugin a html editor as a module.

#### Make a form to add a new blog item

We won't write any HTML ourselves, but just define an empty form with a specified ID:

     <form id="item-form">

</form>

To create our form, we start with the form configuration:

        var fconf = {
"createURI": "${publicUri('service:/data/items/')}", type: { members: { 'id' : { 'base' : 'integer', 'control' : { 'initial' : { 'enable' : false } } }, 'title': 'string', 'content': { 'base': 'string', 'control' : 'textarea-control' }, 'date' : 'date' } } }; / *end fconf */ Next we create the form with as arguments 1. the ID of the associated form 2. the fconf /* create form */  var itemForm = new jQuery.org.kauriproject.forms.Form("item-form", fconf);  #### Prefilling the form with data Because we want to edit a blog item in this form, we do want the form to be prefilled with the data. Therefore we pull the data we need (remember the {id} in the URL template, which contains the ID of the blog item we are editing): <t:variable name="item" src="service:/data/items/${request.attributes.id}" overwrite="false" accept="application/json"/>

This variable can be used to prefill the form via the setWireValue method.

        itemForm.setWireValue(${item}); FInally, we tell the form not to create (but only edit) data and what to do if the form has been submitted:  itemForm.setCreateMode(false); itemForm.submitSuccess = function (data, success) { window.location = "${publicUri('service:/main/items/all.html')}";
};

#### Result

If you now browse to http://localhost:8888/1-edit.html, you should see an edit page prefilled with the data of blog item 1:

#### Adding new data via the same template

We will now create a form to add a new blog item. This is quit similar to what we did above so we will reuse the same page template.  The URI template for that page was {id}-edit.html. We can specify whether we are creating or updating by defining this id as new in case of creating, so for creating a new blog item we use URI /items/new-edit.html.

All there is to it, is now checking via the template language if the request id equals 'new', and then switching to creation mode. Our result page should then be, remark the bold lines:

<?xml version="1.0"?>
<html t:inherit="module:/templates/layout.xml"
xmlns:t="http://kauriproject.org/template">

<t:init>
<t:variable name="id" value="${request.attributes.id}" /> <t:if test="${id != 'new'}">
<t:variable name="item" src="service:/data/items/${id}" overwrite="false" accept="application/json"/> </t:if> </t:init> <t:block name="title">${item.title}</t:block>

<t:superBlock/>

<script type="text/javascript">

var fconf = {
"createURI": "${publicUri('service:/data/items/')}", type: { members: { 'id' : { 'base' : 'integer', 'control' : { 'initial' : { 'enable' : false } } }, 'title': 'string', 'content': { 'base': 'string', 'control' : 'textarea-control' }, 'date' : 'date' } } }; / *end fconf */ /* create form */ var itemForm = new jQuery.org.kauriproject.forms.Form("item-form", fconf); itemForm.setCreateMode(${id == 'new'});
itemForm.setWireValue(${item}); itemForm.submitSuccess = function (data, success) { window.location = "${publicUri('service:/main/items/all.html')}";
};
});
</script>

</t:block>

<t:block name="content">
<form id="item-form">

</form>
</t:block>

</html>

## 3.7 Creating a module to add a HTML editor

We have created a form to add some blog items. It is of course not very user friendly to let users input HTML via a simple textarea. For that, we will use an existing HTML editor. We choose for TinyMCE here, because it has a jQuery plugin and is simple to plugin. We will create this as a separate module in our application and in this section, we'll show how to do that.

#### Creating the module structure

When creating our application by using the archetype, we have already added one module as default 'module1'. Beside this folder, we'll create a new module 'tinymce' with this folder structure:

-- myblog
|-- pom.xml
|-- conf
|-- wiring.xml
|-- module1
|      ...
|-- tinymce
|-- src
|   |-- main
|       |-- kauri
|       |   |-- spring
|       |       |-- services.xml
|       |-- tiny_mce
|       |   |-- jquery.tinymce.js
|       |   |-- tiny_mce.js
|       |   |-- .... rest of tinyMCE code
|       |-- router.groovy
|-- pom.xml

#### Configure the tinymce module

• pom.xml : define the parent and artifact name
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0,http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.kauriproject</groupId>
<artifactId>myblog</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../..</relativePath>
</parent>

<artifactId>kauri-tinymce</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MYBLOG ::: TINYMCE</name>

<build>
</build>
</project>
• services.xml: make sure the restervice is exported
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:kauri="http://kauriproject.org/runtime/1.0#springext"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://kauriproject.org/runtime/1.0#springext
http://www.kauriproject.org/schemas/runtime/springext.xsd">

<context:annotation-config />

<kauri:import-service id="routing" service="org.kauriproject.routing.RoutingService"/>

<kauri:export-restservice ref="main"/>

<bean id="main" factory-bean="routing" factory-method="createRouter">
<constructor-arg ref="context"/>
<constructor-arg ref="module"/>
</bean>

</beans>
• for our own convenience, we'll make sure  that we don't need to specify the tiny_mce directory name when we load the scripts. We can accomplish this by adding this snippet to the router.groovy of our tinymce module (located at src/main/kauri/router.groovy):
builder.router {

directory(
uri: "/",
listingAllowed: true,
root: "module:/tiny_mce/"

)
}

#### Wire it in the myblog application

To wire the new module inside the blog application, we add the tinymce artifact to the wiring.xml and mount the rest service on the correct path:

    <artifact id="tinymce" groupId="org.kauriproject" artifactId="kauri-tinymce" version="1.0-SNAPSHOT">
<inject-restservice name="jquery" ref="jquery:main"/>

<mount name="main" path="/tinymce"/>
</artifact>

Because the other artifact 'module1' depends on this one, make sure to define 'tinymce' before 'module1'

In the root pom.xml, add the module:

  <modules>
<module>module1</module>
<module>tinymce</module>
</modules>

#### Use it in the form

TinyMCE is now available via the service protocol, so we can load the tiny mce jquery script via this URI:

    <script type="text/javascript" src="${publicUri('service:/tinymce/jquery.tinymce.js')}"></script> When the script is loaded we can call tinymce on the textarea of the form: $('form textarea').tinymce({
script_url : '${publicUri('service:/tinymce/tiny_mce.js')}', theme : "simple" }); Note that this will call tinymce for all textarea controls in your form. If you use this elsewhere, be more specific in the jQuery selector To make sure the tinymce module copies its content to the textarea before submission of the form, we have to call the triggerSave method.  itemForm.prevalidation( function () { tinyMCE.triggerSave(true, true);$('form textarea').change();
});

#### Result

Page template {id}-edit.html now looks like this:

<?xml version="1.0"?>
<html t:inherit="module:/templates/layout.xml"
xmlns:t="http://kauriproject.org/template">

<t:init>
<t:variable name="id" value="${request.attributes.id}" /> <t:if test="${id != 'new'}">
<t:variable name="item" src="service:/data/items/${id}" overwrite="false" accept="application/json"/> </t:if> </t:init> <t:block name="title">${item.title}</t:block>

<t:superBlock/>

<script type="text/javascript" src="${publicUri('service:/tinymce/jquery.tinymce.js')}"></script> <script type="text/javascript"> jQuery(document).ready(function() { var fconf = { "createURI": "${publicUri('service:/data/items/')}",

type: {
members: {
'id' : {
'base' : 'integer',
'control' : {
'initial' : {
'enable' : false
}
}
},
'title': 'string',

'content': {
'base': 'string',
'control' : 'textarea-control'
},
'date' : 'date'
}
}
}; / *end fconf */

/* create form */
if(${id == 'new'}) fconf.createURI = "${publicUri('service:/data/items/')}";
else
fconf.dataURI = "${publicUri('service:/data/items/')}${id}";
var itemForm = new jQuery.org.kauriproject.forms.Form("item-form", fconf);

itemForm.setCreateMode(${id == 'new'}); if(${id != 'new'})
itemForm.setWireValue(${item});$('form textarea').tinymce({
script_url : '${publicUri('service:/tinymce/tiny_mce.js')}', theme : "simple", }); itemForm.prevalidation( function () { tinyMCE.triggerSave(true, true);$('form textarea').change();
});

itemForm.submitSuccess = function (data, success) {
window.location = "${publicUri('service:/main/items/all.html')}"; }; }); </script> </t:block> <t:block name="content"> <form id="item-form"> </form> </t:block> </html> Which results in: You'll see at this point a date parse error when you load one of your entities, in the validation section we'll show how to solve this ## 3.8 Adding form validation and formatters #### Add date formatting In this section, we'll add some validation to our form. But for starters, we'll make sure to get rid of the date parse error. In the backend, we want to store the date in this (iso8601) format: yyyy-MM-dd. But maybe we want to show these dates in a different format in the browser (dd/MM/yyyy). We call this respectively the wire-format and user-format. We can specify a format for each one of them via the fconf. Let's show this via an example: 'publicationdate' : { 'base' : 'date', 'wire-format': { 'base': 'wire-date', 'pattern': 'yy-mm-dd' }, 'user-format': { 'base': 'wire-date', 'pattern': 'dd/mm/yy' } } the patterns used here are the ones used by jQuery date parser, documentation can be found here. By extending wire-date with the desired pattern for wire-format and user-format, we can use a different format for backend and userside. #### Add validation In this stage, we'll add some validation to our form. We'll make all of the fields except the publication date and URL, required. The e-mail field should of course contain an e-mail, and the URL a valid URL. And as last we'll check if the publication date is a future date. ##### Client validation We'll mark following fields as required: • title • author • e-mail • content For this, we'll need to extend the fields. Our fconf for the title field still looks like this: 'title': 'string' To extend this, you need to understand that this is in fact a shorthand for this: 'title': { 'base': 'string' } And from this, we can extend our field with validators. We add validators by specifying +validators: 'title': { 'base': 'string', '+validators': { 'required': {} } } All types of available validators can be found in the forms reference. We need the 'required', 'isEmail' and 'isUrl' here, which results in:  var fconf = { "createURI": "${publicUri('service:/data/items/')}",
"dataURI": "${publicUri('service:/data/items/')}${id}",

type: {
members: {
'id' : {
'base' : 'decimal',
'control' : {
'initial' : {
'enable' : false
}
}
},
'title': {
'base': 'string',
'+validators': {
'required': {}
}
},
'author': {
'base': 'string',
'+validators': {
'required': {} ,
'isEmail': {}
},
'label': 'Author (e-mail)'
},
'url': {
'base': 'string',
'+validators': {
'isUrl': {}
},
'label': 'Author (URL)'
},
'content': {
'base': 'string',
'+validators': {
'required': {}
},
'control' : 'textarea-control'
},
'publicationdate' : {
'base' : 'date',
'wire-format': {
'base': 'wire-date',
'pattern': 'yy-mm-dd'
},
'user-format': {
'base': 'wire-date',
'pattern': 'dd/mm/yy'
}

}
}
}
};
##### Remote validation

We'll add one last validation to the form: checking if the publication date is a future date. This is  not a standard validation, and we'll do this by using our own remote validator. Herefore we have to define a validation resource class:

/*
* Copyright 2008 Outerthought bvba and Schaubroeck nv
*
* Licensed 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
*
*
* 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.
*/
package org.kauriproject.myblog.validation;

import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;

public class FutureDateValidationResource extends ValidationResource {

private final DateTimeFormatter iso8601 = ISODateTimeFormat.dateTimeParser();

public FutureDateValidationResource() {
super();
}

public FutureDateValidationResource(Context context, Request request, Response response) {
super(context, request, response);
}

@Override
protected Result validate(String value) {
//JSONObject input = JSONObject.fromObject(value);

if (value != null && !value.equals("")) {
DateMidnight now = new DateMidnight();
DateMidnight date = parseDate(value);

if (date == null) {
return new Result(false, "Date could not be parsed.");
} else if (now.compareTo(date) > 0) {
return new Result(false, "Date is not in future !");
}
}

return Result.OK;
}

private DateMidnight parseDate(String value) {
if (value.charAt(0) == '"' && value.charAt(value.length()-1) == '"')
value = value.substring(1, value.length()-1);
DateTime date = iso8601.parseDateTime(value);
return date.toDateMidnight();
}
}

That extends a validation resource:

package org.kauriproject.myblog.validation;

import java.io.IOException;

import org.restlet.Context;
import org.restlet.data.MediaType;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.representation.Variant;
import org.restlet.resource.Resource;
import org.restlet.resource.ResourceException;

public class ValidationResource extends Resource {

private Result validationResult;

static class Result {
static final Result OK = new Result(true);

boolean valid = true;
String msg;

Result() {
this(true);
}
Result(boolean valid) {
this(valid, null);
}
Result(boolean valid, String msg) {
this.valid = valid;
this.msg = msg;
}
String toJSON() {
if (valid) return "{\"valid\": true}";
else if (msg == null) return "{\"valid\": false}";
else return "{\"valid\": false, \"message\":\""+ msg +"\"}";
}
}

public ValidationResource() {
super();
}

public ValidationResource(Context context, Request request, Response response) {
super(context, request, response);
}

@Override
public void init(Context context, Request request, Response response) {
super.init(context, request, response);
setModifiable(false);
this.validationResult = null;
}

@Override
public boolean allowPost() {
return true;
}

@Override
public void acceptRepresentation(Representation entity) throws ResourceException {
try {
final MediaType mediaType = entity.getMediaType();
if (mediaType != null && mediaType.equals(MediaType.APPLICATION_JSON, true)) {
String value = entity.getText();
this.validationResult = validate(value);
final Response response = getResponse();
response.setEntity(represent());
response.setStatus(Status.SUCCESS_OK);
}
} catch (IOException e) {
e.printStackTrace();
throw new ResourceException(e);
}
}

@Override
public Representation represent(Variant variant) throws ResourceException {
return new StringRepresentation(this.validationResult.toJSON(), MediaType.APPLICATION_JSON);
}

protected Result validate(String  value) {
return new Result();
}
}

This FutureDateValidation class is a duplicate from the one in the forms sample, used on the date-control page.

Because the validator needs the joda-time library to parse and format the dates, we have to include the dependency in the pom.xml of our myblog module:

    <dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>1.6</version>
</dependency>

Remember to build your project after adding this code: mvn install

Once this done, just add this resource to your router.groovy:

    resource(uri: "/futuredate",
ofClass: "org.kauriproject.myblog.validation.FutureDateValidationResource");

And use the remote validator in the fconf:

'publicationdate' : {
'base' : 'date',
'wire-format': {
'base': 'wire-date',
'pattern': 'yy-mm-dd'
},
'user-format': {
'base': 'wire-date',
'pattern': 'dd/mm/yy'
},
'+validators' : {
'remote' : { location: "${publicUri('service:/main/futuredate')}" } } }  #### The result After adding these validations, you should be able to see a page which validates all fields when losing their focus: ## 3.9 Using jQuery UI for paging and grid editing #### Add some blog categories We will now make a page to edit some blog categories which we can use to categorize our blog posts. For starters, we need some mock data to represent this. Start with creating a new folder /categories in the mockdata folder. In this folder add some JSON files containing some categories, for example: 1.json { 'id': 1, 'name': 'lily' } 2.json { 'id': 2, 'name': 'kauri' } 3.json { 'id': 1, 'name': 'daisy' } etc. #### Add the jqgrid module As with all modules you use, to add a new module you should add this module in 2 files: • wire it in your application via wiring.xml • import the restservice via services.xml To use the jqgrid module, add the artifact in the wiring.xml of your myblog application and mount it on path /kauri/jqgrid:  <artifact id="jqgrid" groupId="org.kauriproject" artifactId="kauri-forms-jqgrid"> <mount name="main" path="/kauri/jqgrid" /> <inject-restservice name="jquery" ref="jquery:main" /> </artifact> And later on, inject the service into your myblog module:  <artifact id="module1" groupId="org.kauriproject" artifactId="module1" version="1.0-SNAPSHOT"> <inject-restservice name="forms" ref="forms:main"/> <inject-restservice name="jquery" ref="jquery:main"/> <inject-restservice name="tinymce" ref="tinymce:main"/> <inject-restservice name="jqgrid" ref="jqgrid:main" /> <mount name="main" path=""/> <mount name="data" path="/data"/> </artifact> import it in your spring configuration services.xml: <kauri:import-restservice name="jqgrid"/> That's it. #### Use the module in your template All there is to include to use jqGrid is packed in one file you can easily include:  <t:include src="service:/jqgrid/templates/snippet/headerlinks.xml"/> After this, all the jqGrid magic can be used. Check the jqGrid wiki for documentation on how to use the plugin. Notice what is important in the code below: • define where to pull the data • define some paging paramaters (we want 5 rows per page by default) • define how to manipulate the data to be sent to the server  jQuery("#grid").jqGrid({ colNames: colHeaders, colModel: colModel, height: 250, width:650, viewrecords: true, caption: 'All blog categories', pager: jQuery('#pager'), rowNum:5, rowList:[5,10], sortname:"name", jsonReader: { /* Works on the data returned by the datatype function, where already some data conversion of the server data is performed! */ root: "rows", page: "page", total: "total", records: "records", repeatitems: false, id: "id" }, datatype: function(postdata) { var parameters = {} if (postdata.page != undefined) parameters["page"] = postdata.page; if (postdata.rows != undefined) parameters["pageSize"] = postdata.rows; if (postdata.sidx != undefined) parameters["sort.0"] = postdata.sidx; if (postdata.sord != undefined) parameters["order.0"] = postdata.sord;$.ajax({
url: datapath,
data: parameters,
dataType: "json",
complete: function(jsondata, stat){
if (stat == "success") {
var thegrid = jQuery("#grid")[0];
}
}
});
}

});

And in the html, make sure you have a container with the ID used above:

  <t:block name="content">

<table id="grid" class="scroll" >
</table>

<div id="pager" class="scroll" style="text-align:center;">
</div>

</t:block>

Save all of this in pages/categories/grid.html.xml.

#### Result

Browse to http://localhost:8888/categories/grid.html and this should be the result:

#### Grid editing

We'll make sure that when we click a row, we can edit the name of the category inline. More documentation and example can be found in the jqGrid wiki.

For starters, don't forget to set the editable columns editable:

      var colModel =  [
{name:'name',index:'name', width:55, jsonmap:'name', resizable:true, editable: true}
];

To accomplish inline editing we'll add 'onSelectRow' as parameter to the jqGrid call. This is a function that defines what to do when a row is selected in the grid, and in this case we want to call the 'editRow' function:

onSelectRow: function(id){
if(id && id!==lastSel){
jQuery('#grid').restoreRow(lastSel);
lastSel=id;
}
jQuery("#grid").editRow(id, true, '', '', "${publicUri('service:/data/categories/')}"+id+"?method=PUT", [], after_save); } The first 3 lines make sure that only one row at a time can be selected. The last row defines what to do when a row is edited: • 5th parameter defined the URL to post to e.g. : /data/categories/3?method=PUT • the last parameter after_save is a function that reloads the grid  var after_save = function() {$("#grid").trigger("reloadGrid");
}

When this is done, there is a call made to the correct URL. But we need Kauri-style data to be sent to the server, so we have to make some more customisations:

              ajaxRowOptions : {
type :"POST",
contentType :"application/json; charset=utf-8",
dataType :"json"
},
serializeRowData: function(obj){
var toPost = {};
toPost['id'] = obj.id;
toPost['name'] = obj.name;
var str = JSON.stringify(toPost);
return str;
}   

This does make sure JSON is sent to the server (ajaxRowOptions), and only id and name are sent (and not more jqgrid options, like 'editmethod' etc that would be saved in our category object if we send it to the server) (serializeRowData).

#### Enable adding a category

We'll create a button to add a new category as well. We'll do this by adding the HTML for the button, attaching a click handler to that, and calling the needed jqGrid function to create a row.
First add the button:

    <table id="grid" class="scroll" >
</table>
<input type="button" id="add" value="Add a category" />
<div id="pager" class="scroll" style="text-align:center;">
</div>

In jqGrid, you can call 'editGridRow' with "new" as ID to create a new item. (see documentation jqGrid: Edit grid row)
This function needs some essential parameters:

• closeAfterAdd: to close the window after adding
• ajaxRowOptions: to make sure JSON is posted to the server
• serializeEditData: to edit the data the way we want it before making the ajax call

The URL used for making the AJAX call is the "editurl" in the jqGrid options.

          jQuery("#grid").jqGrid({
....
editurl:   "${publicUri('service:/data/categories/')}" .... }); .... jQuery("#add").click( function() { jQuery("#grid").editGridRow( "new", { ajaxEditOptions : { type :"POST", contentType :"application/json; charset=utf-8", dataType :"json" }, serializeEditData: function(obj){ var toPost = {}; toPost['name'] = obj.name; var str = JSON.stringify(toPost); return str; }, closeAfterAdd : true } ); });  #### Attach a blog category to a blog item We enable the use of blog categories into the blog item editor. Herefore we'll use a selection control in the fconf:  'category' : { base: 'composite', members: { 'id' : { base: 'integer', control: { "base": "selection-control", "options": { "uri": "${publicUri('service:/data/categories')}",
"valueTemplate": "{id}",
"labelTemplate": "{name}"
}
}
}
}
}  

Which results in a selection control on the form:

Note the 'composite' that in between our form and the selection control. This is because we do want to send data to the server in format {'category' : {'id' : 1}} instead of {'category': 1}. The latter would not allow us to save a BlogItem with a Category object in it (but only the ID then).

This is also why the automaticaly created html form shows the 'id' as well as the 'category' label. TODO: show how to remove it by writing HTML.

## 3.10 Migrate from DB mock to DB resources

Check the JPA database resources section in the Kauri documentation for more detail.

#### Making entities

We'll make entities for all data we have used temporary JSON files for and we use JPA for this. Annotate your POJO's with the JPA annotations where appropriate and do not forget to add an empty constructor:

package org.kauriproject.myblog.entities;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity(name = "categories")
public class Category implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;

public Category(){
// (empty) constructor needed
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


We do the same for BlogItem:

package org.kauriproject.myblog.entities;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity(name = "items")
public class BlogItem implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String title;
private String author;
private String url;
private String publicationdate;

@OneToOne(fetch = FetchType.EAGER)
private Category category;

private String content;

public BlogItem(){
// empty constructor
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthorEmail() {
return author;
}
public void setAuthorEmail(String authorEmail) {
this.author = authorEmail;
}
public String getAuthorUrl() {
return url;
}
public void setAuthorUrl(String authorUrl) {
this.url = authorUrl;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getPublicationdate() {
return publicationdate;
}
public void setPublicationdate(String publicationdate) {
this.publicationdate = publicationdate;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}

}


#### Create database and database user and create persistence.xml

We will store our entities in a MySQL database. For this, create an empty MySQL database, and a user with sufficient privileges to create tables and data in it.
Create a persistance.xml file in src/main/resources/META-INF which contains this databasename, username and password:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="kauri-dbresources" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="mysqluser" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/myblog" />
</properties>
</persistence-unit>
</persistence>

#### Startup in production mode

Now don't forget to startup your application in production (default) mode. Or: just leave the '-p prototype' behind when starting up kauri:

/path/to/kauri run

/path/to/kauri run -p prototype

Once this is done, the application will no longer use the mockup data, but persist all data in the specified database.

TODO

## 3.12 Create an RSS feed

#### Add wanted path to router.groovy

is this needed if the path is also in the resource?

    resource(uri: "/feed",
ofClass: "org.kauriproject.myblog.feed.BlogItemsResource");

#### Create a BlogItemResource

We'll create a resource class that can get a list of all blog items, this method puts this list into a hashmap. Such a method returns a KauriRepresentation, which on his turn will be mapped to a template in representations.groovy. We create a "listBlogItems" method in this resource class, annotated with a jaxrs path. This method uses JPA to create a list of blogitems.

package org.kauriproject.myblog.feed;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.kauriproject.myblog.entities.BlogItem;
import org.kauriproject.representation.build.KauriRepresentation;
import org.restlet.resource.Resource;

@Path("/feed")
public class BlogItemsResource extends Resource{

}

@Path("list")
@GET
@Produces("application/xml")
public KauriRepresentation listBlogItems() {
Map<String, Object> data = new HashMap<String, Object>();
// load all blogitems into data
List<BlogItem> items = jpaDaoSupport.getJpaTemplate().find("select b from items b");
data.put("items", items);

return new KauriRepresentation("atom", data);
}
}

#### Add template to representations.groovy

The resource class creates a Kauri representation which in mapped in representations.groovy:

      when(name: "atom") {
template(src: "module:/pages/atom.xml")
}

#### Create atom template

pages/atom.xml explain

## 3.13 Add caching

TODO

see documentation for caching of static resources

# 4 Kauri concepts

This documents gives an overview of the core concepts and technologies provided by Kauri. See Getting started for a practical guide to start using Kauri.

Kauri is a web application framework. See wikipedia in case you don't know what a web application or a framework is.

## 4.1 Adhering to Web architecture

Kauri does not try to work around the constraints imposed by the Web, but embraces them. Kauri wants you to think about resources, URIs, correct use of the HTTP methods, response codes, caching, and so on. In one word, it supports RESTful development. Or if you prefer, ROA and WOA.

For this reason, Kauri does not use the classic Servlet API, but the Restlet API. Many things in Restlet will be familiar for Servlet developers: it is still about requests and responses. But at a more detailed level, its design matches better with REST and HTTP concepts. This in turn will help you to write better Web applications.

Kauri, like Restlet, does not have sessions as known in the Servlet world. Things that you might have traditionally stored in sessions, can often be rethought as resource state, kept in the client, or else stored as (preferably client-controlled) temporary resources.

## 4.2 Routing and resource classes

A RESTful design starts with thinking about the resources you want to expose and their URIs. Kauri thus has very good support for routing requests based on the request URI. You can find more information about routing in the routing chapter.

Kauri provides a flexible routing component. It is configured through a simple Groovy DSL. You do not have to know Groovy for this purpose. Below is a small example, you can probably guess what it does (if not, don't worry, it is all explained in the docs).

builder.router {
directory(uri: "/resources", root: "module:/resources/")
resource(uri: "/persons/{id}.html", ofClass: "com.foobar.Person")
}

The routing will eventually bring the request up to the Java class that will handle it. Such a class, which implements a resource, is called a resource class. In case the URI is not recognized by the system, a 404 Not Found response will be produced.

You can manually implement resource classes based on the Restlet API or the JAX-RS API. That last one is an API defined through the JSR process, and is based on annotations, providing a practical and consice means to implement a resource class. Here is an example to give an idea:

@Path("/persons/{id}.html")
public class PersonResource {

@GET
@Produces("text/html")
public KauriRepresentation getPerson(@PathParam("id") String idParam) {
....
}
}

Kauri also includes a component to automatically expose a database model (implemented using JPA) as RESTful resources.

## 4.3 The Kauri Runtime: modules

Modularization is a core tool of software engineering to keep the complexity low. By dividing an application into modules, that communicate through well-defined interfaces, a big application stays manageable.

An application can not only consist of custom-developed modules, but will often make reuse of modules provided by Kauri or other parties. Examples of modules included with Kauri are the routing module, the templating module, the forms module, and so on.

While you might not find your own application big and complex enough to bother splitting it into modules, you will still benefit from the modularization by being able to reuse existing modules. Since modules are properly encapsulated, you can do so without having to worry about their internal workings.

The core of Kauri, which manages the modules, is called the Kauri Runtime. The Kauri Runtime manages the startup and teardown of modules, the wiring of services between them, and the classloading of the modules.

The description of what modules form a certain application, and how to wire them together, is done in a file which we call the wiring.xml.

Technically, a module is a jar file containing a KAURI-INF directory which can contain:

• Spring bean container configuration

• classloader configuration (by default, auto-generated from your Maven pom)

• other resources: template files, Javascript, CSS, images, ...

At startup, Kauri reads the classloader configuration of all modules and builds the classloader setup. Then it starts the modules, which comes down to booting the Spring container of each module. The service wiring is done by making available the dependencies as beans in the Spring container.

Up to here, nice, but nothing exceptional. The differences come from Kauri Runtime's support for REST-services and the Maven repository.

#### REST-services

REST-services are similar to classic Java services: a module can provide REST-services, and depend on REST-services. A REST-service can answer to REST-style requests (i.e. GET/POST/PUT/... on an URI-identified resource), not just for a single URI but an entire URI-space. When a module depends on a REST-service, you can either wire it to a REST-service provided by another module, or to an arbitrary URI.

In fact, everything you want to make available over HTTP should be provided by a module as a REST-service and is then mounted on a specific path.

#### Maven repository

The Kauri Runtime loads all modules and their classpath needs from Maven-style repositories. A Maven repository is a repository containing artifacts, which typically are jar files. By using the Maven repository, the jars are clearly identified by ID and version, rather than relying on file names. Another advantage is that after building your project using Maven, you can immediately run it. There is no no need for additional copying, as is the case with wars.

#### Internal protocols

The Kauri Runtime provides two special protocols for use within modules: The “module:” protocol to load resources from the module jar, and the “service:” protocol to access REST-services.

## 4.4 Templates

As most other web frameworks, Kauri has a template language, in which you will find the familiar constructs. More detailed information on templates is found here.

It is not the kind of template language like JSP, in which you can embed arbitrary (Java) code, but rather a restricted one in which you can use a limited set of constructs like loops, if's and expressions. We do reuse JSP's expression language (EL).

Kauri's template language is a standalone, reusable library not tied to any other parts of Kauri.

#### XML-based

The template language is XML-based. Each template file has to be a well-formed XML file. The advantage of this is that the template output will always be well-formed markup (start and end tags match, proper escaping of special characters), common formatting rules are enforced (an empty script tag should have a close tag, things like that), and the output is produced as SAX-events instead of characters, allowing to connect it to other XML transformation components (such as XSLT) in an efficient way.

#### Template inheritance

To support a common layout across pages, we support template inheritance, inspired by Django's template language. With template inheritance, you can define a base template in which there are regions which can be overridden by child templates.

As an example, take this base template:

<?xml version="1.0"?>
<html xmlns:t="http://kauriproject.org/template">

<title>
<t:block name="title">The title</t:block>
</title>

<body>
</body>
</html>

The listing below shows a template inheriting from this base template. Notice the t:inherit attribute on the root element. The content of the t:block elements will replace that of the base template. All content outside the t:block's will be ignored. This allows to add body tags etc. so that the inherited template can be viewed stand-alone too.

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns:t="http://kauriproject.org/template"
t:inherit="module:/templates/layout/layout.xml">

<t:block name="title">My page</t:block>

<t:block name="main">My interesting content</t:block>

</html>

Multiple inheritance, calling the “super” block and cross-block initialization are supported. All this is explained here.

A module does not know on beforehand where in the URI space its resources will end up. In case it reuses REST-services from other modules, it will even less know where those will end up in the URI-space. Therefore, the template langauge has a special publicUri() function to translate from internal paths to public paths. REST-services are internally addressed using a service protocol, so a publicUri() call looks like:

<a href="publicUri('service:/main/person/john.html')">John</a>

## 4.5 Forms

Forms play an important role in web applications. Plain HTML forms are rather basic and don't offer a lot of help with common issues such as data validation, custom controls, composite and collection structures, and so on. Kauri Forms solves these problems for you.

In contrast to the forms support of many web application frameworks, Kauri Forms is a Javascript library which runs in the browser. It is not a Java framework which manages a server-side model of your form. Kauri Forms makes the radical assumption that Javascript is available.

The form-controller sits in the browser, and directly GETs and POSTs/PUTs data to resources.

Besides the usual basic widgets, you will find things such a Google Maps widget or an Ajax-enabled upload widget.

A form's structure can be defined in Javascript (JSON), but it can also be implictly derived from annotations on a HTML form.

Below we show an example of a Javascript-defined form. A form consists of widgets, which have an ID and extend from built-in widgets. In the sample below, the IDs of the widgets are name, email and birthday. The email widget has a special property “+validators”, which means we add the listed validators to those of the base type, rather than replacing them.

var fconf = {
createURI: "${publicUri('service:/data/contact/')}", type: { members: { name: "string", email: { base: "string", "+validators": { isEmail: {} }, label: "e-mail" }, birthday: { base: "date", yearRange: "-100:+0", label: "What is your date of birth?" }, } }}; In the HTML page, you put placeholders where the widgets should be inserted. These placeholders use special 'kauri-' attributes to refer back to the form module, like this: <label kauri-role="label" kauri-idref="name"/> <input kauri-idref="name"/> ## 4.6 Holistic approach Besides supporting RESTful design, another important goal of Kauri is to support all players and all steps of a web application project, as described in more detail in the vision document. #### Prototyping The holistic vision is in part realized by the "prototyping mode" of Kauri. In prototyping mode, the focus is on designing the web front-end. The development of a Web front-end is an iterative process. Often starting from a napkin wireframe, some first HTML pages are designed. The static HTML pages might be replaced with executable templates to support extracting the common layout and other reusable snippets. Feedback from the client is used to refine the design. Up to here, nothing too special. The prototyping mode of Kauri allows you to turn your HTML page mockups into a real working prototype. The effort involved in this is not lost, as the development of the real application will re-use the same artifacts. Here are some of the tools offered for prototyping: • You can split off the data used in the template in “mockup data entities”. These are JSON files that can be made available as a variable in the template. This allows reuse of the same data across pages, helps you gradually design your data model, and also makes that the templates will later be usable with non-mock data objects. Kauri has a component called DbMock which provides a complete RESTful interface (with CRUD and query operations) based on a directory structure containing JSON files. • You can support a dynamic URI space by making use of filesystem-defined routing. Simply create file names with {variables} in them (yes, you can use { and } in file names), and these will be treated as URI-matching patterns ( URI templates). • No “throw over the wall”: the templates files created during the initial prototyping serve as a basis for the final ones, no need to restart from scratch. • You can switch back to prototyping mode at any time. In prototyping mode, templates are executed directly, fetching their data from the mockup data entities. In production mode, the templates will typically be called as the result of the processing in a resource class, which is also responsible for passing the data to the template. There is no fixed line between what is possible in a prototype, and what not. A prototype can make use of Kauri Forms and Ajax. As an example, suppose we have a resource person which we want to make available in the URI space as person/{id}.html For this we create a template file at src/main/kauri/pages/person/{id}.html.xml1. During prototyping, template files are executed directly, without going through a resource class. This is sometimes refered to as Model 1 or PHP-style. <?xml version="1.0"?> <html xmlns:t="http://kauriproject.org/template"> <t:variable name="person" src="service:/data/persons/${request.attributes.id}"
overwrite="false"
accept="application/json"/>

<body>
<h1>Person: ${person.name}</h1> <p>City:${person.city}</p>
</body>
</html>

Pay attention to the t:variable instruction: rather than defining the value of the variable using an expression, we tell it to load its data from a URI.

The person data is defined by creating a file src/main/kauri/mockdata/persons/1.json

{
"name": "Mr Foo Bar",
"city": "Foobar City"
}

## 4.7 Technology choices

We think it is useful if some choices have not to be made over and over for each project. Therefore, we have made a selection of third-party technologies which we push forward as the default solution to use in Kauri. This comes without obligation, but it will be useful to reduce learning curve, increase developer familiarity, and increase reuse of dependencies among modules.

More specifically, we have selected jQuery as the Javascript library.

As CSS framework, we use Blueprint CSS.

## 4.8 Developer convenience

### 4.8.1 Quick test cycle

When working on things which require lots of interactive testing, such as templates, CSS, etc. you can immediately try changes without having to rerun your build. This is called running from source. With a simple command line switch, you let Kauri know that it should read module resources directly from your source tree, rather than from the compiled jar.

### 4.8.2 Project templates

Project templates (Maven archetypes) generate the basic structure for new projects.

## 4.9 Open Source

Kauri is available for free with source code included. The sources are released under the business-friendly Apache license.

## 4.10 Other

• Packaging: Kauri includes a Maven plugin which can package your application together with all its dependencies so that it can be deployed or distributed. The package plugin can also generate a traditional Servlet webapp for deployment in legacy environments. More information can be found on this page.

• Security: see here

• Configuration see here

# 5 Prototyping

TODO: we should write a nice intro to the prototyping concepts. The ingredients are:

• front-end design starts with designing screens using wireframes (screen mockups):
• as input/specification to developers implementing the screens
• to refine requirements
• to solicit feedback from customers
• prototyping goes further than wireframes:
• for demo purposes, to show dynamic behavior (ajax...)
• factor out common elements:
• snippets and layout into separate templates
• data into separate json files
• possibly introduce kauri forms
• specific kauri ideas:
• no fixed line between wireframing and prototyping and real app: some parts of the app might already be working, while for others the wireframes are in place
• everyone working on the same code repostiory
• don't throw away templates when moving from wireframe to prototype to real app
• be able to switch back to prototyping at any time: templates are shared between prototype and real app
• start using kauri very early on

## 5.1 Prototyping: step-by-step

### 5.1.1 Introduction

Creating a web application prototype using Kauri can be done by anyone with some "web skills", i.e. HTML, CSS, maybe some Javascript and familiarity with template languages.

This step by step guide will get you started from zero. If you experience any difficulties, you're welcome to share them on our discussion group.

### 5.1.2 Prerequisites

If you have not done so already, install Kauri and install Maven.

We will assume you have added Kauri's bin directory to your PATH environment variable.

### 5.1.3 Create a project

Create a project as described here. When asked 'Choose archetype', select the "kauri-archetype-protototyping" archetype (at the time of this writing, option 2).

Also build and try out the created project as described over there.

### 5.1.4 Start Kauri in prototype mode

Kauri can be started in different modes: either "prototype" or "production" (the default).

Depending on the mode, different parts of the routing will be activated, different Spring configurations can be loaded, etc.

Since we will be prototyping, we start Kauri in prototype mode, and to avoid having to rebuild and restart Kauri when making changes, we start Kauri in source mode.

Here's the command:

kauri(.sh) -p prototype -s module-source-locations.properties

### 5.1.5 Create templates

In prototyping mode, the URI space is defined by the files and directories inside the pages directory, located at:

module1/src/main/kauri/pages

If you create a new file there, for example hello.html.xml, you will be able to access it in your browser as http://localhost:8888/hello.html

Every file you create in this directory will be executed as a template, so it has to be a valid template file. Basically, this means it has to be a well-formed XML file.

But you can do smarter things than this. By putting {variables} in file or directory names, you can define URI patterns.

As an example, suppose we create an "order resource", that is, a page showing the details about an order. We want this to be available at the URI /orders/{orderid}.html

For this, we create an orders subdirectory inside the pages directory, and in that directory, a file called {orderid}.html.xml. You can use the { and } characters in a file name, so this is no problem. To summarize, we create the following file:

module1/src/main/kauri/pages/orders/{orderid}.html.xml

The purpose of the double file extension is as follows: the first extension will be part of the URI path, the second is for having a correct association with applications on your computer. If both extensions can be the same, you only need to use one extension. If you want the URI path to have no extension, but want an extension on the file system, you can use {orderid}..xml (= nothing between the two dots).

Put the following in the {orderid}.html.xml file, our first mockup of an order page:

<html>
<body>
<h1>Order number: 12345</h1>
<h2>Bill to</h2>
Name: John Doe
<br/>
Address: 123 Foobar Street

<h2>Items</h2>
<table>
<tr><th>Nr</th><th>Description</th><th>Price</th></tr>
<tr><td>324</td><td>Chair</td><td>50</td></tr>
<tr><td>17</td><td>Table</td><td>250</td></tr>
</table>
</body>
</html>

You can now browse to the following URI to see the order page:

http://localhost:8888/orders/12345.html

In fact, you can change the 12345 by any string (excluding the slash character), since the template will be executed for any request matching the {orderid}.html pattern.

### 5.1.6 Split off data from templates

Now we go a step further, and make our order page screen mockup into a real template, which retrieves its data externally.

First we will create a mock order entity. To define order entities, we create the following directory:

module1/src/main/kauri/mockdata/orders

In this directory, create a file called 12345.json, containing the following data:

{
billTo: {
name: "John Doe",
address: "123 Foobar Street"
},
items: [
{
code: "324",
description: "Chair",
price: "50"
},
{
code: "17",
description: "Table",
price: "250"
}
]
}

Now we adjust our template {orderid}.html.xml to make use of this data:

<html xmlns:t="http://kauriproject.org/template">
<

t:variable name="order" src="service:/data/orders/${request.attributes.orderid}"/> <body> <h1>Order number:${order.id}</h1>
<h2>Bill to</h2>
Name: ${order.billTo.name} <br/> Address:${order.billTo.address}

<h2>Items</h2>
<table>
<tr><th>Nr</th><th>Description</th><th>Price</th></tr>
<t:forEach in="${order.items}" var="item"> <tr><td>${item.code}</td><td>${item.description}</td><td>${item.price}</td></tr>
</t:forEach>
</table>
</body>
</html>

Because of a limitation in the current Kauri version, you need to restart Kauri after making changes to the the JSON mock data. Remember that you need to start Kauri with the -p prototype argument, otherwise this will not work.

To try it out, browse again to the same URI (assuming you called your entity 12345.json):

http://localhost:8888/orders/12345.html

Some explanation about the template:

• about t:variable: usually t:variable is used to defined a variable based on an expression. Here however, we load the variable data from an external source. The data will be parsed as a JSON object, so that its properties can be accessed in the template. The src attribute contains a "service:" URI, the purpose of the service protocol is to address internal REST-services, in this case the data service, which in prototyping mode works on top of the JSON files.
• to get the value matched by the {orderid} in the {orderid}.html.xml file name, the expression ${request.attributes.orderid} is used. • id properties are automatically added to the mock entities, so you can use${order.id} even though the JSON file does not contain an id property.

You can now create some additional mock orders in the directory mockdata/orders, and verify you can view them in the browser.

### 5.1.7 Listing all orders

The mock JSON entities are not simply static files which we load into our templates. They are managed by the DB Mock component, which provides a RESTful interface on top of them, supporting CRUD operations, query operations including paging and entity-linking possibilities.

We will now show how to create a page listing all orders.

Create a file at

module1/src/main/kauri/pages/orders.html.xml

containing:

<html xmlns:t="http://kauriproject.org/template">
<t:variable name="orders" src="service:/data/orders?sort.1=billTo.name"/>

<body>
<h1>Orders</h1>

<table border="1">
<tr><th>Order ID</th><th>Client</th></tr>
<

t:forEach var="order" in="${orders}"> <tr> <td><a href="${publicUri('service:/main/orders/')}${order.id}.html">${order.id}</a></td>
<td>${order.billTo.name}</td> </tr> </t:forEach> </table> </body> </html> Try it out at: http://localhost:8888/orders.html Some explanation about the template: • the publicUri('service:/...') function call is used to translate internal service URIs to public paths (that will work over HTTP). Modules in Kauri do not know by themselves where their services will end up in the URI space. This is determined by the mount statements in the wiring.xml file. Therefore, we can not use hardcoded paths. For the purpose of this example, we could however simply have used a relative URI. ### 5.1.8 Defining layout We want the various pages in our application to share a common layout. Kauri's template language has an interesting " template inheritance" feature for this. You can write a base template in which certain regions, called blocks, can be redefined by child templates. As part of generating the project, a layout template is already created for you at: module1/src/main/kauri/templates/layout.xml If you open this file, you will see it contains the following blocks: <t:block name="title"/> and <t:block name="content"/> You can of course create as many blocks as you like, and freely choose their names. Now let's adjust our order pages to inherit from this base layout. We will show this for the orders.html.xml, you can do the same thing for {orderid}.html.xml <html xmlns:t="http://kauriproject.org/template" t:inherit="module:/templates/layout.xml"> <t:init> <t:variable name="orders" src="service:/data/orders"/> </t:init> <t:block name="title">Orders</t:block> <t:block name="content"> <h1>Orders</h1> <table border="1"> <tr><th>Order ID</th><th>Client</th></tr> <t:forEach var="order" in="${orders}">
<tr>
<td><a href="${publicUri('service:/main/orders/')}${order.id}.html">${order.id}</a></td> <td>${order.billTo.name}</td>
</tr>
</t:forEach>
</table>
</t:block>

</html>

• Everything outside the t:block elements will be ignored, the content of the t:block elements will be inserted into the base template.
• The attribute t:inherit is used to specify the base template. The special module protocol is used to address your module's resources, in the source tree this corresponds with everything below module1/src/main/kauri
• If you want to define variables that should be visible in all blocks, you can define them inside the t:init element. In this case, we could as well have defined the variable inside the content block, as that's the only place it is used.

After you have made these changes, the pages will still pretty much look the same. You can adjust the layout.xml to apply a more fancy style.

### 5.1.9 Editing entities: Kauri Forms

Most web applications will contain forms, and thus while prototyping the front-end, you will eventually also be designing some forms. You could define these forms simply as HTML. But you could also start using Kauri Forms right away. Together with DB Mock, this will to some extent give the impression of a real working application, as you can load and store data. It also makes that you can to a large detail develop the front-end before, or in parallel with, the back-end.

Let us create a form for editing an order. Create a file at

module1/src/main/kauri/pages/orders/{orderid}-edit.html.xml

and put the following in it:

<html xmlns:t="http://kauriproject.org/template"
t:inherit="module:/templates/layout.xml">

<t:init>
<t:variable name="id" value="${request.attributes.orderid}"/> <t:if test="${id != 'new'}">
<t:variable name="order" src="service:/data/orders/${id}"/> </t:if> </t:init> <t:block name="content"> <t:include src="service:/forms/templates/snippet/headerlinks.xml"/> <script type="text/javascript"> jQuery(document).ready(function() { // Define form configuration var fconf = { "createURI": "${publicUri('service:/data/orders/')}",
"dataURI": "${publicUri(txt:concat('service:/data/orders/', id))}", }; // Create the form var editForm = new jQuery.org.kauriproject.forms.Form("edit-form", fconf); // Modify some form properties editForm.submitSuccess = function (data, success) { window.location = "${publicUri('service:/main/orders.html')}";
};
editForm.setCreateMode(${id == 'new'}); <t:if test="${id != 'new'}">
// Load data into the form
editForm.setWireValue(${order}); </t:if> }); </script> <form id="edit-form"> <div kauri-role="input" kauri-idref="/" kauri-type="composite"> <h1>Order number:${id}</h1>

<h2>Bill to</h2>
<div kauri-idref="billTo" kauri-type="composite" kauri-role="input">
Name: <input kauri-idref="name" kauri-type="string"/>
<br/>
</div>

<h2>Items</h2>
<table kauri-idref="items" kauri-type="collection" kauri-role="input">
<tr><th>Nr</th><th>Description</th><th>Price</th><th/></tr>
<tr kauri-role="layout">
<td><input kauri-idref="code" kauri-type="string"/></td>
<td><input kauri-idref="description" kauri-type="string"/></td>
<td><input kauri-idref="price" kauri-type="string"/></td>
<td><a kauri-role="delete" href="#" onclick="return false;">delete</a></td>
</tr>
</table>
<a kauri-idref="items" kauri-role="add" href="#" onclick="return false;">add item</a>

<p><input type="submit" value="Submit"/></p>
</div>
</form>

</t:block>

</html>

This form supports both editing existing orders and creating new orders.

To edit an existing order, browse to:

http://localhost:8888/orders/12345-edit.html

(the 12345 should correspond to an existing JSON file in mockdata/orders)

To create a new order, browse to:

http://localhost:8888/orders/new-edit.html

You will see how the existing data is loaded, or the new data is saved and appears in the order overview. You will also see that you can add and remove items to the order.

In the template above, you see a script element containing some Javascript. A variable fconf is created, whose purpose is (mostly) to describe the form structure. In the example here, there is actually nothing of form structure described in the fconf. When this is the case, Kauri Forms will automatically derive the form structure from your HTML form, based on the kauri-idref and kauri-type attributes.

Kauri Forms can load and save form data from and to JSON. The IDs of the form widgets (in the kauri-idref attributes) correspond to the properties of the JSON object. In case you are editing an existing order, the data is loaded into the form by the setWireValue(${order}) call. The${order} is evaluated by the template engine, so it will be replaced by the actual form data in the HTML sent to the browser.

We won't explain Kauri Forms in more detail here. If this example has wet your appetite, check out the forms documentation to learn more about it.

### 5.1.10 From prototype to real application, and back again

Up to now we have been running Kauri in prototype mode. If you want to stop working in prototype mode, simply don't pass the "-p prototype" argument.

#### 5.1.10.1 From DB Mock to real data resources

Some things will then however be broken, especially all templates where you load data from DB Mock, since DB Mock is only available in prototype mode. You will have to replace the mock 'data' service by a real one. The way this works is that some Spring configuration is loaded based upon the runtime mode:

module1/src/main/kauri/spring/[prototype|production]

With the project generated by the prototyping-archetype, there is one sample entity present ("Person") which works in both modes. It makes use of JPA for the real entity, backed by an in-memory HSQLDB.

#### 5.1.10.2 From direct template execution to resource classes

During prototyping, the templates in the "pages" directory are executed directly, without first going through some resource class (somewhat similar to what other frameworks call controller).

For some pages this is fine, and can stay this way. However, the more common way of working is to first perform logic and gather data in a resource class, which is then passed on to a template. In a resource class, it is easy to take decisions such as producing an error, redirecting to somewhere else, and so on. A template on the other hand directly starts producing output (and thus sending it to the browser), and hence does not allow to make such decisions anymore.

The same template file can however be reused. You do not need to copy it to another location or so: you can literally reuse the same file. When not in prototyping, the request routing will first look for resource classes to handle the request, before resorting to the direct execution of the templates in the pages directory (in prototyping mode, it works just the other way around).

There is one trick involved though. During prototyping, we define variables with the 'src' attribute to load data. When not prototyping, this data will be passed on from the resource class. Therefore we need to tell the variable not to overwrite the data if is is already previously defined, using the overwrite attribute:

<t:variable name="order" src="service:/data/orders/${id}" overwrite="false"/> Again, the prototyping-archetype generated an example of this, see the PersonResource class. #### 5.1.10.3 Switch between prototype and production mode at any time Since the same template files can be used for prototype and production mode, you can switch between them at any time. ## 5.2 Prototyping: how it works TODO: this should explain how prototyping works to a technical audience: what kauri features support the prototyping: mock dbresources, 'pages' and 'mode' and 'passThrough' in routing, mode-dependent spring configs, runtime mode, ... # 6 Routing ## 6.1 What is routing? In Kauri, routing means the problem of mapping an incoming request to a resource class. Routing is usually done based on the request URI, in particular its path component.  http://kauriproject.org/documentation/tutorial.html?foo=bar&foo2=bar2 <--> <----------------><--------------------------><----------------> scheme authority path query string If you are familiar with other web-frameworks supporting configurable routing, you are probably wondering how the routing is configured in Kauri. For completeness, you should know there are multiple levels of routing (see next section), but the most interesting one is how routing is done within a module. For this, Kauri provides a standard routing infrastructure which is configured with a syntax like this: builder.router { resource(uri: "/user/{name}", ofClass: "mystuff.UserResource") resource(uri: "/order/{orderId}", ofClass: "mystuff.OrderResource") } The syntax of this file is Groovy using the Groovy Builder convention. The uri patterns are defined using URI template syntax, in which the parts in brackets {} represent wildcards. This is a very basic example, there are lots of other possibilities described later on. ## 6.2 The full picture: how a request is routed To refresh your memory, a Kauri setup consists of a number of modules which can provide restservices. These restservices are mounted on a certain path on a certain virtual host. From this sentence, we can already distinguish two levels of routing which happen: 1. an incoming request is routed based on the virtual hosts configuration. If you have not configured any virtual hosts, you don't need to worry about this item, every request will go to the one and only default virtual host. 2. next, the request is routed to a certain restservice based on the path on which the restservice is mounted Once the request arrives at the restservice, it is up to the restservice to decide how the request should be handled further. Power users will appreciate the fact that they can implement any sort of behavior as desired. However, this is rather low-level work and quickly recurring patterns will appear, therefore Kauri provides a standard routing infrastructure (= the one configured with the Groovy syntax) which should suffice for just about all routing requirements. ## 6.3 Routing first steps ### 6.3.1 Outline For the purpose of this routing introduction, we assume you have already a working Kauri project with at least one module. If you set up a project using the archetype, then all the steps below will already have been done. The steps to use the routing are as follows: 1. add the routing module to your wiring.xml file 2. import the routing service in your module's Spring container 3. create a router instance as Spring bean using the routing service 4. export the router as a restservice 5. mount the exported restservice on a path 6. (optional) customize the default built-in routing by creating a routing.groovy file These are all small steps, most of which you are already familiar with. We explain them in detail below. ### 6.3.2 The steps to introduce routing #### 6.3.2.1 Add the routing module to wiring.xml In your wiring.xml file, add the following module inside the <modules> element, before any other modules where you want to make use of the routing. <artifact id="routing" groupId="org.kauriproject" artifactId="kauri-routing-impl"/> #### 6.3.2.2 Import routing service in your module Edit your module's Spring XML configuration, which can be found in the KAURI-INF/spring directory. In your module's Spring XML configuration, add the following Java service import, which makes the RoutingService, supplied by the routing module, available within the Spring container as bean id 'routingService'. <kauri:import-service id="routingService" service="org.kauriproject.routing.RoutingService"/> #### 6.3.2.3 Create a router instance We're still in your module's Spring XML configuration. If it is not the case already, add a kauri:module tag somewhere in it. If you have already a kauri:module tag, make sure it contains at least the attributes listed below. <kauri:module restletContext="restletContext" handle="module"/> Then create the actual router by adding this: <bean id="router" factory-bean="routingService" factory-method="createRouter"> <constructor-arg ref="restletContext"/> <constructor-arg ref="module"/> </bean> As you can probably figure out yourself, the values of the constructor-arg's need to match the values of the attributes of the kauri:module. #### 6.3.2.4 Export the router as a restservice Still in your module's Spring XML configuration: <kauri:export-restservice name="router" ref="router"/> #### 6.3.2.5 Mount the exported restservice on a path In the wiring.xml, inside the declaration of your own module, add a mount statement to mount the router on a certain URL path. Thus only the bold section should be copied in your wiring.xml file. <artifact id="mymodule" groupId="...." artifactId="..." version="..."> <mount name="router" path="/router"/> </artifact> You can of course change the "/router" path to whatever you desire, in fact "/router" is not a very good name. #### 6.3.2.6 Try it out Even though we have not made an router configuration yet, you could already try out the router because a default routing configuration is used in absence of a custom one. This default routing configuration, among other things, will make all resources in KAURI-INF/resources available on your router on the path "/resources". So suppose you create a file helloworld.txt in that resources directory, than you can already access it in your browser using the following URL: http://localhost:8888/router/resources/helloworld.txt Before trying this URL, you should as usual build your module (unless you're working in source mode) and restart Kauri. #### 6.3.2.7 Customize the routing Now you can start customizing the routing according to your own needs. This is done by creating a file KAURI-INF/router.groovy in your module. Here's a small example: builder.router { restlet(uri: "/helloworld", handle: { request, response -> response.setEntity("Hello world from inside the router", mediaType.TEXT_PLAIN) }) } This example makes use of the ability to implement a Restlet inline in the router definition, which is not really a good and common practice (usually the restlets are implemented in separate Java classes), but is handy for this sort of examples. The example can be accessed using: http://localhost:8888/router/helloworld ## 6.4 JAX-RS first steps ### 6.4.1 About JAX-RS The official description for JAX-RS (a.k.a. JSR-311) is that it "defines a set of Java APIs for the development of Web services built according to the Representational State Transfer (REST) architectural style". The reason to talk about JAX-RS in this section about routing is because it defines an alternative way to describe routing. Kauri's routing configuration is a central configuration of the routing structure. In contrast to this, with JAX-RS one adds annotations to classes to describe to which paths they react, hence providing a decentralized routing configuration. ### 6.4.2 Trying it out Let's illustrate JAX-RS with a simple example. Let's assume you have added routing to your module as described in Routing first steps. Make sure you do not have a routing configuration at KAURI-INF/routing.groovy, so that the default routing is used. Now create the directory KAURI-INF/groovy-jax-rs In this directory, create a file named HelloWorldResource.groovy, and put the following in it: import javax.ws.rs.Path; import javax.ws.rs.GET; import javax.ws.rs.Produces; @Path("helloworld-groovy") public class HelloWorldScriptResource { @GET @Produces("text/plain") String plainHelloWorld() { return "Hello world from a groovy-based JAX-RS class!"; } } If you are not working in source mode, rebuild your module and restart Kauri. Now you should be able to access the just-created resource at: http://localhost:8888/router/helloworld-groovy This works because the default routing configuration contains a JAX-RS configuration which automatically scans the directory groovy-jax-rs for JAX-RS-annotated classes. In fact, the same is true for Java classes in your module (which always require to rebuild the module and restart Kauri). ### 6.4.3 More on JAX-RS Even without having learned about JAX-RS, you can figure out a lot from the HelloWorld example above. The URI path to which the JAX-RS class should be bound is defined using the @Path annotation. The method which should handle GET requests is annotated using @GET. The GET method simply returns a String. In fact, it could have returned any kind of Java object, since JAX-RS allows to implement classes to convert the returned object to the desired response mime-type. A number of default implementations of such convertors are provided however, one is for handling Strings. A class with an @Path annotation is called a resource class. Upon each request, JAX-RS makes a new instance of the resource class. In Kauri, these instances are created via your module's Spring container, as a consequence of which auto-wiring of dependencies is supported. To learn more about JAX-RS, you can read the specification which (at the time of this writing) can be found on the JAX-RS reference implementation development site. The specification is not very long or complex, so it's easy to learn JAX-RS just from there. ### 6.4.4 Relationship between JAX-RS and Kauri routing The JAX-RS system is in Kauri used by means of creating a jaxRs routing component. The main advantages of using JAX-RS over, say, plain Restlet's or Restlet Resource classes are: • JAX-RS is a specification, which brings the usual benefits of developer familiarity, availability of multiple implementations, reuse of JAX-RS classes in non-Kauri/Restlet environments, ... • the configuration is decentralized, there is no need to touch a central configuration file for each newly added resource. This brings somewhat more magic to the table, but can be convenient if you have lots of resources. ## 6.5 Some background ### 6.5.1 Routing structure From a conceptual point of view, a routing structure can contain the following types of components: • A router: forwards a request to another component, based on certain properties of the request, often the request path. • A filter: something which can be put in between two other routing components and performs some action before and/or after forwarding the request to the next component. • A request handler: the endpoint of the routing. This is the place where application-specific logic is implemented and the response is created. (in Kauri, request handlers are instances of org.restlet.Restlet) All these components can be freely nested inside each other, in order to form a hierarchical routing structure. The request handlers are the leaves of the routing structure. When you think a bit about it, there is no fixed line where the routing ends. A request handler in itself might contain code which makes decisions based on request properties and delegates to other methods or classes. We don't consider this to be part of the routing anymore though since it is not visible in the routing configuration and hence Kauri doesn't know about it. ### 6.5.2 Groovy as routing configuration syntax The configuration syntax for the routing is not a plain data file like XML, but rather an executable program in the form of a Groovy script. Groovy has a standard pattern for describing tree-structures in an easy-to-read manner, which will look like a plain data syntax unless you start making use of more advanced features. This way of using an existing programming language in such a way that it looks like a specialized syntax is called an internal DSL. ###### Groovy as syntax: pro and con Some of the pro's of using Groovy as syntax are: • It is no XML: the syntax is 'lighter', e.g. braces are used instead of verbose open and close tags. • More flexibility: the script can contain anything as long as the result of its execution is a Restlet instance. • It allows to embed inline request handlers or filters, which can be useful in some simple cases. To be fair, some cons are: • As it offers all freedom of a programming language, it enforces less discipline but allows for more hacking. In other words, the power should be used wisely. • It is code instead of data: it is not read but executed. • The error reporting is the standard Groovy error reporting. ###### Groovy performance You might have heard that Groovy is slow and hence naively think that doing the routing in Groovy will introduce a bottleneck in the system. This is a false reasoning, since the Groovy script is executed only once and serves to create the internal routing structure. It is really just an alternative for other e.g. XML syntax. The internal routing structure doesn't make use of Groovy and could be built up by other means as well. ## 6.6 Default routing When you create a router without specifying a custom location for the router configuration, the routing will be searched at KAURI-INF/router.groovy. If this file does not exist, a default built-in configuration will be used as fallback, which is the following: builder.router { directory(uri: "/resources", root: "module:/resources/") jaxRs(uri: "") { jaxRsResource(scanPackages: "*") jaxRsProvider(scanPackages: "*") jaxRsGroovyScripts(path: "groovy-jax-rs") } } This default routing makes available all files in KAURI-INF/resources as /resources, and automatically scans the module jar for any Java classes with JAX-RS annotations, as well as any Groovy scripts with JAX-RS annotations in KAURI-INF/groovy-jax-rs. ## 6.7 Routing examples If you read the documentation in order, you will already have encountered some examples of routing configuration. For the full description of all possible things, you can consult the routing reference documentation. However, some examples can be useful to show how everything glues together. [TODO: add one or more examples. I'm thinking of multiple hierarchical routers, filters, restlets, ... all together] [See the routing sample included with Kauri for now] ## 6.8 Spring integration For a Restlet or a resource class to do something useful, it will likely need access to the beans declared in your module's Spring container. The module's Spring container is used for instantiating all classes specified in the routing configuration using the ofClass attribute, as well as the JAX-RS resource and provider classes. What this means is that Spring will create the instance of the class, and honor the Spring-related annotations on it. Spring will however not manage the complete life-cycle of the object, so e.g. @Destroy annotations will not be honored. The most useful is Spring's Autowired annotation. Below is an example of its usage. The system will automatically look up a bean in your Spring container of the 'MessageService' type. If there would be multiple of those, then there are additional annotations to select the correct implementation. See the Spring documentation for more information. import org.springframework.beans.factory.annotation.Autowired public class MessageResource { private MessageService messageService @Autowired void setMessageService(MessageService messageService) { this.messageService = messageService; } } ## 6.9 URI template syntax Routers in Restlet and Kauri match URIs based on URI templates. A URI template is basically a string containing named wildcards, called variables, between { and }. An example: /users/{id} By default, the variable {id} will only match URI segments, basically any text not containing the slash character. You can define various options for the variables. The options are specified by adding them comma-separated after the variable name: {var,option1,option2,option3}. The options are (in sequence of usefulness): • the type of variable: what characters are consumed by the variable. The default is "uri_segment". See table below. • should the variable be decoded? By default it is not decoded. Specify option "decode" to decode it. • is the variable required or not. If not, an empty string will be matched. By default it is required. Specify option "optional" to make the variable optional. • is the variable fixed. A fixed variable is not really a variable, it will always match the same value, but will still cause a request attribute to be set. Useful for things that might eventually become variable. Specify option "fixed" to make the variable fixed. The fixed value can be specified after the variable name like this: {varname=value,fixed}. The options can be specified in any order. It does not make sense to specify multiple variable type options. For example, to decode a variable and match all URI path characters (thus possibly multiple path segments), use: /users/{id,uri_path,decode} Variable types Option name Description all Matches all characters. alpha Matches all alphabetical characters. alpha_digit Matches all alphabetical and digital characters. comment Matches any TEXT excluding "(" and ")". comment_attribute Matches any TEXT inside a comment excluding ";". digit Matches all digital characters. token Matches any CHAR except CTLs or separators. uri_all Matches all URI characters. uri_fragment Matches URI fragment characters. uri_path Matches URI path characters (not the query or the fragment parts). uri_query Matches URI query characters. uri_scheme Matches URI scheme characters. uri_segment Matches URI segment characters. uri_unreserved Matches unreserved URI characters. word Matches all alphabetical and digital characters plus the underscore. ## 6.10 Routing reference ### 6.10.1 Basic syntax rules As mentioned elsewhere, the routing configuration syntax is essentially a program written in the Groovy language. However, don't let that scare you away with the thought of having to learn yet another language, since you get can a long way without knowing Groovy. You can pick up the syntax by looking at some examples, such as this: builder.router { restlet(uri: "/helloworld1", ofClass: "org.mycomp.HelloWorld1") restlet(uri: "/hello/world2", ofClass: org.mycomp.HelloWorld2") router(uri: "/hello") { restlet(uri: "/world3", ofClass: org.mycomp.HelloWorld3") } } In case you're wondering, this example will react on URIs starting with: /helloworld1 /hello/world2 /hello/world3 From this example you can see the basic rules: • components names are optionally followed by a set of parameters between brackets • the parameters are a comma-separated list of name value-pairs, the name and value separated by a colon • components nested inside another component are listed within curly brackets following the component • the top-level component (usually a 'router') is prefixed with 'builder.' ### 6.10.2 Setting generic properties on routing components The documentation of the individual routing components describes the parameters supported by those components. Besides what is documented, the system will automatically try to call a setter method on the routing component for any other parameters you specify. For example, if you would have a look at the API documentation of Restlet's Router class, you would see it has the following setter method: public void setRetryDelay(long retryDelay) You can set this parameter as follows: builder.router(retryDelay: 50) { [...] } In general, most of the commonly useful parameters can be found in Kauri's documentation, so you only need to know this for advanced usage. ### 6.10.3 Variables available in the script [TODO] moduleContext: the Restlet context of the Kauri module. confRegistry: the ConfRegistry associated to the module. (see Configuration ) inSourceMode: a boolean indicating if the module in which the routing is created was loaded in source mode or not. ### 6.10.4 Advanced things Since the router configuration is Groovy code, you can write any control structures in it as you like. We advise however to keep the routing configuration as close to static data as possible. This will make it easier to understand for users with no or less knowledge about Groovy. But just for fun and general knowledge, let us look at some examples. The following example will create 10 restlets attached to 10 different URIs on the router: "/helloworld0", "/helloworld1", ..., "/helloworld9". The loop is executed during the building of the routing structure, thus not during actual routing. builder.router { 10.times { i -> restletRoute = restlet(uri: "/helloworld" + i, handle: { request, response -> response.setEntity("Hello world from inside the router " + i, mediaType.TEXT_PLAIN) }) } } The following example shows two things: the currently constructed component is available inside its following {} part as a variable named current, and it shows how to print things to the console. Again, the print is executed only once, during the building of the routing structure. builder.router { print("The current routing component is:${current}")
}

## 6.11 Common parameters

The following parameters are supported by many of the routing  components.

Name

Description

ofClass

Specifies a fully qualified class name of an object to create (e.g. a restlet, filter, resource, ...). The class will be instantiated by the Spring container, so supports auto-wiring annotations.

ofBean

Specifies the ID of a bean in the Spring container. This can be used instead of ofClass.

postAttach

Applies to components nested in routers. See the router documentation for more details.

uri

match

autoAttach

Surprisingly, this won't do something with a car, but rather is a boolean that can be used to disable the automatic attaching to a router of the components nested within it.

## 6.12 challenge

You should use Kauri Security rather than this challenge mechanism for more complex use-cases.

'challenge' creates a Restlet ChallengeAuthenticator, which is a special purpose filter.

Name

Description

realm

Realm to send in HTTP Basic and HTTP Digest challenges.

scheme

Authentication scheme to use.

verifier

The verifier to use (implementation of org.restlet.security.Verifier)

##### Syntax / Examples

Protect a single resource:

import org.restlet.data.ChallengeScheme;
import org.restlet.security.MapVerifier;

builder.router {

def verifier = new MapVerifier();
verifier.localSecrets.put("scott", "tiger".toCharArray());

def chlng = challenge(
uri:"",
scheme:ChallengeScheme.HTTP_BASIC,
realm:"Restlet Tutorials",
verifier: verifier);

chlng.next = router() {
uri: "/",
match: "equals",
data: "module:/resources/greeting.json",
template: "module:/templates/index.xml",
mediaType: "text/html"
)
}

Protect multiple resources (a TemplateRestlet at "/" and a DirectoryResource at "/resources")

import org.restlet.data.ChallengeScheme;
import org.restlet.security.MapVerifier;

builder.router {

def verifier = new MapVerifier();
verifier.localSecrets.put("scott", "tiger".toCharArray());

def chlng = challenge(
uri:"",
scheme:ChallengeScheme.HTTP_BASIC,
realm:"Restlet Tutorials",
verifier: verifier);

chlng.next = router() {
uri: "/",
match: "equals",
data: "module:/resources/greeting.json",
template: "module:/templates/index.xml",
mediaType: "text/html"
)

directory(uri: "/resources", root: "module:/resources/")
}
}

Avoid hardcoding the secrets (still bad, we still use plaintext passwords)

import org.restlet.data.ChallengeScheme;
import org.restlet.data.ChallengeScheme;
import org.restlet.security.MapVerifier;

builder.router {

def verifier = new MapVerifier();
def accounts = new Properties();
for (String key: accounts.key) {
verifier.localSecrets.put(key, accounts.getProperty(key).toCharArray());
}

def chlng = challenge(
uri:"",
scheme:ChallengeScheme.HTTP_BASIC,
realm:"Restlet Tutorials",
verifier: verifier);

chlng.next = router() {
//...
}
}

## 6.13 directory

'directory' creates an org.restlet.Directory, which is a static file server. It supports content negotiation and directory listings.

##### Parameters

Name

Description

root

The root of the directory, specified as URI. Access to resources in upper directories (using ../) is prevented.

Examples:

file:///etc
module:/resources  (-> files in the KAURI-INF/resources
directory in the module archive)
##### Example
router {
directory(uri: "/resources", root: "module:/resources/")
}

## 6.14 filter

'filter' is used to create an org.restlet.Filter. A filter delegates request handling to another routing component, but can do something before and after delegating the request.

Filters are ideal for initializing some context needed by anything further down the URI space, to check authentication or authorization, to customize error handling, etc.

##### Parameters

Name

Description

after

Closure implementing the Filter.afterHandle method. (see Restlet API docs for details).

before

Closure implementing the Filter.beforeHandle method.

handle

Closure implementing the Filter.doHandle method.

##### Syntax

For a filter implemented in Java:

filter (ofClass: "my.package.MyFilter") {

[... nest exactly one other component ...]

}

For a filter implemented directly in the router:

import org.restlet.routing.Filter

[...]

filter(uri: "",
before : { request, response ->
println("Going through a filter");
return Filter.CONTINUE;
}) {

[... nest exactly one other component ...]

}

The nested component can be any other kind of routing component (= any kind of Restlet), including a router or another filter.

This example filters all requests for "/admin" to check authentication information:

import org.restlet.routing.Filter

[...]

builder.router {

before : { request, response ->
// TODO implement authentication check
return Filter.CONTINUE;
}) {

router {
}
}

For authentication purposes, there is a pre-made challenge filter.

## 6.15 jaxRs

'jaxRs' creates a JAX-RS subsystem, which handles requests (routing and response representation production) based on JAX-RS annotated classes.

The JAX-RS resource classes and provider classes can be listed manually, or can be auto-scanned from your module. Groovy-based JAX-RS classes are also supported.

##### Syntax
jaxRs(uri: "") {

jaxRsResource(ofClass: "fully.qualified.ClassName")
jaxRsResource(scanPackages: ["my.package1", "my.package2])

jaxRsProvider(ofClass: "fully.qualified.ClassName")
jaxRsProvider(scanPackages: ["my.package1", "my.package2])

jaxRsGroovyScripts(path: "groovy-jax-rs")
}

The nested elements specify the various resource and provider classes to use. You can repeat the jaxRsResource and jaxRsProvider as many times as needed.

You can specify classes manually by using the ofClass parameter:

jaxRs(uri: "") {
jaxRsResource(ofClass: "my.package.Resource1")
jaxRsResource(ofClass: "my.package.Resource2")
jaxRsResource(ofClass: "my.package.Resource3")
}

Alternatively, you can let the system scan packages (non-recursively) for JAX-RS classes using the scanPackages parameter which takes one string or a list of string as parameters. By specifying the value "*' for scanPackages, the complete module jar will be scanned:

jaxRs(uri: "") {
jaxRsResource(scanPackages: "*")
}

Note that class scanning is limited to classes within the module jar. If there are JAX-RS classes within the module's classpath, they will hence need to be listed manually (which is best anyway to avoid suprise-resources).

Using jaxRsGroovyScripts you can specify a (= one) path containing Groovy-implemented resource classes. The Groovy files should follow the rules for being loadable by the Groovy ClassLoader, basically meaning they should have '.groovy' as extension and the filename should correspond to the class name.

Note that Groovy files which are compiled as part of building your module are simply supported the same as regular classes, the jaxRsGroovyScripts element is only for runtime compiled code.

When running in source mode, the Groovy directory will be watched for changes so that the JAX-RS system will be recreated.

The uri specifies on which path to mount the JAX-RS resources. See the  router documentation for more details. Consider the following configuration (with BarResource having a @Path("bar") annotation):

jaxRs(uri: "foo") {
jaxRsResource(ofClass: "my.package.BarResource")
}

Because the "start" matching mode will be used, both foo/bar and foobar will match the above uri-template. You can easily avoid the second match by adding a slash to the uri:

jaxRs(uri: "foo/") {
jaxRsResource(ofClass: "my.package.BarResource")
}
##### Debug

In case you're wondering if the JAX-RS system has found your classes, you can enable the debug output for the JAX-RS component by adding the following options when starting Kauri:

-l debug -m org.kauriproject.routing

The most common mistake is forgetting the required annotations: for a GET request, the class needs to have at least the @Path annotation, and one method with @GET and @Produces.

##### JAX-RS @Path should not start with a slash, the jaxRs router should be mounted on a path ending with slash

While this is not specific to JAX-RS, it might be helpful to repeat it here anyway:

• the @Path annotations on your root resource classes should not start with a slash. This is not Kauri specific, but required by the JAX-RS specification.
• by consequence, the jaxRs router should be mounted on a path that ends on a slash (the slash is consumed by the router), so that the path which needs to be matched by the jaxRs router does not start with a slash (otherwise it would not match what is in the @Path):
• use jaxRs(uri: "foo/") in the router
• or when using jaxRs(uri: ""), use <mount path="/foo/" ... > in the wiring.xml

The reason for this is that otherwise the URIs constructed by JAX-RS would start with a slash, and hence be absolute. This gives problems constructing correct response URIs (e.g. the Location header).

To give a bad example: suppose the @Path annotation of a resource class is "/bar", and the jaxRs router is mounted on "foo", giving a base URI (in Rest: Request.resourceRef.baseRef) of http://localhost/foo. Combining both would give http://locahost/bar, not the expected http://localhost/foo/bar, because /bar is absolute and thus replaces the existing path.

## 6.16 mode

'mode' creates a filter which passes execution on to the next (= nested) component depending on what Runtime mode is enabled.

##### Syntax
mode(when: "...") {
[nested component]
}

The when parameter can contain a comma-separated list of runtime mode names for which the execution should continue.

Valid mode names are: prototype, production.

The special value "all" is used to denote the set of all modes. This is useful in combination with the ability to substract modes by adding a minus in front of them. For example:

mode(when: "all,-prototype") {
[nested component]
}

This mode filter will pass on execution for all modes but the prototype mode.

If the current Kauri Runtime mode does not match the modes in the list, then the filter will set a status of "404 Not Found" on the response, as well as the special response attribute necessary for the passThrough-feature of the router, these features together allow to activate different components depending on the current mode.

##### Example

Below is an example taken from a testcase.

Since the mode is a routing component like any other, it needs a uri attribute to attach it to the containing router.

builder.router {
mode(uri: "", passThrough: true, when: "prototype") {
pages(root: "/site/pages", ignore: ".svn CVS ignorethis")
}

resource(uri: "/person/{id}.html",
ofClass: "org.kauriproject.routing.test.testmodules.routing2.PersonResource")

mode(uri: "", when: "all,-prototype") {
pages(root: "/site/pages")
}
}

## 6.17 pages

'pages' creates a component which, based on a file system directory, offers the following functionality:

• performs routing based on the file paths within this directory. File and directory names can contain {variables} to create a non-fixed URI space. The file path will be interpreted as a URI template, see URI template syntax.
• all files below the specified directory will be treated as executable templates, hence allowing PHP-style or "Model 1"-style execution of templates without the need to go through a resource class (a.k.a. controller).

This might sound complicated, but is actually very easy to use.

An example will make this more obvious. You can have a file system structure like this:

/person/{name}.html
/person/{name}-edit.html
/persons.html

Yes, you see that right: we use the { and } characters within file names.

The pages component will build a standard Restlet router based on this file structure, the file paths are actually directly usable as URI templates.

The files are treated as templates which are executed 'as is', without first going through a controller. To pull data into the templates, you can use the variable instruction with src attribute. The {variables} from the path are accessible in the template using ${request.attributes.name}. With the pages component, we don't want to promote "Model 1"-style development, but this component gives extra power to people wireframing or prototyping a web front-end. The template output is usually serialized as HTML, except if the URI path ends on ".xml", in which case it is serialized as XML. ##### Syntax The basic syntax is this: builder.router { pages(uri: "", root: "pages") } The root parameter specifies a directory, below KAURI-INF, to be used as root for the filesystem-based routing. This cannot be an arbitrary URI. If you run the application in source mode, changes are automatically picked up without restart. Optionally, you can specify a parameter 'ignore' containing a space-separated list of file names to ignore, in this star (*) can be used as a wildcard. If not specified, default excludes are used, among which .svn, CVS, .DS_Store, ... ##### Double extensions In some cases you might want files to have a different extension on the filesystem and the URI space (because of application-associations), or to have no extension at all in the URI space, while still having an extension on the file system. We allow to do this using double extensions. Some examples will make this clear: Filesystem path URI path /person/{id}.html.xml /person/{id}.html /person/{id}..xml /person/{id} ##### index.html URI paths ending on /index.html are also automatically assoicated with the same URI without "index.html". ## 6.18 read 'read' is a shortcut to create a Restlet which reads a resource. ##### Parameters Name Description source The URL from which to read data to return to the client. This is an URI template. mediaType optional, allows to change the response media type to something else. Its value should be a Restlet MediaType object. Example: mediaType.TEXT_PLAIN or mediaType.TEXT_HTML ##### Example read(uri: "/resources/{path}", source: "module:/resources/{path}", postAttach : { route -> Variable variable = new Variable(Variable.TYPE_URI_PATH, "", true, false) route.getTemplate().getVariables().put("path", variable) }) ## 6.19 redirector 'redirector' creates an org.restlet.Redirector, whose purpose is to create a redirect response. ##### Parameters Name Description mode One of: redirectorMode.MODE_CLIENT_PERMANENT (301) redirectorMode.MODE_CLIENT_FOUND (302) redirectorMode.MODE_CLIENT_SEE_OTHER (303) redirectorMode.MODE_CLIENT_TEMPORARY (307) redirectorMode.MODE_DISPATCHER (= Restlet internal redirect) targetTemplate A URI template to define the URI to redirect to. ##### Which redirect-mode to use? Good question. Traditional redirects as done by servlets typically result in a 302 response, though 303 and 307 are usually better choices. See resources such as the RWS book for a detailed treatment. ##### Variables availabe in the targetTemplate The variables are resolved in the following order: • request object attributes • response object attributes • entries as specified in the table found in the org.restlet.util.Resolver javadoc. ##### Allowed redirect-locations The resolved targetTemplate will end up as the Location: header in the HTTP response. In actual responses over the wire this always needs to be an absolute URI (including scheme and host!), but for convenience the kauri runtime will help out making correct absolute public URIs based for: • relative URI: these will be resolved versus the current request URI • service URI: (ie. starting with the service:/ pseudo-protocol): these will be resolved versus the public mounted path as described in the wiring.xml (This is similar to the URI Resolving in the templates) ##### Examples builder.router { redirector(uri: "/redirect-me", mode: redirectorMode.MODE_CLIENT_TEMPORARY, targetTemplate: "http://www.google.com/search?q=linkto:{ri}") } The {ri} variable in this example returns the resource identifier, basically the complete request URI. So suppose the router is mounted such that the following request addresses the redirector: http://localhost:8888/myrouter/redirect-me Then the client would be redirected to: http://www.google.com/search?q=linkto:http://localhost:8888/myrouter/redirect-me ## 6.20 resource 'resource' is used for adding subclasses of org.restlet.resource.Resource to the routing. Both org.restlet.resource.Resource and org.restlet.Restlet (as supported by the restlet routing instruction) allow to implement code to handle a request. Resource is different from Restlet in that it is: • a higher-level API • a new instance is created for each request, so Resource's don't need to be thread-safe Typically the Restlet class will be used for more system/infrastructure-level work, while the Resource class should be used for everyday resource implementation work. An alternative for Resource is the JAX-RS API. ##### Parameters (There are parameters available to implement resources inline in the routing using closures, but we recommend using ofClass/ofBean instead) ##### Example The following example of a Resource implementation is stolen from the Restlet project: package org.restlet.example.book.restlet.ch4; import org.restlet.Context; import org.restlet.data.MediaType; import org.restlet.data.Request; import org.restlet.data.Response; import org.restlet.resource.Representation; import org.restlet.resource.Resource; import org.restlet.resource.ResourceException; import org.restlet.resource.StringRepresentation; import org.restlet.resource.Variant; public class HelloWorldResource extends Resource { public HelloWorldResource() { // A default constructor is required in this case. } public void init(Context context, Request request,Response response) { super.init(context, request, response); // Declare all kind of representations supported by the resource getVariants().add(new Variant(MediaType.TEXT_PLAIN)); } @Override public Representation represent(Variant variant) throws ResourceException { Representation representation = null; // Generate the right representation according to the variant. if (MediaType.TEXT_PLAIN.equals(variant.getMediaType())) { representation = new StringRepresentation("hello, world", MediaType.TEXT_PLAIN); } return representation; } } It is attached to a router as follows: router { resource(uri: "/helloworld", ofClass: "org.restlet.example.book.restlet.ch4.HelloWorldResource") } ## 6.21 restlet 'restlet' is used to create any type of org.restlet.Restlet. You can refer to classes, to Spring beans or implement a Restlet inline using a closure. You should also consider using resource. ##### Parameters Name Description handle Closure implementing the Restlet.handle() method. ##### Syntax A Restlet implemented inline: ... restlet(uri: "/helloworld", handle: { request, response -> response.setEntity("Hello world from inside the router", mediaType.TEXT_PLAIN) }) ... A Restlet implemented in Java: ... restlet(uri: "/helloworld", ofClass: "com.mycompany.MyRestlet") ... Just one instance of this Restlet class will be created, the instantiation is delegated to Spring so things like autowiring annotations will work. ## 6.22 router 'router' creates an org.restlet.Router. This is the central part of the whole router configuration. The components created by the other routing configuration elements are usually attached to a Router. An exception is that components can also be attached as delegate to a filter. When attaching a component to a router, certain parameters can be specified, most importantly the URI, as shown in this example which creates a router with two resources attached to it: builder.router { resource(uri: "/user/{name}", ofClass: "mystuff.UserResource") resource(uri: "/order/{orderId}", ofClass: "mystuff.OrderResource") } The uri parameter of the resources is not an attribute for the resources themselves, but for attaching the resource to the router. So certain parts of the router-related configuration are specified on the components nested inside the router. The main reason for explaining this is because this part of the configuration will be discussed here, rather than repeating it for each component. By default, a router will match URI patterns in "starts" mode. This means the URI pattern will match for a given request URI if the request URI starts with the URI pattern. So a request URI of "/fooxyz" will be matched by the URI pattern "/foo". The matching mode can be changed for the router as a whole or for each individual route of a router. For the above example, it is better to change the match mode to "equals", like this: builder.router(match: "equals") { resource(uri: "/user/{name}", ofClass: "mystuff.UserResource") resource(uri: "/order/{orderId}", ofClass: "mystuff.OrderResource") } ##### Parameters for the router itself Name Description type The kind of router to create. Supported values: • "restlet": creates a normal Restlet Router. • "kauri": creates a Kauri-specific subclass of the Restlet Router, which has some specific behavior and functionality. The default is "kauri". routingMode This parameter only applies when the router type is set to restlet. When the router type is kauri, it is always the first matching pattern which is used. Set this to one of: routingMode.BEST|CUSTOM|FIRST|LAST|NEXT|RANDOM match Sets the default matching mode for all Routes within this Router. Its value can be the string "equals" or "start". The default is "start". This can be overridden for each individual Route. todo: explain more is possible, see Restlet docs for full details. ##### Parameters for components attached to a router The following are parameters which can be supplied to any sort of component attached to a router. Name Description uri A URI pattern, in URI template syntax. See URI template syntax. postAttach A closure which will be executed after the component has been attached by the router. See detailed explanation below. match Sets the matching mode for this router. Its value can be the string "equals" or "start". The default is "start", though this default can be overridden by adding a match parameter on the router, see above. passThrough This parameter only applies when the router type is kauri. If this boolean parameter is set to true (default is false) and after the attached restlet has been called the response is "404 Not Found" and additionally the response carries an indication that the 404 is because the URI pattern is not recognized, then the router will continue the matching process with the routes that follow the current one, in sequence. The "special indication" is a response attribute org.kauriproject.routing.no_route with as value Boolean.TRUE. Various components created through the routing config support this: router, jaxRs, mode. This feature can be useful when the attached restlets perform (some sort of) routing themselves. For example, the following snippet delegates all requests to JAX-RS, and if there was no resource class to handle the request, goes on matching the routes that follow it. router { jaxRs(uri: "", passThrough: true) pages(uri: "", root: "pages") } ##### Fine-grained configuration via postAttach Attaching a component to a router creates a Route object, via this Route object various options can be set. In the routing configuration, this can be done by specifying a closure via the postAttach parameter. The name postAttach comes from the fact that it is a closure which will be called after (= post) the attaching of the component to the router. The closure takes one argument, the Route instance. One of the more interesting things which can be done via postAttach is setting options on the Template contained in the Route. The Template object represents the URI template expression. As an example, see this illustration from the read component: read(uri: "/resources/{path}", source: "module:/resources/{path}", postAttach : { route -> Variable variable = new Variable(Variable.TYPE_URI_PATH, "", true, false) route.getTemplate().getVariables().put("path", variable) }) For full information on all the capabilities, see the Restlet API documentation: Route class, Template class, Variable class. ## 6.23 template 'template' is a shortcut to create a Restlet which will execute a Kauri template, optionally passing it the data retrieved from a certain URL. To use the template instruction, you need to pass a template service implementation when constructing the router. If you're not sure this is already the case, then see here. IMPORTANT WARNING: there's some chance that this class will be removed in the near future to replace it by a more powerful system to support wireframe-based application prototyping. ##### Parameters Name Description template The URL from which to read the template. This is a URI template. mediaType The mediaType to send in the response. Default is text/xml. data The URL from which to read the data. This is a URI template. This is optional. The data should be a JSON file. The data will be made available to the template as a context attribute "data". dataMediaType The mediaType for the data. If the data URL would not return a correct media type and you don't control the called service, then you can override the media type using this parameter. ##### Example template(uri: "/template/{templateId}", template: "module:/templates/{templateId}.xml", mediaType: "text/html", data: "module:/templates/{templateId}.json") ## 6.24 Routing module ### 6.24.1 Introduction In Routing first steps you could read how to introduce the routing module in your wiring.xml and import its RoutingService in your own module. The remainder of the documentation is mainly about the Groovy-based router configuration syntax. There are few things which can be interesting about the module itself though. ### 6.24.2 Routing configuration options When constructing the router, you can pass a RoutingConfig instance on which you can set various optional properties. The below snippet shows all the options. You only need to set those properties which you are interested to change. <bean id="router" factory-bean="routingService" factory-method="createRouter"> <constructor-arg ref="restletContext"/> <constructor-arg ref="module"/> <constructor-arg> <bean class="org.kauriproject.routing.RoutingConfig"> <!-- The location of the Groovy router configuration. The specified location should be a path somewhere below KAURI-INF, using arbitrary URIs is not possible. --> <property name="configPath" value="myrouter.groovy"/> <!-- If the router configuration file is not found, should the built-in default be used instead? If not, an exception will be thrown. --> <property name="fallBackToDefault" value="true|false"/> <!-- Some routing instructions need a template service in order to perform their work. In that case, you need to supply it using this property. --> <property name="templateService" ref="templateService"/> <!-- Provide custom factories for the routing language implementation. This allows to extend the routing config with your own instructions. --> <property name="customFactories"> <map> <entry key="myinstruction" ref="..."/> </map> </property> </bean> </bean> ### 6.24.3 Step by step: supplying a template engine to the routing Assuming you are already using routing in your module, but the router has no access to the template engine yet, then here you can find how to set this up. Make sure you have the template module declared in your project's wiring.xml (if it's already there, then skip this step): <artifact id="templateModule" groupId="org.kauriproject" artifactId="kauri-template-service-impl"/> In the spring container of your module, import the template service using kauri:import-service (again, if it's already there, skip this step): <kauri:import-service id="templateService" service="org.kauriproject.template.service.TemplateService"/> When constructing the router, pass the templateService via the RoutingConfig. <bean id="router" factory-bean="routingService" factory-method="createRouter"> <constructor-arg ref="restletContext"/> <constructor-arg ref="module"/> <constructor-arg> <bean class="org.kauriproject.routing.RoutingConfig"> <property name="templateService" ref="templateService"/> </bean> </constructor-arg> </bean> ### 6.24.4 Multiple routers in one module Since you can specify alternative routing configuration file locations, as explained above, it can make sense to create multiple routers. This can be done by creating multiple router beans and exporting them as multiple restservices, which is obvious if you know a bit of Spring. ### 6.24.5 Extending the routing DSL It is possible to extend the routing DSL (= domain specific language) with your own elements. [Not sure if we should document this in more detail since this might lead to a proliferation of the routing language.] # 7 Representation builder ## 7.1 What is a representation Kauri has a flexible system for producing resource representations. For developers familiar with other frameworks, this is similar to what is often called the "view", the V in the MVC pattern. Here is a nice description of what a representation is: "REST components perform actions on a resource by using a representation to capture the current or intended state of that resource and transferring that representation between components. A representation is a sequence of bytes, plus representation metadata to describe those bytes. Other commonly used but less precise names for a representation include: document, file, and HTTP message entity, instance, or variant." (Fielding) So for example, a representation is both the HTML page transferred to your browser when doing a GET request, as well as the body of a form posted towards the server. The representation builder system described here focuses on the production of representations served towards the client, and not handling of representations submitted towards the server. ## 7.2 The need for a representation builder module ### 7.2.1 Moving the mechanics of representation production out of resource classes In the core Restlet API, a resource class is responsible for creating the response representation and setting it on the response object. This is done by creating an instance of a subclass of Representation. For very simple and very complex cases, it makes sense to do this directly in the resource class. In a typical web application, you will often produce representations using a template. In Kauri, this means the resource class should have a handle to (= dependency on) the TemplateService and use that to create a TemplateRepresentation. This works just fine. However, it is a very 'manual', hardcoded and somewhat laborious way of constructing the representation. It would be easier if the resource class only needs to return a logical representation name and the data objects. The mapping of the logical name to the real implementation can then be done somewhere else, outside of the concern of the resource class. And this is exactly what Kauri's representation module provides. For people familiar with Spring MVC, this is similar to the ModelAndView and the ViewResolver. For people familiar with Apache Cocoon, this is similar to the sendPage call. For people familiar with JAX-RS, this is somewhat the same role as the MessageBodyWriter providers. ### 7.2.2 Creating representations in case of errors and exceptions Resource classes may throw (runtime) exceptions or set an error response status without specifying a body. See also the section on error handling. The representation builder will catch all throwables and set an error response status code and response body. In case an error response status is set, but no response body is present, the representation builder can create the response body. For both cases, the response to be created is configurable. ## 7.3 First steps ### 7.3.1 Adding the module This part needs to be done once for your project. If you have generated a project using the archetype, this will already be in-place. #### 7.3.1.1 Add the representation builder module to wiring.xml In your wiring.xml file, add the following module inside the <modules> element, before any other modules where you want to make use of the representation builder. <artifact id="representation-builder" groupId="org.kauriproject" artifactId="kauri-representationbuilder-impl"/> #### 7.3.1.2 Import representation builder in your module and install it Edit your module's Spring XML configuration, which can be found in the KAURI-INF/spring directory. If it is not the case already, add a kauri:module tag somewhere in it. If you have already a kauri:module tag, make sure it contains at least the attribute listed below. <kauri:module handle="module"/> Add the following tags, which import the RepresentationBuilder service (which is supplied by the kauri-representationbuilder-impl module) and installs it in the current module. <kauri:import-service id="representationBuilder" service="org.kauriproject.representation.build.RepresentationBuilder"/> <bean factory-bean="representationBuilder" factory-method="install"> <constructor-arg ref="module"/> </bean> ### 7.3.2 Making use of the representation builder To make use of the representation builder, you need to do two things: 1. in a resource class, create a KauriRepresentation instance containing a logical name identifying the representation and the data objects necessary to produce the representation 2. configure the representation builder so that this logical name is resolved to an actual representation. #### 7.3.2.1 Creating a KauriRepresentation instance If your resource class is implemented using the core Restlet API, then you need to create the instance and either: • for plain Restlet subclasses, in the handle method, set it on the response • for Resource subclasses, return it from the represent method. Here's an example of the second case: import org.kauriproject.representation.build.KauriRepresentation; ... public Representation represent(Variant variant) throws ResourceException { Representation representation = null; if (MediaType.TEXT_PLAIN.equals(variant.getMediaType())) { Map<String, Object> reprData = new HashMap<String, Object>(); reprData.put("message", "Hello world!"); return new KauriRepresentation("helloworld", reprData); } return representation; } If your resource class is implemented using the JAX-RS API, then you can simply return a KauriRepresentation instance: import org.kauriproject.representation.build.KauriRepresentation; ... @GET public KauriRepresentation get() { Map<String, Object> reprData = new HashMap<String, Object>(); reprData.put("message", "Hello world!"); return new KauriRepresentation("helloworld", reprData); } #### 7.3.2.2 Configure logical name to actual representation mapping In case you don't create a specific configuration, there is a default mapping which will map the logical name to a template file name. For the above examples, helloworld is used as the logical name, and will result in the template module:/templates/helloworld.xml to be used. If you want to customize the mapping, or make use of non-template based representations, you will need to create a custom configuration. ## 7.4 Some background TODO [explain use of filter + little diagram of where the filter fits in] ## 7.5 Default configuration When you use the representation builder in a module without specifying a custom location for the configuration, it will be searched at KAURI-INF/representations.groovy. If this file does not exist, a default built-in configuration will be used as fallback, which is the following: builder.representations { select { when(name: "{name,all}") { template(src: "module:/templates/{name}.xml") } } exceptions { exception { template(src: "clap://thread/org/kauriproject/representation/defaulterrorpage.xml") } } errors { error { template(src: "clap://thread/org/kauriproject/representation/defaulterrorpage.xml"); } } } This default configuration will try to map the logical representation name to a template file in KAURI-INF/templates. In case of an exception or an error status, a built-in template will be used to generate an error page. ## 7.6 Configuration reference ### 7.6.1 Overview #### 7.6.1.1 Location of the configuration file The default location for the configuration file is KAURI-INF/representations.groovy. In the Maven source tree layout, this is at src/main/kauri/representations.groovy. If you do not have such a configuration file, it suffices to create it and it will be automatically used. If you are running in source mode, this change will be picked up immediately, if you're not running in source mode you need to rebuild the module and restart Kauri. #### 7.6.1.2 Syntax The configuration file is a Groovy program, using the GroovyBuilder pattern. This is the same as for the routing. The routing documentation contains details on motivation and basic syntax information. However, everything you need to know for normal usage can be found below. #### 7.6.1.3 Examples Below you'll find the basic reference information. To see examples of how this all fits together, check out the samples included with Kauri. ### 7.6.2 Basic structure The configuration consists of three sections: 1. A section for mapping logical representation names to actual representations. 2. A section for mapping exception classes to representations. 3. A section for mapping error status codes to representations. This is the minimal structure containing the placeholders for those three sections: builder.representations { select { } exceptions { } errors { } } ### 7.6.3 Mapping logical representation names to representations The basic tool for this mapping is a switch-structure using 'select' and 'when' as the syntactic elements: select { when(name: "foo") { template(src: "module:/templates/foo.xml") } when(name: "bar", mediaType: "text/html") { template(src: "module:/templates/bar.xml") } when(name: "something/{remainder,all}") { select { when(name: "something/A/B/C") { template(src: "module:/templates/A.xml") } when(name: "something/X/Y/Z") { template(src: "module:/templates/X.xml") } } } } Here is everything you need to know about the 'when' node: • A name parameter specifies a pattern to match on the logical representation name. • A mediaType parameter specifies a pattern to match on the requested media type. • The name and mediaType parameters can be combined or used by themselves. A when clause without name or mediaType parameter will always match. • The patterns are in URI template syntax, hence similar to what is used in the routing configuration. In contrast to the routing, the patterns are always matched in "equals" mode, meaning that the pattern must match the whole input string. • during the matching process, the when nodes are processed in order (not with a best match, as done in the routing). A 'when' node should contain exactly one child node, which can be: • a node that defines the representation to be created. In the above example, we used the 'template' node, but there are others available as well. • again a select node. Nesting select's inside when's is mainly useful if you have a long list of logical names: bringing some hierarchy into the matching process might give better performance. It is not invalid for a when node to contain no child, but it won't do anything meaningful either, the matching process will continue with the next when node. ### 7.6.4 Mapping exceptions to representations For mapping exceptions to an appropriate representation, a selection process based on the exception class name is available. Here is some example syntax: exceptions { exception(classes: ["my.company.WrapperException"], unroll: true) exception(classes: ["my.company.FooException", "my.company.BarException"]) { template(src: "module:/templates/error_not_found.xml", statusCode: 404) } exception { template(src: "module:/templates/error.xml", statusCode: 500); } } The matching works as follows: 1. The system runs over the exception nodes. If its classes parameter lists a class which is the same as the exception class, or a superclass thereof (= instanceof check), then the exception node matches. An exception node with no (or an empty) classes parameter will always match, except when searching for causes (see step 2). 2. If the exception node matches and has an "unroll: true" parameter, the system will get the cause of the exception (= the first nested exception), if it exists, and go back to step (1). If there is no cause, or the handling for the cause didn't return anything, processing will continue here. 3. If the exception node matches and has a child element specifying the representation to create, then that will be the representation used. 4. If the exception node matches and has no child element, then the system moves on to the next exception node. ### 7.6.5 Mapping error status codes to representations This mapping is very straightforward: it maps a status code or a list of status codes to a representation. errors(overwrite: false) { error(status: 404) { template(src: "module:/templates/error_not_found.xml") } error(status: 500..599) { template(src: "module:/templates/server_error.xml") } error { template(src: "module:/templates/error.xml") } } The matching rules are as follows: • the rules are evaluated in order, the first one which matches is used • the status can be a single integer or a list of integers. Note that: • an error-rule without a status parameter will always match. Hence it only makes sense to have one such rule, and to have it at the end. The errors node can have an optional attribute 'overwrite', indicating that error responses should always be overwritten with the representations configured here. By default this is false, thus if there is already a response representation present, it will be left untouched. The representations used inside error { } should not carry a statusCode parameter, so it is disallowed to override the status code. ### 7.6.6 Multiple formats for exceptions and errors Sometimes you might want exception and error responses to be formatted differently depending on who makes the request: if it is an Ajax call, an error response formatted as JSON will likely be preferred over a human-oriented HTML error page. When a module contains only resources intended for use in Ajax calls or only resources intended for human display, you can always format exceptions and errors in the same way. But when the resources might be accessed in different ways, it is more useful to let the client specify how it wants errors to be formatted. This format is not necessarily related to the format requested: an Ajax call might retrieve a blurb of HTML but still want an error formatted as JSON. This client-specified error and exception formatting is possible by having multiple exceptions and errors sections in the configuration, carrying a media attribute. /* This exception section will be used when the client does not specify a preferred format */ exceptions { } exceptions(media: "json") { } errors { } errors(media: "json") { } The client can specify the requested format (media) in two ways: • a request parameter called kauri-error-media • a request header called X-Kauri-Error-Media The representation builder will then use the matching exceptions/errors section. ### 7.6.7 Representations To create an actual representation, a few built-in solutions are available, and a way to refer to your own classes to create the representation. #### 7.6.7.1 template This creates a template representation, the most common way of producing an HTML or XML response. This uses Kauri's template engine. Syntax: template(src: "uri") The src parameter specifies the template file location, typically this will be a URI using the module protocol such as module:/templates/foo.xml #### 7.6.7.2 resource This creates a representation which returns a static resource. Syntax: resource(src: "uri") #### 7.6.7.3 custom This allows to use your own code to create the representation. Syntax: custom(ofClass: "fully qualified class name") custom(ofBean: "spring bean name") You can either specify a class or refer to a bean in the Spring container by name. Either way, the resulting object should implement the interface org.kauriproject.representation.RepresentationFactory. See its javadoc for more information. #### 7.6.7.4 json Formats an exception or error as json. This should only be used in the exceptions or errors sections. Syntax: jsonStatus(statusCode: 500) The output produced is of the following kind: { status: "(HTTP status code)", description: "", throwable: { message: "(exception message)", type: "(exception fully qualified class name)", stackTrace: [ {class: "...", method: "...", native: true|false, file: "...", line: number} ], cause: { (nested throwable description) } } } The description and throwable will only be present when available. #### 7.6.7.5 Reusing matched values In the src attributes of the template and resource representations, you can refer to match values from the when nodes, using URI template syntax. Example:  select { when(name: "{name,all}") { template(src: "module:/templates/{name}.xml") } } If you have nested select's, you can use "../" syntax to walk up in the select node stack. #### 7.6.7.6 Common syntax On each representation-creating node, you can use the following optional parameters. Name Description statusCode an integer, specifying the HTTP status code for the response. For normal representations this is by default 200, for exceptions this is by default 500. mediaType the media type for the response. (todo: behavior and defaults depend on representation implementation) # 8 Templates ## 8.1 Introduction Kauri has its own template engine. It has the usual things you can expect from a template engine, both towards the user as towards the developer (e.g. template pre-compilation). Unique about Kauri's template engine is that it is XML-based, which has the advantage of providing guaranteed XML/HTML well-formed output, avoidance of HTML-injection, performant XML-pipeline processing of the template output, and abstraction of some HTML serialization rules (e.g. close tag required for <script>). The default expression language is EL, as implemented by JUEL. For those cases where you need to do something more powerful, you can use Groovy. The Kauri template engine is a stand-alone library, which can be easily used in other projects without pulling in all of Kauri. ## 8.2 Template features The Kauri template engine is still under construction, so not all expected features are already implemented. You can get an overview of the features here, including their current state and an indication of the importance we have given it. Using our mailinglist or issue tracker, you are invited to do feature requests in case we have missed something, or convince us that we should give higher priority to a certain feature. Contributions are also welcome. ## 8.3 Usage ### 8.3.1 Using templating in Kauri The integration of the template engine within Kauri is offered by the kauri-template-service-[api|impl] modules. ###### Normal usage For normal usage scenario's, you will not use the template-service immediately, but rather make use of the representation builder. If you generated a project using an archetype, this will already be configured for you, and you can simply use it as shown in this hello world sample. ###### Calling template-service immediately If you are in a situation where you can't or don't want to make use of the representation builder, you can call the template-service immediately. Add the template-service in the kauri.xml. If you are already using the template service via the representation builder, this will already be present: <artifact id="templateModule" groupId="org.kauriproject" artifactId="kauri-template-service-impl"/> Add a dependency to kauri-template-service-api to your module's pom.xml:  <dependency> <groupId>org.kauriproject</groupId> <artifactId>kauri-template-service-api</artifactId> <version>${version.kauri}</version>
</dependency>

Import the template service in your module's Spring config:

<kauri:import-service id="templateService" service="org.kauriproject.template.service.TemplateService"/>

Now you can pass this bean to your own classes to use the TemplateService.

### 8.3.2 Using templating from CLI

You can use it in CLI mode: java DefaultTemplateService <templateLocation> [var=value [var2=value2 [...]]]

For example:

<t:if test="${some expr}"> </body> </t:if> </html> The errors in the above snippet are that you can't create dynamic variable names this way, and that the body and t:if elements are not properly nested. #### 8.4.1.2 Namespace for template instructions A simple template might contain just some${...} expressions, but as soon as you want to use any instructions, you will need to declare the Kauri template namespace, which is:

http://kauriproject.org/template

Here's an example of how to bind the namespace to the "t" prefix and use instructions:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:t="http://kauriproject.org/template">
<t:forEach begin="1" end="5" step="2">
<p>do something</p>
</t:forEach>
</root>

### 8.4.2 Expression language

Expressions can be used to insert dynamic content into the generated output or to provide arguments to template instructions (e.g. the "test" attribute of an <if> instruction).

Kauri template supports two expression languages:

• EL (= same as in JSP)
• Groovy (which is actually a full programming language)

Normally, you should have enough with EL and never touch Groovy.

Groovy offers a powerful escape for those who know what they're doing.

#### 8.4.2.1 EL

The default expression language is the Unified Expression Language (EL), which is the same as used by JSP.

You can type your EL expressions using the ${...} or #{...} delimiter. Note: when just using the expression language (thus no template directives), there is no need to declare the template namespace. The${} and #{} delimiters will be picked up automatically when passed to the template engine. If you want to use the $or # character as regular text, you have to escape it with a backslash: \$ and \# .

##### 8.4.2.1.1 Expressions

Some of the supported expressions are:

• boolean
• true
• false
• logical operators
• and
• or, ||
• not, !
• relational operators
• ==, eq
• !=, ne
• <, lt
• >, gt
• <=, le
• >=, ge
• arithmetic operators
• binary: X <operator> Y
• +
• -
• *
• /, div
• %, mod
• unary: <operator> X
• -
• conditional operator
• <exp> ? <val1> : <val2>
• property resolution
• . , [ ]
• expr.identifier is equivalent to expr["identifier"]

e.g. $g{"groovy "*3} prints 'groovy groovy groovy'. ### 8.4.3 Template inheritance #### 8.4.3.1 Introduction The goal of this feature is to be able to split of the common layout of multiple pages to one shared base template, to avoid repetition. Disclaimer: this feature borrowed quite some ideas from Django's template language. #### 8.4.3.2 Basic terminology • base template: the template that defines the skeleton page structure (the general page layout) with regions to be filled by the child templates • child template: a template which inherits from a base template • the child template extends the base template • multiple levels of inheritance are possible, so a template can at the same time be a child template and a base template #### 8.4.3.3 Syntax ##### 8.4.3.3.1 The basics ###### 8.4.3.3.1.1 The base template The base template is a template that contains t:block elements to define regions that can be overridden by child templates. .... <t:block name="content"> [ default content for when block is not overridden] </t:block> ... ###### 8.4.3.3.1.2 The child template A child template is a template with on the root element a t:inherit attribute. The value of the t:inherit attribute is the URI of the base template. This attribute is evaluated at runtime, so it can contain expressions to dynamically determine the base template. The child template can contain t:block elements to replace the t:block elements with the same name from the base template. All content outside of the blocks will not be used. It is not an error to have blocks which do not exist in the base template, these will be ignored. It is not required for a child template to define all the blocks from the base template. If a block is not overridden, the block-content from the base template will be outputted. The t:block start tag and end tag themselve are never outputted, only the content of the block is outputted. The child template can have html, body, and other tags which facilitate viewing or editing the child template as an individual page. Each block has its own scope: variables defined within the block will not be visible to other blocks. <html t:extends="base.html"> <t:block name="content"> .... </t:block> <t:block name="navigation"> <t:superBlock/> </t:block> </html> ##### 8.4.3.3.2 Calling the block from the base template: t:superBlock When overriding a block, it might be that you want to keep the content from the block in the base template, and only add to it. This is possible using the t:superBlock element. Example: Suppose this base template: <html> <t:block name="foo"> base template content </t:block> </html> And this child template: <html> <t:block name="foo"> Hello world. This is the content from the base template: <p><t:superBlock/></p> </t:block> </html> Will produce this output: <html> Hello world. This is the content from the base template: <p>base template content</p> </html> As this example illustrates, the <t:superBlock/> element can be located at any position and depth within the overriding block. ##### 8.4.3.3.3 Cross-block initialization: t:init Suppose you have a child template with a few blocks: <html> <t:block name="block1"> ... </t:block> <t:block name="block2"> ... </t:block> <t:block name="block3"> ... </t:block> </html> Remember that only the content of the t:block elements from the child template is executed. Often, you will run in the situation that you want to define some variables and macro's to use in multiple of these blocks. This is possible by defining them in a t:init element. <html> <t:init> <t:variable name="foo" value="bar"/> </t:init> <t:block name="block1"> ... </t:block> <t:block name="block2"> ... </t:block> <t:block name="block3"> ... </t:block> </html> When executing a template that uses inheritance, the template engine will first execute the t:init blocks from each of the templates, starting with those from the top-level base template. This allows child templates to redefine variables and macro's defined by the base templates. The t:init element can contain any template instructions, but will be executed in silent mode, which means it will produce no output. Typically it will contain variables and macro's, but it can for example be useful to conditionally define a variable using t:if . If one template file contains multiple t:init elements, they will simply all be exeucted. TODO: • What happens with init blocks from included and imported templates? Probably executed when executed the included template. • What happens when an included or imported template itself inherits from base templates? Probably this simply works as expected. ### 8.4.4 URI resolving At various locations in the template language, you can specifies URI's, such as for include and import, inherit, variable and insert. These URI's can either be absolute or relative. Relative URI's will be resolved against the URI of the template that contains them. So if you define, for example, a macro in one template and call it from another template, any relative URI's within that macro will be resolved against the URI of the template containing the macro, not the one making the macro call. In general URI's are resolved at runtime rather than at compile-time, so you can specify URI's using expressions, allthough this depends on the specific template instruction. This section contains an explication of how the resolving of the URI's works. Most template users will not have to worry about this, since it should work as you expect. At a technical level, the template library defines an interface SourceResolver, the concrete implementation provided will determine how the URI resolving works. When using the template library within Kauri through the kauri-template-service module, a Kauri-specific SourceResolver is used, which supports Kauri's special service protocol and module protocol. The resolving of the service and module protocols depends on the module within which they are used: the module protocol fetches resources from the current module, and the service protocol addresses REST-services from the current module's service registry. So for example, two different modules might both contain a resource at templates/layout.xml, which can be fetched using the URI module:/templates/layout.xml. Depending on the module within which this URI is used, data from a different layout.xml file will be returned. When you execute a template within a certain module, it is most logical that all URIs contained within it are also resolved within the context of that module. However, imagine the following scenario: • a template in a module A includes a template from module B, via the service protocol • the template from module B includes, using a "module:" URI, another template from module B This would not work if we evaluate this second include within the context of module A (where the template is being executed). Therefore, we have made it such that, when including templates via the service protocol, and the service protocol addresses a service from another module, the source resolving of URIs in that included template will be done within the context of that other module. This of course works any number of includes deep. However, it only works if the template engine can be aware of the "module switch". Thus if you write a restservice which in itself retrieves data from a restservice in another module, then the template engine won't be aware of the switch. But that is a rare case, which can be worked around by using a template with an include instead. ### 8.4.5 Whitespace handling Kauri Template sometimes removes whitespace-only text occurring in template files, so that the template output would not contain an abundance of irrelevant whitespace. But if you want to keep the whitespace, it is possible to do so. The rule for whitespace removal is as follows: if the text between two tags consists of only whitespace characters, then this text is removed while parsing the template. Whitespace characters are space, tab, line feed (a.k.a. new line or end of line) and carriage return. Other forms of whitespace, such as non-breaking spaces, are not considered as whitespace. From the moment the text between two tags contains a non-whitespace character, the text will be left alone. It will not be trimmed. The whitespace stripping happens during parsing of the template, not on the output produced by the template. As a consequence, whitespace occurring in text that is inserted via expressions or other constructs is never touched. There are two mechanisms available to tell the template language that whitespace should be preserved: the xml:space attribute and the t:text instruction. ##### xml:space The xml:space attribute is defined by the XML Recommendation. If you add an attribute xml:space=”preserved” on a start-tag, all whitespace between that start-tag and its matching end-tag will be preserved. It is possible to revert this effect at a lower level by adding the attribute xml:space=”default”. The xml:space attributes will not occur in the template output. In case you do want to produce an xml:space attribute in the output, you can do so by creating the attribute via t:attribute. ###### Examples <p xml:space=”preserve”> All whitespace <span> </span> will be preserved. But here it will be stripped: <span xml:space=”default”> </span>. </p> In case you're wondering, the “xml:” namespace prefix is a special one that does not need declaration. ##### t:text The t:text instruction will preserve all whitespace occurring within it, but the t:text instruction will not occur in the output. It is hence an alternative for xml:space=”preserve” for those cases where you don't have an element to add the xml:space attribute on, while also being shorter to write. ###### Examples In the example below, the words very and important would stick together in the template output, as the whitespace-only text between the </strong> and <em> tag is removed: <p> <strong>very</strong> <em>important</em> </p> This can be avoided as follows: <p> <strong>very</strong><t:text> </t:text><em>important</em> </p> In the example below, in case the if-test evaluates to true, the output of the template would contain a newline character, two spaces, the text “More than three” and another newline. This is because the whitespace is not trimmed. <t:if test=”x > 3”> More than tree </t:if> If you want to avoid this, you can wrap the text into a t:text tag: <t:if test=”x > 3”> <t:text>More than tree</t:text> </t:if> The t:text tag is here not used to preserve the whitespace within it, but rather to introduce whitespace-only nodes before and after it, which will be stripped. ### 8.4.6 @inherit The t:inherit attribute, to be used on the root element of a template, is part of the template inheritance feature. ### 8.4.7 attribute The attribute instruction can be used to add attributes to an element in a dynamic way. ###### Specifying the attribute name at runtime Using t:attribute, the attribute name can be specified using expressions: <div> <t:attribute name="my-${something}" value="music"/>
</div>

The name can include a namespace prefix. As usual for attributes, the default namespace (= no prefix specified) does not apply.

###### Adding attributes conditionally

You can surround the attribute with conditional logic (such as an if) to conditionally add the attribute:

<div>
<t:if test="${1 < 3}"> <t:attribute name="class" value="music"/> </t:if> </div> Attribute instructions should be the first children of an element, thus immediately follow a start-tag. They can not be used anymore once child content for the element is generated. So the following is not possible, as there is no start-tag to add the attribute to: <div> Hello world. <t:attribute name="my-${something}" value="music"/>
</div>

If you don't need the above mentioned dynamism when adding an attribute, you can as well add the attribute directly on the element. So you can then simply do:

<div class="music">
</div>

### 8.4.8 block

The t:block instruction is part of the template inheritance feature.

### 8.4.9 choose (when... otherwise...)

<t:choose>
<t:when test="${false}"> <p>first case - false</p> </t:when> <t:when test="${true}">
<p>second case - true</p>
</t:when>
<t:otherwise>
<p>other</p>
</t:otherwise>
</t:choose>

TODO: describe behavior (only first matching when executed etc.), is otherwise optional, is content between the when's allowed and what happens with it

### 8.4.10 comment

Produces a comment in the output.

Any comments in template, using the <!-- comment --> syntax, will not be part of the template output. To produce a comment in the template output, you need to use t:comment.

t:comment can in itself contain any template instructions, the contents will be serialized as XML and used as comment text.

Example:

<t:comment>This is a comment</t:comment>

### 8.4.11 element

Allows to create elements in the output using dynamically determined name.

<p>do something with ${item}</p> </t:forEach> #### 8.4.12.2 Supported list types You can loop over: • Java arrays • any kind of Java Collection • org.w3c.dom.NodeList and org.w3c.dom.Node (will iterate over the child nodes) • any other kind of object will behave as a single-entry list #### 8.4.12.3 Loop status Inside the forEach, you have access to a variable called loopStatus providing the following fields: • position: the current value between begin and end, augmented with the step upon each loop • index: sequence number augmented upon each loop, starting from 0 • number: same as index, but starting from 1 • revIndex, revNumber [todo see issue #111] ### 8.4.13 if Conditionally evaluate some part of the template. <t:if test="${true}">
<p>always say hello</p>
</t:if>

### 8.4.14 include, import

include and import allow to include other template files into the current one, hence supporting modularisation and re-use.

An include/import will cause the included template to be executed at the moment the include/import instruction is encountered. Any output produced by the included/imported template will be inserted at that location.

The difference between include and import is that and import will never override macro definitions from the template it is included in. An include on the other hand behaves as if the content of the included template would be inserted at the location of the include instructions: any macro will override previously defined macro's with the same name.

###### Syntax
<t:include src="..." mode="..."/>
<t:import src="..." mode="..."/>

Attributes:

• src: URI of the template to include
• this attribute is evaluated at runtime, hence can contain expressions.
• relative URIs will be resolved against the URI from which the current template was loaded.
• recursive inclusions are detected and disallowed.
• mode: (optional) either "silent" or "regular" (default). When mode is silent, the template will be executed, but no output will be produced. This is useful for templates that only contain macro's or variables. It will avoid that the root element and the whitespace between the macro's will be outputted.
###### Usage

Includes and imports can occur at any location in a template file. They are not only useful for including macro libraries, but also for reusable snippets.

The same template can be included multiple times.

###### Supress root element trick

If you have a "snippet" template to be included in other templates, but you don't want the template to produce a root element, you can use a t:if element as root for your template:

<?xml version="1.0"?>
<t:if test="${true}" xmlns:t="http://kauriproject.org/template"> Hello world! </t:if> ###### See also For reusable layouts, be sure to check out the template inheritance feature. ### 8.4.15 init The t:init element is part of the template inheritance feature. ### 8.4.16 insert ##### <t:insert> The t:insert instruction is used to insert some file or variable into the output of the template. The inserted file/variable is treated as static content: template instructions or expressions contained in it are not evaluated. The file/variable will by default be parsed as XML, this can be changed to text or html inclusion using the mode attribute. ##### @src|@variable : The content to insert To insert contents from a file or network-stream use the @src attribute and let it point to some absolute or relative URL (protocols supported are 'http', 'file', 'module', and 'service', see URI resolving for more details) <foo> <t:insert src="bar.xml"/> </foo> To insert a variable use the @value attribute and let it contain a string value or some expression that evaluates to a string value. <foo> <t:insert value="${item.html}"/>
</foo>

Using the @src takes precedence over the @value.

##### @mode: The type of content to insert

The @mode attribute allows to specify in which way the content will be regarded during the import. The possible values for the mode are:

• txt
In this mode content will be included as is.  If it contains any markup it will not be seen, but regarded as simple character-data in the output of our XML template.
In other words in the final output of the template it will show up escaped in &lt; and &gt; entities.
• xml
With this mode, the content is regarded as XML. This means the source (or string-value) will be parsed and included as actual XML.  The parsing step here will force proper XML  well-formedness rules on the content being inserted.
• html
When the inserted content is regarded as HTML the output behavior is similar to the XML mode: actual tags will be entered into the stream (and not escaped).  In this mode input is expected to be HTML which does not need to comply to strict XML well-formedness rules. It uses internally the neko-html parser to produce valid XML out of the html input.

The mode to apply is determined according to the following fall-back strategy:

1. The mode specified with the @mode attribute takes precedence. If not specified:
2. The Mime-Type found on the retrieved input source (This only when the @src is used.) is mapped onto xml, html or text
3. If still no match is found (e.g. @value is used, and no @mode is specified) then mode="txt" is assumed.
<foo>
<t:insert src="http://somewhe.re/over-the/rainbow" mode="html" />
</foo>

In html mode the inserted content is automatically limited to the contents of the <body> element of the page.  The output can thus easily be producing mixed-content-model XML. Your template should provide a proper root element to coop with that.

##### @encoding: The character-set to apply

A similar approach is taken towards the used encoding to read the content to be inserted. Here the fallback-strategy is as follows:

1. The encoding specified with the @encoding attributes is used. If not specified:
2. The encoding found on the retrieved input source is used.
3. If none is specified the default encoding (java system property file.encoding) of the VM running the template will be used.

None of this applies to @value content because that is already present as character-content to the templating engine. In this case the characters to insert do not need to be decoded from some (external) byte-stream.

<foo>
<t:insert src="module:/myfile-in-Cp1252.txt" encoding="Cp1252" />
</foo>

### 8.4.17 macro (callMacro, parameter)

<t:macro name="...">
<t:parameter name="..." value="..."/>
</t:macro>

<t:callMacro name="...">
<t:parameter name="..." value="..."/>
</t:callMacro>

Macro's can be defined at any location in the template. They are immediately available everywhere: the location where they are defined in the template does not matter.

Macro's can be called recursively.

The purpose of t:parameter is as follows:

• within t:macro: to define the possible parameters, and optionally give a default value for them
• within t:callMacro: to specify a value for a parameter
###### Implementation problems

There are still some rough edges on the current implementation.

• the value attribute on t:parameter is always optional, but should only be optional when embedded within t:macro
• there are no checks that you can only set parameters (within t:callMacro) that are defined within t:macro
• t:parameter is current exactly equivalent to:
• within t:macro: same as t:variable/@overwrite=false
• within t:callMacro: same as t:variable
• parameters share the same storage space with variables. Even when not giving a parameter explicitly within t:callMacro, it might be that somewhere higher up a variable is defined with the same name as the parameter, the value of this variable will then be used. And thus not the default value of the parameter.
• first content of callMacro element is executed, then that of the called macro. You can actually put anything within t:callMacro. (might be useful to conditionally set parameters?)
###### Recursive macro example

Suppose we have a tree of nodes, where each node has a property name, and a property parent pointing to its parent node. When a node has no parent, the parent property is null.

The follow template fragment shows how to display the name of a node (theNode) and its ancestor nodes.

<t:callMacro name="displayNode">
<t:parameter name="node" value="${theNode}"/> </t:callMacro> <t:macro name="displayNode"> <t:parameter name="node"/> <p>${node.name}</p>

<t:if test="${node.parent != null}"> <t:callMacro name="displayNode"> <t:parameter name="node" value="${node.parent}"/>
</t:callMacro>
</t:if>

</t:macro>

### 8.4.18 protect

Conditionally evaluates the contained content, depending on the access control decision.

<t:protect access="...">
[content here]
</t:protect>

The access attribute contains a comma separated list of values. These could for example be role names.

To use the t:protect instruction, you need to provide an AccessDecider to the template engine, which will take the access decision based on the values in the access attribute. There is no built-in behavior.

For the template engine as integrated in Kauri, see here.

### 8.4.19 superBlock

The t:superBlock instruction is part of the template inheritance feature.

### 8.4.20 variable

##### Introduction

The variable instruction associates a value with a name.

The value can be specified using the value attribute or, if not present, in the content of the variable element. It can be a literal string or contain expressions.

The value can be of any type (i.e., not just strings), depending on the expression.

<t:variable name="foo" value="${bar}"/> <t:variable name="sometext">bla</t:variable> <t:variable name="data" mode="json">{"parsed": "value"}</t:variable> <p>foo =${foo}</p>
<p>and here is some text: ${sometext}</p> <p>and some parsed data:${data.parsed}</p>
##### Loading variable data from a URI

The data of a variable can also be loaded from a URI instead of specifying it in the value attribute, or nesting it in the <t:variable> tags.  You do so by specifying the URI in the @src attribute.

The mime-type of the loaded data will determine the way the content is handled (i.e. parsed/interpreted). This behavior van be forced or overridden by using explicit @mode attribute mentioned below

##### Handling the data

The way the retrieved data is handled is covered by the @mode attribute. It can contain the following values:

@mode

by default for mime

handling

json

application/json

the data will be parsed as JSON (object or array) and hence you can use expressions to walk over the JSON data. The JSON library we use will map the data onto Java Objects.

xml

*text/xml*, *application/xml*, or  **+xml

the data is parsed into a (namespace-aware) DOM-tree

html

text/html

the data is parsed into a (namespace-aware) DOM-tree, but will apply smart tag balancing in the process.

txt

any other text/*

the data is not parsed at all, but just read in as text (using the source-declared encoding)

The middle column declares which @mode will be assumed if it is not specified, based on the retrieved @src

Syntax example:

<t:variable name="foo" src="http://somewhere/data.json"/>
${foo.someproperty} When the resource would support content-negotation, you can specify your preferences in an accept attribute: <t:variable name="foo" src="http://somwhere/data" accept="application/json"/> The accept attribute takes a comma-separated list of media types. Specifying a quality factor, as in the HTTP Accept header, is currently not supported. ###### Fallback for loaded data. Both of the attributes @value and @src can be used together, in which case the remote loading (@src) will be favored. The expression in the @value attribute will only be evaluated when the remote loading failed. Note: in absence of the @value expression, a failure to load the data from @src will throw an exception that prevents further template execution. ###### Only set a variable if it is not yet defined It is possible to say that a variable should only be assigned if it does not have a value yet. The previous value might be assigned by an earlier variable instruction, but more interestingly, might be provided as parameter by the executor of the template. This makes it possible to define defaults for variables within a template, while allowing to provide custom values from outside the template. Syntax: <t:variable name="..." value|src="..." overwrite="false"/> When the overwrite attribute is not specified, it defaults to true. # 9 Database resources ## 9.1 Introduction Kauri's database resources (often called DB resources) provide an easy way to expose database entities as RESTful resources. Two implementations are provided: • One that works on top of JPA (Java Persistence API, implemented by Hibernate and others) • One that allows to mock database resources by creating JSON files on the filesystem. This is useful at early stages in the project, when the real database resources are not yet available. It can also be useful at later stages in the project, to experiment with new entities or to work on the front-end without access to the database. ## 9.2 Interface Here we describe the interface which is common to all database resource implementations. ### 9.2.1 URI structure The URI structure can be summarized as follows (* = 0 or more occurences, ? = 0 or 1 occurence): /entityname(/id/propertyname)*(/id)? The following table shows some examples of what is possible:  /myentity list of all myentity records /myentity/1 the entity myentity with id = 1 /myentity/1/myproperty assuming myproperty is a property of myentity, and that myproperty is an entity by itself, this will return the entity associated through myproperty. If myproperty is a list, it will return the list of all such entities. /myentity>/1/myproperty/2 Same as the previous, but assumes myproperty is a list, and will only return the entity with id = 2. ### 9.2.2 Methods The HTTP methods have their usual meaning. GET, PUT, POST, DELETE, HEAD and OPTIONS are all supported Creating a new entity is done by posting to a list-URI. So the ID of the new entity is assigned by the server. ### 9.2.3 Querying Querying (searching) for entities is done using the query string on list-URIs. The name of the property to search on should be preceded by "q.". Searching on a single property: /myentity?q.propertyname=value Searching on multiple properties: /myentity?q.propertyname1=value1&q.propertyname2=value2 ### 9.2.4 Sorting When lists of entities are returned, you can specify sorting options to influence the order. The parameters are: sort.{seqnr}=propertyname order.{seqnr}=asc|desc where seqnr is 1, 2, ... Specifying the order is optional, default is ascending. Example: ?sort.1=prop1&order.1=desc&sort.2=prop2 ### 9.2.5 Paging When lists of entities are returned, you can use paging options to avoid that the complete list is returned. The paging options are specified using the following request parameters:  page The page number, the first page is numbered 1. If the page number is larger than the number of available pages, an empty result will be returned. pageSize (optional) The size of a page, default is 10. When the page request parameter is present, the plain list result will be wrapped in a container describing the page. For example, for the JSON format, this container is as follows: { page: 1, pageSize: 10, totalPages: 5, totalRows: 46, data: [ { ... }, { ... }, ...] } ## 9.3 JPA database resources ### 9.3.1 Setup Using the JPA database resources is straightforward, simply follow the steps below. If you have generated a project using an archetype, then depending on the selected archetype these steps might already have been done for you. #### 9.3.1.1 Create some JPA entities In your Kauri module, add some POJO's you want to persist. Annotate them with JPA annotations, only @Entity is required. #### 9.3.1.2 Create a persistence.xml Add a META-INF/ persistence.xml file and configure your persistence unit (connection-url, username, pasword) The default persistence-unit name is "kauri-dbresources". If you use another one, you need to define it using a Spring bean named "persistenceUnitName", see below. #### 9.3.1.3 Update the pom.xml In the pom.xml of your module, add a dependency on the kauri-dbresources-impl artifact:  <dependency> <groupId>org.kauriproject</groupId> <artifactId>kauri-dbresources-impl</artifactId> <version>${version.kauri}</version>
</dependency>

#### 9.3.1.4 Spring bean configuration

In your spring bean configuration (src/main/kauri/spring/...), add the following import:

<import resource="classpath:org/kauriproject/dbresources/jpa/services.xml"/>

If needed override the default persistenceUnitName by adding:

<bean id="persistenceUnitName" class="java.lang.String">
<constructor-arg value="{your-persistency-unit-name-here}"/>
</bean>

#### 9.3.1.5 wiring.xml

The import we did in the Spring configuration will automatically export a REST-service called jpaRestlet.

In the wiring.xml, you can mount this REST-service on a path of your choice.

Inside the XML-element defining your module, add:
<mount name="jpaRestlet" path="/data"/>

#### 9.3.1.6 Try it out

After doing an "mvn install" and (re)starting Kauri, browse to:

http://localhost:8888/data/myentity

where myentity corresponds to the name of an entity as annotated on your Java classes, such as @Entity(name = "myentity")

### 9.3.2 JPA database resource interface specifics

The JpaRestlet provides the JPA database resources. It implements the common database resource interface.

All resources have three representations:

• application/json: a json representation
• text/xml or application/xml: an XML representation
• text/plain: a textual representation of your entity

Content negotiation (the HTTP Accept header) can be used to indicate your preferred representation.

In case you can't set the Accept header, you can work around this by specifying it in the URI, for example ?media=json

Entities that are serializable, can also be retrieved as serialized Java objects.

For POST/PUT operations, the payload can be JSON, XML or serialized Java objects.

### 9.3.3 Limitations

Currently database resources are in initial stable phase. We are aware of certain restrictions and imperfections, but before we tackle those issues we'd like to have a better view on where this module is going and what features users want to see in it.

The database resources are vulnerable to SQL injection.

The database resources only work with Hibernate as JPA provider.

### 9.3.4 persistence.xml examples

Here you can find some persistence.xml examples that can help you get started with Kauri database resources in your project.

#### 9.3.4.1 In-memory database (used in samples)

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="kauri-dbresources" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:kauri-sample" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
</properties>
</persistence-unit>
</persistence>

#### 9.3.4.2 MySQL database

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
<persistence-unit name="kauri-dbresources" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="false" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.username" value="sqluser" />
<property name="hibernate.connection.password" value="sqlpwd" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/kauritest" />
</properties>
</persistence-unit>
</persistence>

## 9.4 Mock database resources

### 9.4.1 Introduction

The mock database resources (often called DB Mock) allow to provide database resources without having a database and code in place.

They are useful at early stages in the project, when the real database resources are not yet available. It can also be useful at later stages in the project, to experiment with new entities or to work on the front-end without access to the database. Since they provide the same RESTful interface as the real DB resources, smooth transition between the two is possible.

Creating mock data resources is simply a matter of creating a directory structure containing JSON files. DB Mock will automatically provide the CRUD (create-read-update-delete) and query operations, so that your prototype will raise above the level of static data. Linking between entities is also supported, using {$ref: "..."} objects. There is no description of the type of the entities [required/necessary/possible]. While the mock database resources behave to a some extent as real database resources, it is by no means a perfect substitute for them. The goal of DB Mock is that an application can function (in the sense of being able to click through everything) in absence of real database resources, not that all displayed data would be correct at all times. ### 9.4.2 Setup Follow the steps below to use DB Mock. #### 9.4.2.1 Update the pom.xml In the pom.xml of your module, add the following dependency: <dependency> <groupId>org.kauriproject</groupId> <artifactId>kauri-dbresources-impl</artifactId> <version>${version.kauri}</version>
</dependency>  

#### 9.4.2.2 Spring bean configuration

Add the following to your module's Spring configuration (src/main/kauri/spring/...):

  <kauri:export-restservice ref="data"/>

<bean id="data" class="org.kauriproject.dbresources.mock.DbMockFinder">
<constructor-arg ref="restletContext"/>
<constructor-arg ref="module"/>
<constructor-arg ref="mockdata"/>
</bean>

The first two constructor-arg's refer to the beans made available by the kauri:module tag.

The third constructor-arg is the path within the module resources where the mock entities are stored. By convention we usually store these in mockdata, which means in your project source tree you have to add these below src/main/kauri/mockdata.

#### 9.4.2.3 wiring.xml

In the wiring.xml, you can mount the "data" REST-service (that we exported using kauri:export-restservice) on a path of your choice.

Inside the XML-element defining your module, add:
<mount name="data" path="/data"/>

#### 9.4.2.4 Try it out

Just to try things out, you might want to create some test mock data.

For example, create the directory src/main/kauri/mockdata/persons, and add a file 1.json to it, containing:

{
name: "John",
city: "New York"
}

Build by executing "mvn install", (re)start Kauri, and browse to:

List of persons:
http://localhost:8888/data/persons

Person by id:
http://localhost:8888/data/persons/1

Persons called John:
http://localhost:8888/data/persons?q.name=John

### 9.4.3 Defining entities

#### 9.4.3.1 General structure

The JSON entities are defined by creating one subdirectory per kind of entity in the src/main/kauri/mockdata directory.

The listing below shows the directory structure of a module containing three types of entities: contacts, tasks and projects.

Within these directories, you create one JSON file per entity instance. The name of the file (without .json extension) is the ID of the entity.

.
|-- contact-module
|   -- src
|       -- main
|           -- kauri
|               |-- mockdata
|                   -- contacts
|                       -- 1.json
|                       -- 2.json
|                       -- 3.json
|                       -- 1.json
|                       -- 12.json
|                       -- 13.json
|                   -- projects
|                       -- 1.json
|                       -- 2.json
|                       -- 3.json

#### 9.4.3.2 JSON entities

Here is an example of a project entity that contains a label, description, start, finish, type, status, importance and a set of subtasks:

{
label: "Defining prototype module requirements",
description: "Investigating which requirements we have towards prototyping a Kauri project",
start: "2008-09-01",
finish: "2008-09-30",
type: "research",
status: "busy",
importance: "+++",
{label: "Explore", description: "run the kauri samples, make it work!"},
{label: "Try a prototype", description: "hands on, try to make a prototype"}
]
}

#### 9.4.3.3 Linking between entities

In the example above, we could imagine that the subtasks are also entities itself, which we want to CRUD by themselves. Then we would like to create a reference to these entities instead of repeating them. This can be accomplished by linking entities using objects with a  $ref property. If the name of the name-value pair in a JSON object is '$ref' then the value is a reference to another entity.

##### 9.4.3.3.1 Example
{
"label": "Defining prototype module requirements",
"description": "Investigating which requirements we have towards prototyping a Kauri project",
"start": "2008-09-01",
"finish": "2008-09-30",
"type": "research",
"status": "busy",
"importance": "+++",
{$ref: "/tasks/3"}, {$ref: "/tasks/3"}
]
}

Of course in this case we have to have a file /entities/tasks/3.json:

{
"label": "Explore",
"description": "run the kauri samples, make it work!"
}

#### 9.4.4.3 Updating data (PUT, POST, DELETE)

DB Mock supports PUT, POST and DELETE operations, so it is possible to actually update the data. The updates are however only effective for the currently running Kauri, restarting Kauri will loose the updates. At the time of this writing, this is implemented by copying the resources to a temporary location and applying the updates on this copy.

When you GET an entity, any entities linked within it using {$ref: "..."} will be merged. However, when creating or updating an entity, these merged entities will not be split out again in separate files. This is because the system has no knowlege of which properties are linked entities. The PUT and DELETE operations are smart enough to apply updates within files, if the addressed entity would be a part of a JSON file instead of a file on its own. # 10 Forms ### Intro The Kauri Forms module implements a browser targeted (Javascript based) form framework. The framework provides a formal and systematic approach to end-user data-entry. It is not serving more generic end-user interaction and UI effects, but we bundle jQuery and jQuery UI as separate Kauri packages. So with the Kauri forms framework you build browser-based interaction screens that allow the end-user to read, modify and save (or create) some kind of data-structure. This data-structure is exchanged between the form-framework and the back-end in the known JSON format. ### Requirements By design this framework clearly assumes modern browser technology to be available: • It depends on jQuery, a base Javascript library. • In sync with the REST orientation/mindset of Kauri, this framework will appeal to client-applications to manage application state and to use Ajax requests to the available REST services. These assumptions boil down to: 1. we assume a fairly modern browser supporting Ajax requests 2. Javascript support is enabled in the browser We think this largely fits today's common practice. NOTE: At the time of writing this module does not do an effort to support some graceful degrading towards browsers/deployments that do not meet these requirements. Rest assured though, like all Kauri modules it is entirely optional to use it or not. ### RIA meets ROA The above proceeds on one of our believes: that ROA (resource oriented architecture) designs assume smarter clients that are able to control their own application state. The latter are commonly grouped under the term Rich Internet Applications (RIA). These RI-Architectures come in many implementation variants, some of which offered through specific (some paying) development environments. Most of those have a flexible way to deal with back-end (Ajax) requests and will thus invariantly be usable with the mid-tier-service modules delivered with Kauri. ### Further reading: Check up on the related samples in the Kauri distribution. ## 10.1 Concepts #### Goals and Features ##### Made for data-entry: managing a data-structure As explained in the introduction the Kauri Forms framework is about creating interaction screens to allow management of structured data. A typical example of such structured data in JSON notation would look like this: { "name": "John Doe", "sex": "Male", "birth": "19700605", "hobbies": ["family", "reading" , "math", "stars", "trains", "photography"], "address": { "street": "Longstreet", "number": "5758", "zip": "TX 3007", "city": "Hometown", "country": "Belgium" } } As the example shows these data-structures are by nature composed of different members that in their own right can be either • 'simple' (holding a straight value), • 'collection' (aka array), or • 'composite' (aka object, substructure). Assuming the REST services to manage these entities (store, retrieve, query, secure, ...) are available the forms-framework is there to help create browser based interaction screens and logic 1. to modify these structures, 2. validate the data-entry and finally 3. communicate with the available back-end services ##### Made for real life applications The difference between good and great applications appeals for the kind of end-user interaction that goes beyond assuring the dull correctness of data entry, and aspires to make a difference that matters in how the end-user can efficiently perform his daily work. In our experience the nowadays web-based front-end designers up for the challenge have a great deal of low level HTML, CSS and Javascript experience. In order to support them, the framework should allow them to leverage that experience and focus on making 'the difference'. In other words: the dull stuff should be handled correctly out of the box and extras and customisations should be easily possible. In practice we allow 1. Extending the framework with custom controls and features. 2. Extensively configuring the available components. 3. Standard HTML/CSS editing of the visual UI components. 4. Wiring up events between the various form controls internally, or between the form-controls and custom Javascript functions and non-Kauri UI libraries. How all that is done we explain in this section, after some general introduction. #### Essential Framework Concepts and terminology The framework introduces 3 distinct concepts with their own specific goals and responsibilities: 1. Fields 2. Controls 3. The Form ##### A Field A 'Field' in Kauri Forms groups the 'data-type' aspects of each individual low-level member in the data-structure. These aspects are: 1. value properties, e.g. • holding single or multi-values • a list of available values to choose from (called 'options') 2. formatting properties • These cover how string representations of the typed values are to be parsed/formatted • Both to the back-end and the end-user. 3. validation properties • Checking if entered data is possible, acceptable, consistent, ... 4. extra convenience properties • a default or assumed 'control' to enable editing • a general 'share' section. For handling some recurring data-types, the framework already offers a number of standard 'Field' implementations: • basic: • 'string', • 'integer', 'decimal', • 'boolean', • structural: • 'case', • 'composite', • 'collection', • specific: • 'integer-range', • 'date', 'time', 'datetime', 'date-range', • 'location' (a google maps entry) • 'file' (file to upload) Next to these, own fields can be added. The core task of these Fields is to keep track of the 'value' being offered for editing in the form. This involves triggering and managing validation, but also converting the value to-from the (string) representations of it that are either entered/seen by the end-user or communicated to the back-end. Note that both towards the backend (json/wire-format) and to the end-user (keyboard-entry and screen-feedback) all communication is essentially string based (or 'untyped' if you like). For this purpose the Field knows about two distinct 'formatter's that handle formatting (to string) and parsing (from string) of the actual value. These two are known respectively as the: 1. wire-formatter: to convert the local value to-from the value as passed over the wire (ie. JSON) 2. user-formatter: to convert the local value to-from the value as shown and edited by the end-user. Note that any occuring formatting and parsing errors will be presented to the end user in the same way as validation errors: both indicate invalid data in the form and require a similar action to get resolved. Just like the formatting logic, the actual validation logic is provided in separate (reusable) classes that implement a simple validation interface. Its responsibility is to evaluate a single value leading to either an ok or to a validation-message. ##### A Control A 'Control' then will, for each distinct member in the data-structure, offer the graphical screen elements to show its value and allow changing it. In more detail this involves: 1. Produce a specific UI Control (set of activated HTML elements) to allow the required end-user interaction. This includes input-elements, specific action triggers, labels, format or validation feedback, ... 2. Rely on a specific 'Field' to properly handle the data-type related aspects of the values being modified through the control. 3. Bind to user-input events to trigger formatting, validation and fire events. 4. As well as bind to events from other controls 5. And depending on the specific control: load reference data from specific configured URI's More or less matching the earlier mentioned typical Fields (datatypes) the Kauri-forms module offers these 'Control' implementations: • basic • 'input-control', • 'checkbox-control', • 'selection-control', • 'textarea-control', • structural • 'case-control', • 'composite-control', • 'collection-control' • specific • 'slider-control', • 'date-control','datetime-control', • 'gmap-control' • 'upload-control' Just like with the Fields, your own custom controls can be added. ##### The Form Finally the Form object in this framework is the corner-piece in the whole setting that organizes the various controls on the screen and handles the communication to the rest-services. For that it will: 1. Act as a top-level composite Control holding the first-level members. 2. Read the HTML template for matching elements and extract a basic "configuration" from it. 3. Apply an optional external form-configuration. 4. Create and set-up all nested controls. (including the top-level control provided by itself) 5. And maintain a registry of controls to allow lookup and referencing between them. (Useful in e.g. event-binding and handling) 6. Last but not least, it will communicate to the back-end upon form-submit. #### Form Configuration (aka fconf) To make the Form manage the data-structure of your choice (i.e. show the correct fields, and apply the desired formatting and validation) you need to give it the proper "configuration". This configuration holds a number of things: 1. a description of the various members of the data-structure and how the form should allow modifying them. 2. the service URIs needed for data-submission 3. specific form properties Matching the sample data-structure from the first paragraph, below you find a rough structure of an appropriate matching form configuration: var fconf = { /* described data structure */ "members": { "name": { /* some string input */ }, "sex" : { /* Male or Female choice */ }, "birth: { /* date input */ }, "hobbies": { /* flexible list of strings */ }, "address": { /* nested structure of street, number, zip, city and country */...} } /* communication properties */ "createURI": "${publicUri('service:/data/person/')}",

/* Additional custom types */
"controlTypes": {
"name-of-control": {  /*   definition */   }
}
}

Roughly speaking there are 3 main sections in this configuration:

1. The listing of form-members and their (inline) field-type descriptions.
2. Form-specific properties, mainly to configure the communication end-points for form-submit.
3. Possible additional custom types (for fields, controls, formatters and validators) to reference to.

See the reference 'form config' for a more detailed explanation of what should go in each section. Additionally check the reference on each of the controls you want to use to learn about how they can be configured and tuned. Below you just find some simple examles as a first introduction into the nested field-description:

...
"members":   {
"name": "string",   //a shorthand for { "base": "string" }

"birth": {
"base": "date",
"yearRange": '-100:+0',

"label": 'What is your date of birth?'
},

"base" : "composite",
"members": {
"street"   : "string",
"nr"       : "string",
"zip"      : "string",
"city"     : "string",
"country"  : "string"
}
}
}
...

Note how the composition/nesting of members in this structure enables to give each control in the hierarchy a unique absolute-id by concatenating them into 'paths'. We call the resulting full-identification the control "index". So in the above example the following ones will have been created.

  /name
/birth
...
...

These "indices" will turn up again when we talk about the HTML Template binding further down.

Finally, to complete the 'form' explanation we just need to explain how to turn this form-configuration into a live form. This involves:

1. the following lines of Javascript:
  var form=new $.org.kauriproject.forms.Form("my-form", fconf); 2. and an HTML <form> element that matches up with the id (mentioned as first argument):  <form id="my-form" /> #### HTML Form Creation As shown above the matching <form/> element can be kept empty. In that case the Javascript framework will create all the required HTML elements to enable the needed end-user interaction. (as hinted above this is under the responsibility of the different controls) TODO: describe current match/create algorithm that decides when to start creating elements --> some of this still under discussion (see mail-list, see issue?) + position and importance of "input" element #### HTML Template Binding Of course those elements will be created and positioned in some standard way as coded inside the specific controls (each of them might allow some configuration to tweak that a bit). Instead of sticking to that default the framework allows to "bind" the interaction behaviour of the distinct controls to specific (and arbitrary positioned) HTML elements in a custom provided page. To make the binding work however these HTML elements need some additional mark-up that declares them as: 1. Being tied to a specific control. By using the @kauri-idref attribute. 2. Being created to fulfill a specific function or role. Through the @kauri-role attribute. As an example: <label kauri-idref="name" kauri-role="label">Name:</label> <input kauri-idref="name" kauri-role="input" /> <span kauri-idref="name" kauri-role="messages" /> This allows the front-end designer to arbitrarily position the label, input-box and feedback messages (typically format and validation errors) associated to the control. For ease-of-typing the kauri-idref attribute is inherited down the nodes in the HTML structure. This means that the value can be placed on a common parent for various nested elements: <div kauri-idref="name"> <label kauri-role="label">Name:</label> <input kauri-role="input" /> <span kauri-role="messages" /> </div> Remember that controls can be nested (This is how composite controls manage composite values.) In this case the member-names are combined into an absolute id or "index" for the control. The @kauri-idref value should point to this index, but can choose to do so in a relative way. By default the kauri-idref value will be appended to the one of any parent element in the HTML structure. Only if the value kauri-idref starts with a '/', the value is considered to be absolute. Note: Relative-path-traversing syntax (i.e.: './' or '../' prefixes) are NOT supported in the @kauri-idref Further explanation on the kauri-idref, plus a complete list of the supported 'kauri-roles' is to be found in the 'form HTML' reference. #### Blending HTML Template and Configuration The more people make use of the customization possibilities of the HTML template, or more technically: the more nested kauri-idref attributes are found on the HTML elements nested in the <form> tag, the more of the data-structuring information the system can derive from it. This derived structure is effectively taken into account and thus avoids the double typing of providing the complete structure in the form-config as shown above. While these kauri-idref values are a simple and flexible alternative for expressing some implicit structure, they are no match for the expressiveness of the JSON form-config for more elaborate stuff like specific control settings. To match up the best of both worlds we allow the @kauri-type attribute to associate pre-configured control-types to the identified (by kauri-idref) controls. These pre-configured control-types are listed (using their name as a property-key) in the fconf['controlTypes'] object. For more details, check the 'form HTML' and 'form config' reference for more details on this usage. #### Event Handling and wiring For the event-handling kauri-forms just relies on the jQuery event mechanism. All regular jQuery event handling applies, and any additional kauri-specific events are bound and triggered through the matching "input" element. Getting a handle to this element is easy: 1. First lookup the control you want to bind to with CONTROL#findControl(path). This path argument can be absolute (starting with '/') or relative (NOTE: traversing the hierarchy with '../' is supported here) 2. on the found control the method CONTROL#getElement() will return the jQuery wrapped HTML element handling the 'input' role which is passing on all the events. In a code-sample:  var form = new$.org.kauriproject.forms.Form("my-form", fconf);
var wzip = form.findControl('/address/zip');
wzip.getElement().valueChanged(function() {
alert("The zip value changed to: ", wzip.getValue());
});

• the reference of available stuff. Explaining how to use them
• an explanation on how to build custom controls
• the hackerguide to learn about the internals of this framework

## 10.2 Standard Usage

The simplest scenario to create a form is to let the framework generate all HTML for you. This is possible by defining the structure you want in javascript and call the form creation mechanism.

### 10.2.1 Defining the form configuration

The form configuration is defined in a javascript object. All members of our form are defined in the members field. Per member we define at least the field type we need.
For example: our form needs a simple textfield 'name'. Then we define:

 var fconf = {
members: {
'name': 'string'
}};

That's it for the form configuration.  In fact that's a shorthand for this:

 var fconf = {
members: {
'name': {
base: 'string'
}
}};

in which 'name' is an object and can contain more then just the base type.

If we want to create a form with 6 basic form fields: a textfield name, a textfield with e-mail validation e-mail, a datepicker for a birthday, a checkbox and an textarea control, we use the structure below:

      var fconf = {
members: {
'name': 'string',
'email': {
base: 'string',
'+validators': { 'isEmail': {} },
label: "e-mail"
},
'birthday': {
base: 'date',
yearRange: '-100:+0',
label: 'What is your date of birth?'
},
'mondaysok': {
base: 'boolean',
label: 'Do you like mondays?'
},
'description': {
base: 'string',
control: 'textarea-control',
label: 'Describe yourself in 10 words'
}

}};

Each member contains at least a base type. Other fields in this example are: a label, a validator 'isEmail' and a control. The latter needs a little explanation. Each fieldtype is by default coupled to a control type. E.g. a 'string' fieldtype is by default coupled to a 'input-control', or a 'date' fieldtype is coupled to a 'date-control'.  But the description field in this example, does not need a simple input-control (which is the default), but needs a textarea-control.
Thus, by leaving the 'control' field, you fallback on the default controltype for the fieldtype.

In the form configuration we need one last info: where to post the form to on submit. This is defined in the createUri, which is defined next to the type-field. This results in the fconf below:

    var fconf = {
"createURI": "${publicUri('service:/data/contact/')}", members: { 'name': 'string', 'email': { base: 'string', '+validators': { 'isEmail': {} }, label: "e-mail" }, 'birthday': { base: 'date', yearRange: '-100:+0', label: 'What is your date of birth?' }, 'mondaysok': { base: 'boolean', label: 'Do you like mondays?' }, 'description': { base: 'string', control: 'textarea-control', label: 'Describe yourself in 10 words' } }}; ### 10.2.2 Creating the form #### 10.2.2.1 Creating the Kauri form by giving the id to the Form constructor When configured the form, all that rests is to create the form by calling the Form constructor with 2 arguments: 1. the id of the form in html 2. the fconf (form configuration) we created above  jQuery(document).ready(function() { var basicForm = new jQuery.org.kauriproject.forms.Form("basic-form", fconf); }); And the html for this form looks as simple as this:  <form id="basic-form" method="get" action="" > </form> #### 10.2.2.2 Creating the Kauri form with jQuery Another possibility is to create the form in jQuery and passing this jQuery wrapper to function kauriform: var basicForm =$("<form/>").appendTo($("div#someId")).kauriform(fconf); ## 10.3 Building Custom Controls #### Before you start Before venturing into creating own/custom controls for the kauri-framework we advise to 1. Get an understanding of how the system works (read about the concepts, this document, the hackerguide and maybe even the actual code) 2. Scan what is already there (both references and code) to make sure that what you need is not yet available. Maybe you'll find a close match from which your development can start. #### Analyse The Value The first aspect to consider is deciding which kind of value (type, structure) the control is expected to be editing. Things to consider: • Is it a simple value, or composite? • What is its basic Javascript data-type ? • Will it be multivalued (array)? Write down the structure and a few samples, and note down the different "formats" of this value. I.e. the 'user-format' (i.e. its representation to the end-user) and the 'wire-format' (i.e. the representation-format sent in the json structure to-and-from the data-service) Note that the user-format only is relevant when the user-interface actually foresees a string-representation of the value that is in some way end-user facing. This includes feedback-only purposes where the user-format is only read, never entered by the user. Taking the sample of a date: • the value itself is of type Date • the user-format will typically be some short date format like DD/MM/YYYY (potentially locale dependant, or following some configurable pattern) • the wire-format is typically chosen to be in the format described in ISO-8601 Understand how this 'value' step is also instrumental in the decision if you really should make a custom control or not: If you can't come up with a specific value to be edited, then that probably is because there is no value at all. In such cases a kauri-control is not what you are looking for and you should probably investigate into creating some custom User Interface effects through applying jQuery or jQuery-UI stuff and investigate into blending that with your form-controls. #### Formatters and Validators Related to this value-structure you might want to evaluate if the control you envision requires any custom formatters or validators to ensure a correct (and guided) entry of new values. To get up to speed with creating those we advise to read: #### Responsibilities The core job of your custom control is to manage the bridge between the HTML elements on the page (showing feedback to the user, and receiving his/her input) and the actual typed value kept inside the control. The control base-class to start from does many of this already in a correct and consistent way. What makes your custom control 'different' however will be the custom look and interaction possibilities it will offer. That is what you will need to focus on. ##### Value Access The first aspect to cover is how your control should deal with the value as being entered and fed back to the end-user. This is done through two methods: 1. void setUserValue(value) This should take the passed string-value (it will already be formatted to string by the user-formatter) and use that to update the UI elements so it shows the new value. 2. String getUserValue() This needs to read the (string) value as entered by the end user a return it to the caller. To do so, both methods should typically operate on the 'input' element (@kauri-role) found in the HTML DOM/tree and associated to the control (@kauri-idref) Standard initialization will make a reference to that element (jquery-wrapped) available through the getElement() method. ##### HTML Template Binding and/or Element Creation. In fact that standard initialization process will have automatically found (or created) all associated HTML elements (i.e. the ones with the different roles as well). For each kauri-role, this algorithm will use the 'select' and 'create' hints found in the 'elements' property of your control:  elements[role] = { "select" : jQuery-selector-string, "create" : jQuery-creator-string (used when selector doesn't find the elements) } After initialization all the found or created elements are available through the 'getElement(role)' method. (When omitted the role for the retrieved element is assumed to be 'input') After this initial element-binding has happened the initElements(create) method will be called. In this method any additional lookups, element creation or other HTML/DOM initialization can occur. The passed argument 'create' is a boolean indicating if the control is operating in 'create' mode or not. This mode indicates that no matching 'input' element was found, and that all further not-found role elements are expected to be created by your code. The 'binding' between control and matching HTML elements needs to work in two ways though. Up to now we've explained about the form looking up (or even creating) associated elements so DOM manipulation on them will make sure the UI reflects state changes are reflected in those elements. The binding however also needs to work the other way around: when the user interacts with the HTML (i.e. mostly <form><input>) elements, the control should be triggered to perform value-parsing, validation, etc etc. Therefore your control should register event-listeners with these elements. The default initialization already takes care of the change() event on the 'input' element associated to the control, but if you have other HTML elements to track, then you should use the initEvents() method to get that organized. We advise using the jQuery event mechanism for registering your listeners. ##### Exposing events The control itself will publish a 'valueChanged' event (which is distinct from the more low level HTML 'change' event). As we use the jQuery event mechanism for this as well, we 'tunnel' the event through the actual 'input' element of the control. Your control might want to expose specific events when certain state-changes occur. By convention we advise to use the same 'input' element to do so. Depending on your case either initElements() or initEvents() will be the most logical place to put this standard snippet of code to introduce your own "myEvent"  this._makeEventHandler("myEvent", optionalBindDataObject); Triggering the event is done with:  this.getElement().myEvent(); Or with the more verbose variant from jQuery in case you want to pass optional eventData  this.getElement().trigger("myEvent", optionalEventData); Registering a listener will typically happen from outside:  var siblingControl = this.lookupControl('../sibling-name'); this.getElement().myEvent(function() { // handling the event } ); Event-handlers will be executed in the context of the$input element (i.e. the this reference will point to the control's input element to which the event is bound) and be passed two arguments:

1. an Event Object (see jQuery documentation).
2. a so-called event-data object holding the merger of the optionalBindData and optionalEventData objects.  If not overwritten in the event-data, this will hold a reference to the control in evt.data.control itself.
##### Control Event Wiring

The form will initialize all its containing controls in an order that matches the logical top-down structure of the composing members. It is important to understand that this order is likely not to be in sync with the (rather arbitrary) dependency-sequence of different controls listening to each other's events.

More clearly: your control's own initElements() and initEvents() methods might be called well before those of the control emitting events it wants to listen to.

To avoid the issue where one is registering for an event that has not been exposed yet, a specific initEventWiring() method is foreseen on your control. This method is assured to be called only after all controls in the form have gone through their respective initElements() and initEvents().

Wrapping up:

1. Event-declaration code should go into initElements() or initEvents().
2. While initEventWiring() should be used to register your event-handler on some other control.

#### Coding

The framework offers an easy base-class for your controls to derive from. Below you find the typical (and minimal) frame of your own custom control.

;
( function( $) { var kf =$.org.kauriproject.forms;
var controlTypes = kf.controlTypes;

The anonymous function construct above is a known technique to ensure no top level naming conflicts will occur. The variables we declare form a shorthand for the namespaces relevant for Kauri.

    $.inherit(MyControl, kf.Control); function MyControl( id, form, conf) { this['<super.init>'](id, form, conf); } With the$.inherit we declare our control to be a subclass of the base control class.
Your constructor method can just delegate to the base implementation through the <super.init> call.
(One of the features of our prototype-inheritance system)

    MyControl.prototype.elements = {};
$.extend(MyControl.prototype.elements, kf.Control.prototype.elements);$.extend(MyControl.prototype.elements, {
"some-role" : {
create :"<div class="my-control">html to create control element for role "some-role"</div>",
select :"div.my-control"  // jQuery selector to find the some-role element without @kauri-role: if possible
}
});

Above you see how to inherit the base-class 'elements' and add specific element directives for your control.

    MyControl.prototype.initElements = function(create) {}

MyControl.prototype.initEvents = function() {}

MyControl.prototype.initEventWiring = function() {}


These steps in the control initialization have been explained above.
As well as the required user-value handling code below.

    MyControl.prototype.getUserValue = function() {

var $input = this.getElement(); // logic to read the value entered by the user from the HTML element return value; // should typically be a string } MyControl.prototype.setUserValue = function( value) { value = value || ""; var$input = this.getElement();

// logic to update the HTML element so it shows to the user what the current value is
}

kf.controlTypes.put("my-control", MyControl);

Finally the above line will register your new control which makes it available for referencing it from the fconf.

})(jQuery);

Internally our code uses exactly the same way of working, so check up on the already provided base-controls for more complete and complex examples.

### 10.3.1 Custom Formatters

##### Responsibility

The formatters in the kauri forms framework are simple and straightforward components that handle conversion between typed values and their string-representations.

The 'field' section of the Form Concepts page explains where those conversions fit in.

Formatters are expected to cover the conversion in both directions. Therefore two methods should be implemented:

1. format:
• receives a typed value as argument
• and should return its formatted string-representation
2. parse:
• receives a formatted string-representation which it should parse/interpret
• to produce a typed value as return

During either conversion one can decide that the offered input argument isn't suitable (This will most likely occur during 'parse' from string to typed value only.)  In such cases the implementation should just 'throw' a String-message, which will be displayed to the end user in the same way as a validation error.

##### Coding

The framework offers a base class to start your own formatter from.  Its main advantage is a re-usable 'fail' method that will ensure the required raising of validation error in the correct manner (and some recurring features like i18n, parameter injection etc etc)

;
( function( $) { var kf =$.org.kauriproject.forms;
var formatters = kf.formatters;

The anonymous function construct above is a know technique to ensure no top level naming conflicts will occur. The variables we declare form a shorthand for the namespaces relevant for Kauri.

    $.inherit(MyFormatter, kf.Formatter); function MyFormatter( ) { } With the$.inherit we declare our control to be a subclass of the base control class.

The needed parse/format methods can then just be implemented as needed:

    MyFormatter.prototype.parse() = function(valstr) {

// Expected behaviour is to trim input and intrerpret empty strings as containing "No Value"

var kf = $.org.kauriproject.forms; var validators = kf.validators; kf.validators.putAll( { "isPrime": { "validate": function(value) { var primeFunc = function(n,f) { f = f || 2; if (n == f) return true; if (n%f==0||n==1) return false; return primeFunc(n, f+1); }; if (primeFunc(value)) { return this.notifySuccess(); } else { return this.notifyFail("That is not a prime number"); } }} }); })(jQuery); ##### Declaring Alternatively the validator can be specified inside the form-config by placing it in the 'validators' section. In that case the behaviour of the described base class will be automatically applied to it, allowing you to leav out quite some boiler-plate code: Assuming the dafult format() is ok, you could deal with it like this: var fconf = { ... 'validators': { 'isPrime' : { 'validate': function(valstr) { // implementation here, including calls to this.notifySuccess() and this.notifyFail(msg); } } } } ## 10.4 Forms Reference Control types Field types Formatters Validators Name autocomplete-control case-control collection-control common for all controls composite-control date-range-control datetime-control dblselect-control gmap-control input-control output-control radioselection-control selection-control slider-control textarea-control upload-control Name boolean case collection composite date-range datetime decimal file integer integer-range location string time Name numeric numeric-range pattern pattern-date pattern-date-range short-date short-date-range time true-false wire-date wire-date-range wire-date-time Name dateRange dateRangeOrder dayOfWeek fieldComparer isDate isEmail isInt isIntRange isOption isUrl length range regex remote required #### Validators ##### Error messages All validators have the possibility to customize their error message. For example if you add the required validator and you want to set the error message "This field is absolutely required!". "+validators" : { "required" : {"message" : 'This field is absolutely required!'} } Note: for some validators it is also possible to use some {0}, {1} arguments to show a configured value of the control. ### 10.4.1 Form configuration object ##### General sections What goes into the form-config structure? var fconf = { /* communication properties */ "createURI": "${publicUri('service:/data/person/')}",

/* described data structure */
"members": {
"name":    {   /* some string input */          },
"sex" :    {   /* Male or Female choice */      },
"birth:    {   /* date input */                 },
"hobbies": {   /* flexible list of strings */   },
"address": {   /* nested structure of street, number, zip, city and country */...}
}

/* Additional custom types */
"controlTypes": {
"name-of-control": {  /*   definition */   }
}
}
##### Form Specific properties

uri for create and read/write

(if any?)

##### Additional Custom Types

named, referable and extensible custom 'formatters, validators, fields and controls'

howto define?
howto use/refer?

### 10.4.2 Forms API

##### Control
Properties Methods
 reset() Sets the control back to its initial value. e.g. form.reset() findControl(path) Finds another control by its path. path A path is a slash-separated list of control identifiers, e.g. Examples:   var street = form.lookupControl("/personal/addresses/2/street");   var city = street.lookupControl("../city"); getWireValue() Returns the current wire value of the control setWireValue(wireValue[, noValidation]) Sets the current wire value of the control, optionally triggering validation. wireValue: the wire value noValidation: boolean indicating no validation is required String getId() Returns the control's id Control getParent() Gets the parent of the current control. Identical to this.lookupControl("..") Control getForm() Gets the form control that contains this control Array getOptionValues() If this control has an options object, return the values. (FIXME: wouldn't it make more sense to have getOptions().getValues()?)
##### Validator

Properties

Methods

 notifySuccess() Reports a validation success to the validation listener and returns true notifyFail(msg, args) Reports a validation failure to the validation listener. msg: The message to display (See Message API) args: Arguments for the message notify(result, msg) Reports a validation failure or success to the validation listener and returns 'result'. msg: A Message object (See Message API) args: Arguments for the message
##### ValidationListener

Each Validator uses validation listener to report validation results

Properties Methods
 validationSuccess() Event indicating a successful validation validationFail() Event indicating a failed validation validationStart() Event indicating validation is started validationCompleted() Event indicating validation is completed validationIgnored() Event indicating validation is ignored (this happens when a remote validation result arrives after a new validation round has already been triggered)
##### Formatter

Formatters are used to convert user input (strings) to objects and back. A control uses two formatters: one for converting between strings and user-values and one for converting between strings and wire-values.

Properties Methods
 parse(str) Parse the user input and return an object representation. str: the string to parse format(obj) Convert the object to a string representation. obj: the object to format fail(msg, args) A formatter should call this method when the parse or format functions can't complete normally. msg: A Message object (See Message API) args: Arguments for the message
##### Field

No properties or methods available in the public API

##### FieldType

No properties or methods available in the public API

##### Options
Properties
 boolean shared Indicates this options object is used by multiple controls String uri The uri template where the option's data are synchronously retrieved
Methods
 boolean refreshable() returns true if 'uri' is defined void refresh() fires an ajax request to refresh the values and labels boolean updateable() returns true if 'uri' is defined or if 'fixed' is false.
Events
 update(eventHandler) If the Register an event handler eventHandler: An event handler for update events use option.update() to manually trigger the update event.

TODO

TODO

TODO

### 10.4.4 Fields

Registered name

boolean

Properties
Control
User-Format
Wire-Format

-

#### 10.4.4.2 case

###### Specifications
Registered name

case

Properties
control
Default configuration

-

selector

fieldtype specifying the case selector

cases

object containing possible cases

User-Format
Wire-Format
###### Example
"cases": {
"text" : {
"base": "string",
"label": "Text"
},
"number" : {
"base": "decimal",
"label": "Number"
}
}

Registered name

collection

Properties
Control
User-Format
Wire-Format

Registered name

composite

Properties
Control
User-Format
Wire-Format

#### 10.4.4.5 date-range

###### Specifications
Registered name

date-range

Properties
Base
members
Control
User-Format Wire-Format

Registered name

datetime

Properties
Base
members
Control
User-Format
Wire-Format

#### 10.4.4.7 decimal

###### Specifications
Registered name

decimal

Properties
Base
Control
Default configuration

-

User-Format
Wire-Format

numeric with rawFormat

Registered name

file

Properties
Control

#### 10.4.4.9 integer

###### Specifications
Registered name

integer

Properties
Control
Default configuration
User-Format
Wire-Format

numeric with rawFormat

#### 10.4.4.10 integer-range

###### Specifications
Registered name

integer-range

Properties
Base
Control
Default configuration
User-Format
Wire-Format

numeric-range with rawFormat

Registered name

location

Properties
Control
Inherits

Members

User-Format

-

Wire-Format

-

#### 10.4.4.12 string

###### Specifications
Registered name

string

Properties
Control
Default configuration

-

User-Format

trim

Wire-Format

-

Registered name

time

Properties
Base
Control
User-Format
Wire-Format

### 10.4.5 Controls

#### 10.4.5.1 autocomplete-control

###### Data Structure

The JSON structure used for a autocomplete control looks as follows:

{"name":"value"}
###### Form Config Syntax
dataUri

The uri where data can be looked up

inputTemplate

A string template that defines how the values are represented in the html input element

listTemplate

A string template that defines how the values are represented in the list template.

initial

Initial value

###### Example
"contact": {
"base": "string",
"label": "Select a contact",
"control": {
"base": "autocomplete-control",
"dataUri": "/data/contact/",
"inputTemplate": "{id} - {name}",
"listTemplate": "{id} - {name} {email}"
}
}

with html

  <div kauri-idref="contact">
<label kauri-role="label" for="contact"/>
<input id="contact" type="text" kauri-role="input"/>
</div>

#### 10.4.5.2 case-control

###### Data Structure

The JSON structure used for an input control looks as follows:

{"casecontrolname":{"case":"selectedcase","value":"casevalue"}}
###### Form Config Syntax
nullable

boolean field which defined whether or not this selection can contain a 'empty' (nothing selected) value

null-text

which text to display when nothing selected (use in combination with nullable : true)

initial
###### Example

configuration via fconf:

"tn": {
"base": "case",
"selector": some-selector-fieldtype,
"label": "Text or Number?",

"control": {
"base": "case-control",
"nullable": true,
"null-text": "--- please select ---"
},
"cases": {
"t" : {
"base": "string",
"label": "Text"
},
"n" : {
"base": "decimal",
"label": "Number"
}
}
}

#### 10.4.5.3 collection-control

###### Data Structure

The JSON structure used for a collection control looks as follows:

[
"hello",
"world",
...
]
###### Form Config Syntax
base

collection-control

initial example

note that 'cols' and 'rows' does not overrule the css properties of the textarea

control: {
'base': 'collection-control',
'control': {
'base': 'collection-control',
'templates' : {
'layout': "<div style='border-style: dashed; border-width: 1px; ;margin: 10px; padding: 10px;'><div ><span kauri-role='label'/><span kauri-role='control'/><span kauri-role='messages'/><span kauri-role='delete'/></div></div>",
'control': "<div kauri-role='container' ></div>"
}
}
}
###### Specific Formatters

This section describes any specific existing formatters (if any) are available to format the values managed by this control.

###### Specific Validators

This section describes any specific existing validators (if any) are available to validate the values managed by this control.

###### Events

This section lists and describes the specific events produced by this control.

#### 10.4.5.4 common for all controls

All controls have some common properties that aren't control specific.

###### Form Config Syntax
initial

initial is an object that defines some initial properties for the control:

• enable: true/false
• show: true/false
• value: initial value for this control
templates

for each control, templates can be defined. These specify what the generated control should look like.

• control
###### HTML Bindings

You can bind HTML to the form configuration. Via the attribute 'kauri-idref' you specify which kauri field you are binding the HTML to. This idref can be absolute or relative. If a piece of HTML is bound to the form configuration via kauri-idref, you can add some additional properties.

1. you can specify which fieldtype it is using via kauri-type
2. you can specify which controltype it is using via kauri-control
3. you can add some initial properties (value, type="hidden", disabled)

Without attaching it to a specific fconf field (i.e. without specifying kauri-idref) you can also assign a piece of html code to be the layout of a collection or composite with the kauri-layout attribute. If a layout contains more then one HTML element, you can group them in kauri-group. And even more, when assigning layouts you can also assign positions to copy each layout clone via kauri-cursor.

kauri-idref

makes the coupling between the HTML and the form configuration.

example

fconf:

var fconf = {
members: {
'firstname':  {'base' : 'string'},
'lastname':   {'base': 'string'}
}};
new jQuery.org.kauriproject.forms.Form("myform", fconf);

html :

<form id="myform">
<label kauri-role="label" kauri-idref="firstname"/>
<input kauri-idref="firstname" kauri-role="input"/>
<label kauri-role="label" kauri-idref="lastname"/>
<input kauri-idref="lastname" kauri-role="input"/>
</form>
kauri-type

specifies which FieldType to use for this field

Example

fconf:

var fconf = {
members: {
}
};
new jQuery.org.kauriproject.forms.Form("myform", fconf);

html :

<form id="myform">
<input kauri-idref="firstname" kauri-role="input" kauri-type="string"/>
<input kauri-idref="lastname" kauri-role="input"  kauri-type="string"/>
</form>

remark that in this example, the control type for "firstname" and "lastname" will default to the default controltype for the field-type "string".

kauri-control

specifies the ControlType to use for this field. This one is optional, if left out, it will default to the default ControlType of the according FieldType.

example

fconf:

var fconf = {
controlTypes: {
sliderControl: {
base: 'slider-control',
min: 1,
max: 1000,
step: 1,
isRange: false
}
}
};

html :

<form id="myform">
<span kauri-idref="size" kauri-type="integer" kauri-control="sliderControl" kauri-role="control"/>
</form>
kauri-role

assigns a 'role' to a field. Possible values for kauri-role are:

• input : a control with 'input' role won't be replaced by a template. This means you know what you are doing in templating, and don't want the forms framework to do any automatic rendering of controls for you. Not specifying any role for a control, defaults to this 'input' role.
• control : if this role is assigned to a control, the html code for this will be replaced by the template of the control
• label: the label for a control
• messages : bundles the messages gathered for this control
example

Following will generate a datepicker input control for you:

<span kauri-idref="birthday"  kauri-role="control" kauri-type="date"/>

While this will assume you know what you are doing (using some datepicker yourself) and will not generate anything:

<span kauri-idref="birthday"  kauri-role="input" kauri-type="date"/>
kauri-child kauri-layout

specifies a layout for a composite or a collection. This piece of HTML code will be cloned and inserted into the DOM for each child element of the composite/collection. Value of the kauri-layout atributes references the absolute path of the parent collection/composite control.

example

Collection "countries" will be displayed in a table. Each country will be displayed in a table row. To accomplish this we set kauri-idref="countries" at table level and kauri-layout="/countries" at row level. Remark that the latter contains a absolute path.

<table kauri-idref="countries" kauri-type="collection" >
<tr>
<th>Name</th>
<th>Capital</th>
<th>Area (km*km)</th>
</tr>
</thead>
  <tbody kauri-role="container" >
<tr kauri-layout="/countries">
<td >
<input kauri-idref="name" kauri-type="string" kauri-role="control"/>
</td>
<td>
<input kauri-idref="capital" kauri-type="string" kauri-role="control"/>
</td>
<td>
<input kauri-idref="area" kauri-type="integer" kauri-role="control"/>
</td>
</tr>
</tbody>
</table>
kauri-group

to group more then one HTML element in groups, use this attribute. Without kauri-group the layout assumes just one group.

example

Take the above kauri-layout example. Assume we want 2 rows per collection child, we cannot accomplish that with just the kauri-layout attribute. Those 2 <tr> elements can then be grouped by using the kauri-group attribute.

<table kauri-idref="countries" kauri-type="collection" >
<tr>
<th>Name</th>
<th>Capital</th>
<th>Area (km*km)</th>
</tr>
</thead>
  <tbody kauri-role="container" >
<tr kauri-layout="/countries" kauri-group="country">
<td >
<input kauri-idref="name" kauri-type="string" kauri-role="control"/>
</td>
<td>
<input kauri-idref="capital" kauri-type="string" kauri-role="control"/>
</td>
</tr>
<tr kauri-layout="/countries" kauri-group="country">
<td>
<input kauri-idref="area" kauri-type="integer" kauri-role="control"/>
</td>
</tr>
</tbody>
</table>
kauri-cursor

With kauri-cursor you have the possibility where to insert the cloned layout per child of the composite or collection. If we don't do this, the clone will be inserted at

1. the position of the layout element in HTML
2. the end of the containment element (first of 2 available will be used)

First option is not available if we use automatic rendering of the collection or composite.
If a kauri-cursor is found, this one will be used to insert the clone.

example
<table kauri-idref="people" kauri-type="collection" >
<tbody kauri-role="container">
<tr kauri-cursor="/people/#" kauri-group="peoplegroup" />
<tr kauri-layout="/people/#" kauri-role="container" kauri-group="peoplegroup" >
<td >
<span kauri-idref="firstname" kauri-role="control" kauri-type="string"/>
</td>
<td>
<input kauri-idref="lastname" kauri-role="input" kauri-type="string"/>
</td>
<td kauri-idref="children" kauri-type="collection" kauri-layout="/people/#/children/#" kauri-child="string" >
<input kauri-role="input" kauri-type="string" />
</td>
</tr>
<tr kauri-cursor="/people/#" kauri-group="other"/>
<tr kauri-layout="/people/#" kauri-group="mylabel" >
<td kauri-cursor="/people/#/communications"  kauri-group="mylabel" /><!--  expliciet -->
<td kauri-idref="communications" kauri-type="collection" kauri-layout="/people/#/communications/#" kauri-group="comGroup">
<input kauri-idref="type" kauri-role="control" kauri-type="string" kauri-control="output-control"/>
<input kauri-idref="value" kauri-role="input" kauri-type="string"/>
</td>
</tr>
</tbody>
</table>
initial properties

some attributes in html can be used to specify the initial properties

value="somevalue"
type="hidden"
disabled
###### Events
• valueChanged : event handler triggered on change of value of control
• validationFinished : event handler triggered when validation of control is finished

#### 10.4.5.5 composite-control

###### Data Structure

The JSON structure used for a composite control looks as follows:

{
"integermember": 15
"stringmember": "hello world"
"compositemember": {
...
}
"collectionmember": [
...
}
}
###### Form Config Syntax
base

composite-control

members

{ "member1": ..., "member2": ... }

initial example

note that 'cols' and 'rows' does not overrule the css properties of the textarea

control: {
'base': 'composite-control',
'members': {
'firstName': { base: 'string' },
'lastName': { base: 'string' }
}
}
###### Specific Formatters

This section describes any specific existing formatters (if any) are available to format the values managed by this control.

###### Specific Validators

This section describes any specific existing validators (if any) are available to validate the values managed by this control.

###### Events

This section lists and describes the specific events produced by this control.

#### 10.4.5.6 date-range-control

###### Data Structure

The JSON structure used for a date-range control looks as follows:

{"name":"2010-12-31/2011-21-31"}
###### Form Config Syntax
base

date-range-control

forceOrder

"asc", "desc", "none" to indicate whether the members should be automatically ordered ascending or descending or not.

(Default: "asc")

initial example

note that 'cols' and 'rows' does not overrule the css properties of the textarea

control: {
'base': 'date-range-control',
'forceOrder': 'desc'
}
###### Specific Formatters

This section describes any specific existing formatters (if any) are available to format the values managed by this control.

###### Specific Validators

This section describes any specific existing validators (if any) are available to validate the values managed by this control.

###### Events

This section lists and describes the specific events produced by this control.

TODO

#### 10.4.5.8 dblselect-control

###### Data Structure

The JSON structure used for a selection control looks as follows:

{"name":[{object1},{object2}]}
###### Form Config Syntax

this boolean field defines whether or not to show a '>>' button which adds all options at once

showRemoveAll

this boolean field defines whether or not to show a '<<' button which removes all options at once

this boolean field defines whether or not to show an input field to add a custom option

data

the list of options, defined in a JSON array

initial
###### Examples
simple selection list with 3 options
"colors": {
"base": "string",
"label": "Colors",
"control": {
"base": "dblselect-control",
"options": {
"data": ["red", "green", "blue", "white", "black", "yellow", "purple"]
},
"showRemoveAll": true,
}
}

#### 10.4.5.9 gmap-control

###### Data Structure

The JSON structure used for a gmap control looks as follows

"location":{"latitude":"51.00833734239019","longitude":"3.712741613126127","zoom":"16"}
###### Form Config Syntax
base

gmap-control

initial example
locationControl: {
base: 'gmap-control'
}
###### Specific Formatters

This section describes any specific existing formatters (if any) are available to format the values managed by this control.

###### Specific Validators

This section describes any specific existing validators (if any) are available to validate the values managed by this control.

###### Events

This section lists and describes the specific events produced by this control.

#### 10.4.5.10 input-control

###### Data Structure

The JSON structure used for an input control looks as follows:

{"name":"value"}
###### Form Config Syntax

this boolean field defines whether or not this input field is op type "password"

initial
###### Example

configuration via fconf

"controlTypes": {
'base': 'input-control',
'initial' : {
'enable': false,
'show' : true,
'value': 'test'
}
}
}

configuration via html

<input kauri-idref="name" kauri-type="string" kauri-control="input-control" kauri-role="input" disabled="disabled" type="hidden"/>

#### 10.4.5.11 output-control

###### Data Structure

The JSON structure used for an output control looks as follows:

{"name":"value"}
###### Form Config Syntax
base

output-control

html

this boolean field defines whether or not the value of the control should be shown as html or not

initial
###### HTML Bindings

see the syntax common for all controls for how to set initial properties via html

###### Example
"controlTypes": {
"htmlTextControl": {
'base': 'output-control',
'html' : true
}
}

or via HTML

<span kauri-idref="tip-of-the-day2" kauri-control="output-control" kauri-type="string"/>

###### Data Structure

The JSON structure used for a radioselection control looks as follows:

{"name":"value"}
###### Form Config Syntax
cols

number of columns used to display the possibilities

data

the list of options, defined in a JSON array

initial
###### Example
"radio": {
"base": "string",
"label": "Value set",
"control": {
"options": {
"data": ["yes", "no", "maybe"],
"cols": 3
}
}
}

#### 10.4.5.13 selection-control

###### Data Structure

The JSON structure used for a selection control looks as follows:

{"name":"value"}
###### Form Config Syntax
showRefresh

this boolean field defines whether or not to show a refresh button next to the selection control

depends

selection-controls can depend on the value of other controls

options

the list of options. This options can be retrieved via a data field or via an uri which gets the list.

data

the list of options, defined in a JSON array

uri

uri which gets the option list as a JSON array

valuetemplate

template to use to render the value

labeltemplate

template to use to render the label used in the options list

nullable

boolean field which defined whether or not this selection can contain a 'empty' (nothing selected) value

null-text

which text to display when nothing selected (use in combination with nullable : true)

initial

Specific Formatters

This section describes any specific existing formatters (if any) are available to format the values managed by this control.

###### Examples
simple selection list with 3 options
"control": {
"base": "selection-control",
"options": {
"data": ["yes", "no", "maybe"]
},
"initial": {
"value": "maybe"
}
}
selection list which gets the data from an uri
"control": {
"base": "selection-control",
"options": {
"uri": "${publicUri('service:/data/getoptionlist/')}", "valueTemplate": "{id}", "labelTemplate": "{name}" } } where the service returns a structure like this: [{"id" : "1", "name": "option1"}, {"id" : "2", "name": "option2"}, {"id" : "3", "name": "option3"}] a refreshable selection list "control": { "base": "selection-control", "options": { "uri": "${publicUri('service:/data/optionlist/')}",
"showRefresh": true,
"valueTemplate": "{id}",
"labelTemplate": "{name}",
"nullable": true,
"null-text": "--- please select ---"
}
}
selection list that depends on value of another control

in the 'depends' field the path of the needed control is given a name which then can be used in the uri:

"control": {
"base": "selection-control",
"depends": {"needThisOne": "/othercontrol"},
"options": {
"uri": "${publicUri('service:/data/optionlist/{needThisOne}/options')}", "valueTemplate": "{name}", "labelTemplate": "{name}" } } ###### Events • update: This is not an event of the selection-control, but of the options member contained within the selection-control. The event is fired when the options are updated (or loaded for the first time if they are loaded asynchronously). Usage: var myform = new$.org.kauriproject.form.Form("form", fconf);
myform.findControl("/myselection").options.update(function() {
//... do something with the options
});

#### 10.4.5.14 slider-control

###### Data Structure

The JSON structure used for an input control looks as follows for a range slider:

"slider-range":{"start":"10","end":"20"}

and for a non-range slider:

"slider":"10"

slider-control

###### Form Config Syntax
base

slider-control

isRange

true for range sliders, false for non-ranges

min

the minimum value possible

max

the maximum value possible

step

which step to use to change the value of the slider

initial
###### Example
sliderControl: {
base: 'slider-control',
min: 1,
max: 1000,
step: 1,
isRange: false
}

#### 10.4.5.15 textarea-control

###### Data Structure

The JSON structure used for a textarea control looks as follows:

{"name":"value"}
###### Form Config Syntax
base

textarea-control

rows

number of rows in the text area

cols

number of columns in the text area

boolean true|false to specify whether this textarea should be readonly or not. default is false.

initial example

note that 'cols' and 'rows' does not overrule the css properties of the textarea

control: {
'base': 'textarea-control',
'cols': 40,
'rows': 10,
}
###### Specific Formatters

This section describes any specific existing formatters (if any) are available to format the values managed by this control.

###### Specific Validators

This section describes any specific existing validators (if any) are available to validate the values managed by this control.

###### Events

This section lists and describes the specific events produced by this control.

###### Data Structure

The JSON structure used for an input control looks as follows:

{"uploadfieldname":{
"charset":"WINDOWS-1252",
"mimetype":"application/pdf",
"size":43000,
"id":"tmpresourceid",
"filename":"filename.pdf",
"fieldname":"file"}
}

fieldname is not implemented yet, and will always be "file"

###### Used in

file, upload-control is thus the default control-type for a field of type 'file'.

###### Form Config Syntax
base

initial example
"uploadControl" : {
}
###### Specific Formatters

This section describes any specific existing formatters (if any) are available to format the values managed by this control.

###### Specific Validators

This section describes any specific existing validators (if any) are available to validate the values managed by this control.

###### Events

This section lists and describes the specific events produced by this control.

### 10.4.6 Formatters

#### 10.4.6.1 numeric

###### Description

format from a Number to a String and parse to a Number

###### Specifications
Registered name

numeric

Properties
• rawFormat : Set to true if no locale formatting is needed. Default is false.

Methods
• format (Number) returns String
• parse (string) returns Number: parses a string and returns the converted Number

#### 10.4.6.2 numeric-range

###### Description

Formats a String of format

"Number1 - Number2"


to object:

{ start: Number,  end : number }

and vice versa.

###### Specifications
Registered name

numeric-range

Properties
• rawFormat : Set to true if no locale formatting is needed. Default is false.

Methods
• format (object) returns String : formats a integer range object {start: Number, end: Number} to a String "Number1 - Number2"
• parse (string) returns object : parses a String "Number1 - Number2" to an integer range object {start: Number, end: Number}

#### 10.4.6.3 pattern

###### Description

use a pattern to format or parse

patterns:

• $: alfanumeric • # : digit • * : whatever character ###### Specifications Registered name pattern Properties • pattern : pattern to use, default is "*" Methods • format (String) returns string : formats a String using the specified pattern • parse (string) returns String : parses a string using the specified pattern and the converted String ###### Example Pattern for a Belgian bank account: ###-#######-## var f = getFormatter("pattern", { pattern :"###-#######-##" }); format of "737000003679" returns "737-0000036-79", parse of " 737-0000036-79 " returns "737000003679" (remark the trimmed string). #### 10.4.6.4 pattern-date ###### Specifications Registered name pattern-date Properties • pattern (string) : format in which dates will be formatted and format that will be expected when parsing dates. The default pattern is the ISO-8601 format (yy-mm-dd). Example 2008-05-16. The syntax used for specifying the date format is the one used by the jQuery datepicker. Methods • format (Date) returns spring : formats a Date using the specified pattern • parse (string) returns Date : parses a string using the specified pattern and returns a Date #### 10.4.6.5 pattern-date-range TODO #### 10.4.6.6 short-date ###### Description short-date is a pattern-date with a preconfigured pattern. Formatter is based on jQuery formatDate patterns. ###### Specifications Registered name short-date Base Formatter Properties Methods • format (String) returns string : formats a Date using the specified pattern and returns the String • parse (string) returns Date: parses a string using the specified pattern and return the Date #### 10.4.6.7 short-date-range TODO #### 10.4.6.8 time ###### Description time is structure of format "hh:mm:ss" ###### Specifications Registered name time Methods • format (Date) returns String : formats a Date using the specified pattern and returns the String • parse (String) returns Date: parses a string using the specified pattern and return the Date #### 10.4.6.9 true-false ###### Description formatter to formats or parses a Boolean value ###### Specifications Registered name true-false Methods • format (Boolean) returns String : return "true" or "false" • parse (String) returns Boolean: returns false in case of "false" (case insensitive) or true in all other cases #### 10.4.6.10 wire-date ###### Description wire-date is a pattern-date with a preconfigured pattern. ###### Specifications Registered name wire-date Properties Methods • format (Date) returns String : formats a Date using the specified pattern and returns the String • parse (String) returns Date: parses a string using the specified pattern and return the Date #### 10.4.6.11 wire-date-range ###### Description wire-date-range parses date separated by a specified separator to object {start: Date, end : Date} ###### Specifications Registered name wire-date-range Properties • rangeSeparator : default value is "/" Methods • format (Object) returns String : formats Object {start: Date, end : Date} to String "startDate / endDate" • parse (String) returns Object: parses a String "startDate / endDate" to Object {start: Date, end : Date} #### 10.4.6.12 wire-date-time ###### Description wire-date-time parses date and time separated by a specified separator to objects {date: datePart, time : timePart} where datePart and timePart are just 2 Strings ###### Specifications Registered name wire-date-time Properties • timeSeparator : default is "T" • pattern : default is the ISO_8601 format Methods • format (Object) returns String : formats Object {date: String, time : String} to String "dateStringTtimeString" • parse (String) returns Object: parses a String "dateStringTtimeString" to Object {date: String, time : String} ### 10.4.7 Validators #### 10.4.7.1 dateRange ###### Specifications Registered name dateRange Base Properties • minDate (Date) : the minimum required date • maxDate (Date) : the maximum required date Methods • validate (object) : checks if the provided object is a date and is positioned between the minimum and the maximum date (minimum and maximum not included) #### 10.4.7.2 dateRangeOrder ###### Specifications Registered name dateRangeOrder Base • order: "asc" • strict: false Properties • - Methods • validate (object) : checks if the provided object's date members start and end are in the correct order (ascending, strictly ascending, descending or strictly descending) #### 10.4.7.3 dayOfWeek ###### Specifications Registered name dayOfWeek Properties • dayOfWeek : which day of the week needs to be checked ( 0 = sunday , 6 = saturday) • _days : array containing week day names (starting with sunday, ending with saterday) Methods • validate (object) : checks if the provided object is a date and is weekday ###### Example { "base" : "dayOfWeek"), "dayOfWeek" : 0 } new Date(2008, 7, 31) validates (is a sunday) new Date(2006, 7, 30) Does not validate (isn't a sunday) #### 10.4.7.4 fieldComparer ###### Specifications Registered name fieldComparer Properties • fieldA : first field needed for validation • fieldB : second field needed for validation • operation : operation used for validation, possible operation are: • eq : compare for equality valA and valB • lt : valA < valB • gt : valA > valB • lte : valA <= valB • gte : valA >= valB Methods • validate (object) : compares the 2 fields using the operation specified ###### Used in #### 10.4.7.5 isDate ###### Specifications Registered name isDate Properties • patterns (string array) : a list of patterns that can express the date format. By default this is yy-mm-dd and dd/mm/yy. Methods • validate (object) : checks if the provided object is a date or can be changed into a date. ###### Used in #### 10.4.7.6 isEmail ###### Specifications Registered name isEmail Methods • validate (String) : checks if the provided String is a valid e-mail address (email regex from - http://www.regular-expressions.info/email.html) #### 10.4.7.7 isInt ###### Specifications Registered name isInt Methods • validate (object) : checks if the provided object is valid number or can be converted into one ###### Used in #### 10.4.7.8 isIntRange ###### Specifications Registered name isIntRange Base isInt Methods • validate (object) : checks if the provided object is a int range { start : Number, end: Number} ###### Used in #### 10.4.7.9 isOption ###### Specifications Registered name isOption Methods • validate (value, data) : checks if the provided value is available in the options list given as second argument #### 10.4.7.10 isUrl ###### Specifications Registered name isUrl Methods • validate (String) : checks if the provided String is a valid uri (uri regex from http://www.osix.net/modules/article/?id=586) #### 10.4.7.11 length ###### Specifications Registered name length Properties • min : the minimum length (default to 0) • max : (optional) the maximum length Methods • validate (object) : checks if the provided object (String or Array) is of provided length #### 10.4.7.12 range ###### Specifications Registered name range Properties • min : required minimum (optional) • max : required maximum (optional) • step : required step (optional) Methods • validate (object) : checks if the provided object is between the minimum and maximum and -if between- a required step Only integer steps are implemented so far ###### Used in ###### Example { "base" : "range", "min" :-10, "max" :10, "step" :3 }; -15 : does not validate -14 : does not validate -12 : does not validate -11 : does not validate -10 : does validate -9 : does not validate -8 : does not validate -7 : does validate 7 : does validate "some text" : does not validate #### 10.4.7.13 regex ###### Specifications Registered name regex Properties • regex (String) : the regex used to validate Methods • validate (object) : checks if the provided object validates the regex ###### Example Pattern for a Belgian national register number: xx.xx.xx-xxx.xx "+validators" : { regex:{ "regex":/\d{2}\.\d{2}\.\d{2}-\d{3}\.\d{2}/ } } #### 10.4.7.14 remote ###### Specifications Registered name remote Properties • location: location path for remote validation Methods • validate (value, validationData) : validate wireData in remote validation #### 10.4.7.15 required ###### Specifications Registered name required Methods • validate (value) : check of the provided value is not empty # 11 Internationalization (i18n) The internationalization (i18n) support of Kauri includes: • determination of the active locale settings • a reusable form snippet to let users configure their locale preferences • translation based on resource bundles • formatting of numbers and dates (including timezone adjustment) • template language integration of the above two features • server side and client side (browser) support • customization of resource bundles by developer-users or deployer-users ## 11.1 i18n first steps ### 11.1.1 wiring.xml If you generated your project from a template, then this might already be set up for you. In the wiring.xml, add the following modules as first modules.  <modules> <artifact id="i18n" groupId="org.kauriproject" artifactId="kauri-i18n-impl"> <mount name="i18n" path="/kauri/i18n"/> </artifact> <artifact id="locale-assignment" groupId="org.kauriproject" artifactId="kauri-locale-assignment"/> The kauri-i18n-impl module provides all i18n functionality, most notably resource bundle loading. The locale-assignment module installs a Restlet filter which will determine the locale to use. This is a small module, which you could replace with your own if you want to use custom logic for this. ### 11.1.2 pom.xml This step is optional. It is only necessary if you plan on programmatically making use of i18n, thus to lookup a translation or format a number or date from Java code. In the pom.xml of your module, add the following dependency:  <dependency> <groupId>org.kauriproject</groupId> <artifactId>kauri-i18n-api</artifactId> <version>${version.kauri}</version>
</dependency>

### 11.1.3 Defaults configuration

(optional)  Create a file conf/locale-assignment/defaults.xml

<i18n ignoreClientInfo="true">
<defaultLocale language="en" country="" variant=""/>
<defaultTimeZone>UTC</defaultTimeZone>
</i18n>

option

@ignoreClientInfo

If true, the browser's accepted variants will be ignored.  Default false

defaultLocale

Default java.util.Locale.getDefault()  @country and @variant can be omitted

defaultTimeZone

Default UTC (not java.util.TimeZone.getDefault() - currently under discussion)

### 11.1.4 Create a resource bundle

Resource bundles should be put in an i18n directory in src/main/kauri. The name of the resource bundle should not conflict with those of other modules (except if by intention), therefore its name is namespaced using Java-style dotted notation. A suffix is added to specify the locale, such as _en (to include the country, use e.g. _nl_BE). The file extension should be .xml. So for example, we could create the following files:

src/main/kauri/i18n/org.myproject.mymodule_en.xml
src/main/kauri/i18n/org.myproject.mymodule_fr.xml

In the _en file, we could put this:

<?xml version="1.0"?>
<messages>
<message key="yes">yes</message>
<message key="no">no</message>
</messages>

In the _fr file, we could put this:

<?xml version="1.0"?>
<messages>
<message key="yes">oui</message>
<message key="no">non</message>
</messages>

### 11.1.5 Create a template

Assuming you have set up the pages router, you can create a template file at:

src/main/kauri/pages/i18ntest.html.xml

with something like this in it:

<html>
<body>

### 11.4.3 format() function

The format function takes a variable number of arguments:

• the first argument is the "format string". This is a string containing placeholder like {0} where content should be inserted. To those familiar with that, it is similar to Java's MessageFormat, but not the same.
• the other arguments are the parameters to be inserted into the first format string

#### 11.4.3.1 Format string syntax

##### 11.4.3.1.1 Basics

The format string contains placeholders using  {...} syntax. If you want to insert {...} literally, escape it using backslash: \{...}.

The placeholder contains the index of the parameter to insert, and optionally some formatting arguments.

A simple format string thus might look like:

The quick {0} fox jumps over the {1} dog.

Used with the format function in the template language:

${format('The quick {0} fox jumps over the {1} dog.', 'brown', 'lazy')} If the first argument would be part of a resource bundle below the key 'quick_dog_phrase', the usage would be: ${format(i18n('quick_dog_phrase'), 'brown', 'lazy')}
##### 11.4.3.1.2 Formatting arguments

Formatting arguments are useful when the value to insert is not a string, but a date or number.

The full format of the placeholders is:

{index,type,style_or_pattern}

The parts are:

• index: 0, 1, ... as explained before
• type: how to format the object
• style_or_pattern: some types take an extra style hint or formatting pattern as an argument

Dates will be adjusted to the user's timezone when formatting.

The table below lists the available types and styles.

Object type

Type

Style / pattern

dates

(java.util.Date
or

date

none / S / M / L / F (short/medium/long/full)

time

none / S / M / L / F

datetime

none / two characters from S / M / L / F / -

dtpattern

A joda-time date/time formatting pattern.

numbers

(java.lang.Number)

int

none

nrpattern

A Java SimpleNumberFormat pattern.

##### 11.4.3.1.3 Examples
Format a single date:
${format("{0,date}", someDateObject)} Format a single date using a pattern:${format("{0,dtpattern,dd/MM/yyyy}", someDateObject)}

Format a date-time using long date format and small time format:
${format("{0,datetime,LS}", someDateObject)} ## 11.5 Server API TODO I18n object Note: the I18nManager is made available via a ThreadLocal variable. If you spawn your own threads, you will have to take this into account, e.g. by passing a reference to the I18nManager manually. ## 11.6 Client API Since web pages are often constructed dynamically by downloaded Javascript code, features such as translation and number formatting need to be available client-side as well. i18n REST-service The kauri-i18n-impl bundle exposes an 'i18n' REST-service. The main purpose of this REST-service is to make resolved resource bundles available. #### Getting a bundle Motivation: due to locale fallback (e.g. from nl-BE to nl to en), looking up a key from a resource bundle might require reading multiple resources, which might or might not exist, and it would not be efficient to access all those resources from the browser. Therefore, the i18n REST-service provides a 'resolved' resource bundle, which is a merged view of the resource bundle and its fallback bundles. Getting a bundle is done through this resource: /bundles/{bundle}/{locale} for example: /bundles/org.myproject.mybundle/fr_CH The locale can also be specified in full lower case, and using dash as separator, e.g. fr-ch The resource bundle is returned as a JSON object, allowing easy use from Javascript. [TODO: if values include mixed content, are these part of the json?] #### Getting lists of locales and timezones To help build GUIs to let users select their locale and timezone, the following resources are also available: /info/locales/{locale} /info/locales /info/countries/{locale} /info/countries /info/languages/{locale} /info/languages /info/timezones/{locale} /info/timezones The optional {locale} specifies the locale in which the list should be returned. These resources are used by the locale settings page, which can be seen in action in the kauri-i18n-sample. #### Javascript API Building a message an displaying the text: var kf =$.org.kauriproject.forms;
var msg = kf.Messsage.build(key, args[, type, source])
alert(msg.getText())

Setting a message bundle:

The example below does not work because kf.locale.loadMessages(path) is not implemented in Kauri 0.4 - See http://dev.outerthought.org/trac/outerthought_kauri/ticket/167
In Kauir 0.4 you should use kf.locale.setMessages(messages);

## 12.7 Technical overview

### 12.7.1 Spring Security

If you wish to go beyond the superfical level, you will have to study Spring Security. There is extensive documentation available.

Spring Security comes with is own set of concepts, such as Authentication, SecurityContext, GrantedAuthority, ConfigAttribute, ConfigAttributeDefinition, ObjectDefinitionSource, AccessDecisionManager, etc.

### 12.7.2 Relation between Kauri Security and Spring Security

Kauri reuses Spring Security, with the exception of the Servlet-specific parts. More specifically, this means the concept of the "filter chain" from Spring Security, with its various ProcessingFilters and its matching AuthenticationEntryPoints, is not used within Kauri. We have not modified Spring Security, we reuse the binary release as-is, we just don't use some of its classes.

The Servlet-specific parts in Spring Security have to do with authentication and web-level authorization. Since authentication is split in different stages, even there we can reuse most of Spring Security as-is. The follow table summarizes these stages, and as you can see, it is only the first stage which we had to change for Kauri.

Authentication stage

Spring Security or Kauri Security object responsible

reading authentication information from request or challenging the user.

org.kauriproject.security.AuthenticationMethod (orchestrated by the security filter)

validating the authentication information and returning a populated Authentication token

org.springframework.security.AuthenticationManager

org.springframework.security.userdetails.UserDetailsService

making security information available

org.springframework.security.context.SecurityContext(Holder)

The object-level (AOP) authorization features of Spring Security do their work based on the SecurityContext, and hence all work as expected.

For Web-level security, you can directly access the SecurityContext, or do it through Restlet or JAX-RS APIs, as explained in Security context.

### 12.7.3 Relation between Kauri Security and Restlet security

Kauri does not make use of Restlet's security features, though we do populate Restlet's security context (Request.clientInfo.subject), which should make its authorization filters work.

### 12.7.4 Internal requests

Since internal requests operate within the same executing thread as the launching thread, they re-use the same SecurityContext. No re-authentication happens.

In case an internal request is performed from a daemon thread, outside of the scope of another request, the usual authentication challenging will performed.

# 13 Runtime

The Kauri Runtime is the platform on which Kauri applications run.

It provides the basic infrastructure for:

• managing a set of modules, including their classloading (from a Maven-style repository)
• booting the modules = launching bean containers (Spring)
• allowing exchange of Java services and "REST-services" between modules, and exposing those REST-services remotely via (typically) HTTP

The documentation is still mostly todo, but we have already availabe:

## 13.1 wiring.xml reference

### 13.1.1 Index

<?xml version="1.0"?>
<wiring>
<virtualHosts default="">
<virtualHost name="" hostPort="" hostDomain="" hostScheme="" canonicalUri=""/>
</virtualHosts>

<modules>

<file id="" path="">
<mount name="" path="" virtualHost="" canonical=""/>
<inject-restservice name="" ref="module:service"/>
<inject-javaservice name="" service="" ref=""/>
</file>

<artifact id="" groupId="" artifactId="" classifier="" version="">
<mount name="" path="" virtualHost="" canonical=""/>
<inject-restservice name="" ref="module:service"/>
<inject-javaservice name="" of service="" ref=""/>
</artifact>

<directory id="" path=""/>

</modules>
</wiring>

### 13.1.2 Element description

#### 13.1.2.1 wiring

The root element.

#### 13.1.2.2 virtualHosts

This element is optional.

This element is used in case you want your application to handle requests for different virtual hosts.

Remember that one Kauri Runtime instance usually corresponds to one application. If you have multiple applications that you want to associate with different virtual hosts, you would rather launch these as separate Kauri instances, and use other techniques such as putting an Apache httpd instance in front to distribute the requests to the different Kauri instances.

Attributes:

• default: (optional attribute) the value of this attribute should correspond with the name of one of the child virtualHost elements. If not specified, the first virtual host is used as default. The default virtual host will be used for mount's which specify no virtualHost attribute.

#### 13.1.2.3 virtualHost

Attributes:

• name: a name for this virtual host, needs to be unique. This name is used for internal referencing within the wiring.xml.
• hostScheme: (optional) a regular expression matching the scheme (example: http). Defaul tis ".*".
• hostDomain: (optional) a regular expression matching the domain (example: kauriproject.org). Default is ".*".
• hostPort: (optional) a regular expression matching port number (example: 8080). Default is ".*".
• canonicalUri:(required) this attribute is important in case Kauri needs to build a URI that addresses this virtual host. An example is the use of the publicUri() function in the template language: if the specified restservice is attached to a different virtual host than the one of the current request, then the publicUri() function will need to build a URI including the scheme and authority. Since the host scheme, domain and port are optional and can be specified as regular expressions, we can't derive the canonicalUri from there.

We demonstrate the use of virtual hosts and the purpose of the canonicalUri's using an example.

<runtime>
<virtualHosts default="web">
<virtualHost name="static" hostDomain="static.kauriproject.org" canonicalUri="http://static.kauriproject.org"/>
<virtualHost name="web" hostDomain="www.kauriproject.org" canonicalUri="http://www.kauriproject.org"/>
</virtualHosts>

<modules>
<artifact id="webmodule" ...>
<inject-restservice name="static" ref="staticmodule:files"/>
<mount name="myservice" path="/foo" virtualHost="web"/>
</artifact>

<artifact id="staticmodule" ...>
<mount name="files" path="" virtualHost="static"/>
</artifact>

</modules>

</runtime>

Suppose the webmodule generates a page with a template that creates a link as follows:

<a href="${publicUri('service:/static/downloads/bar.zip')}">bar.zip</a> The purpose of the publicUri() function is to translate the service-URI in the argument to a public URI. The "static" service of the webmodule is provided by the "files" service of the staticmodule, which is mounted on the path "" on the virtualHost static. Since the virtual host is different from the request to the webmodule, the publicUri() function will generate an absoute URI: http://static.kauriproject.org/downloads/bar.zip. #### 13.1.2.4 modules The modules element is the most important part of the runtime configuration: it specifies which modules to launch, and the wiring of the services between them. Modules can be specified in three ways: using file references, using artifact references, or by specifying a directory containing module jars. Each module is identified by a unique id. Within the wiring.xml, this is used for describing the wiring between the modules. At runtime, it may be used for informational or error messages. The order in which the modules are defined is important. It is in this order that the modules will be started. The wiring between the modules needs to be such that there are no forward references to modules which are not yet launched. To put it in another way, the Kauri Runtime is currently not smart enough to figure out the startup order itself. #### 13.1.2.5 file Specifies a module using a file reference. Might be useful sometimes, but in general we recommend to refer to modules as artifacts. Attributes: • id: a unique id for this module • path: path to a module jar file #### 13.1.2.6 artifact Specifies a module using a Maven repository reference. Attributes: • id: a unique id for this module • groupId: • artifactId: • classifier: (optional) the classifier is an additional dimension to identify an artifact. It is not often used. Sometimes it is used for projects which provide jdk-specific artifacts. • version: This version attribute is optional for modules which have org.kauriproject as groupId. In that case, the version of the currently running Runtime will be used as default. #### 13.1.2.7 directory Using directory, you can tell the runtime to launch all the modules jars in the specified directory (non-jar files will be ignored). The modules will be loaded in alphabetical order according to their file name. When using directory, explicit wiring between modules and mounting of restservices is not possible. Attributes: • id: the actual module id's will be a combination of this id and the file name. • path: path to the directory containing the module jars. #### 13.1.2.8 mount Mounts a REST-service exported by a module on certain path of a certain virtual host, to make it available for access from outside the application. Attributes: • name: the name of the REST-service, as specified in the kauri:export-restservice element in the module's spring config. • path: the path on which to mount. We recommend the following: • to mount on the root, specify an empty path "" • to mount on a specific path, start with slash but don't end on it: "/foo/bar" • virtualHost: (optional) the virtual host on which to mount, if not specified the default virtual host is used. • canonical: (optional) boolean true/false. In case the same REST-service is mounted on multiple path, this attribute can be used to define the canonical one. There should be only one mount per REST-service which has this attribute as true. If none is specified as being cannonical, the first one is assumed to be the canonical. The canonical mount is relevant for translation of internal to public links, as is done by the publicUri() function of the template language. #### 13.1.2.9 inject-restservice This is used to wire a REST-service dependency of a module. If a module's Spring config contains kauri:import-restservice elements, then you use inject-restservice to connect the restservice. REST-service dependencies can be connected to REST-services that are exported by other modules, or to arbitrary URIs. Attributes: • name: the name of the REST-service, as specified in the kauri:import-restservice element in the module's Spring config. • ref: reference to a REST-service exported by another module, or an arbitrary URL. • other REST-service: use "module-id:restservice-name" syntax • URL: use "url(...)" syntax Example: Suppose we have two modules called module A and module B. Module A exports (= provides) a REST-service in its Spring config: <kauri:export-restservice name="foo" ref="beanId1"/> Module B imports (= depends on) two REST-services in its Spring config: <kauri:import-restservice name="bar1" ref="beanId1"/> <kauri:import-restservice name="bar2" ref="beanId2"/> Now, let us connect the "bar1" dependency of module B to the "foo" service provided by module A. The "bar2" dependency will be connected to an arbitrary URL. <runtime> <modules> <artifact id="moduleA" groupId="mygroup" artifactId="artifactA" version="1.0"/> <artifact id="moduleB" groupId="mygroup" artifactId="artifactB" version="1.0"> <inject-restservice name="bar1" ref="moduleA:foo"/> <inject-restservice name="bar2" ref="url(http://myservice.org/something/)"/> </artifact> </modules> </runtime> Note that the order of the modules is important: in the ref attribute you can only refer to modules that come before the current one. ##### 13.1.2.9.1 About REST-service types It is possible to declare a type attribute on the kauri:import-restservice and kauri:export-restservice elements. This is optional, but if it is declared on both the import and export of two wired services, then these types need to be equal or an error will be given. The REST-service type is just a free-form string. #### 13.1.2.10 inject-javaservice This is used to wire a Java-service dependency of a module. Note that wiring Java services is optional. Since Java services are typed, the Runtime can auto-wire dependencies on a certain type of Java service as long as there is only one provided service for that type. Attributes: • The service to wire can be identified by using one of the following attributes (not both): • name: the name of the Java-service, as specified in the kauri:import-service element in the module's Spring config. • service: the type of the Java-service • ref: use "module-id:javaservice-name" syntax When performing the wiring for a particular dependency, the Runtime will first see if there is an inject for this particular dependency, identified by name. If that is not the case, it will look if there is an inject for the type of service. If that is not the case, the Runtime will auto-wire the dependency by looking in the global Java service registry for a service of that type. If there would be more than one available, or none, an error will be thrown. ## 13.2 connectors.xml reference ### 13.2.1 Index <connectors> <serverConnector protocols="" address="" port=""> <parameter name="">value</parameter> </serverConnector> <clientConnector protocols=""> <parameter name="">value</parameter> </clientConnector> </connectors> ### 13.2.2 Element description #### 13.2.2.1 connectors This element is used to define the Restlet server and client connectors. From the Restlet docs: A connector in the REST architecture style is a software element that manages network communication for a component, typically by implementing a network protocol (e.g. HTTP). Example configuration:  <connectors> <serverConnector protocols="HTTP" port="8888"/> <clientConnector protocols="HTTP"/> <clientConnector protocols="FILE"/> </connectors> When deploying your application as a Servlet webapp, the server connectors are ignored. #### 13.2.2.2 serverConnector Defines a Restlet server connector. From the Restlet docs: A server connector listens for connections (from clients of any kind), transmits the request to the component that performs the request processing, creates the response and sends it to the client. Attributes: • protocols: a protocol or comma-separated list of protocols. Based on the protocol, a matching connector implementation will be searched. When specifying multiple protocols, an implementation is searched which supports all of the listed protocols. The most common protocol is HTTP. • address: the (IP) address to which to listen. • port: the port to which to listen. Using nested <parameter> elements you can specify implementation-specific configuration options. The server connector implementation that will be used depends on what Restlet finds on the classpath. Kauri includes Jetty by default, so that is what will be used. More information on the available protocols and parameters for this connector can be found in the Restlet documentation. For an example configuration, see connectors. #### 13.2.2.3 clientConnector Defines a Restlet client connector. From the Restlet docs: A client connector initiates communication with a server (of any kind) by creating a request. Attributes: • protocols: a protocol or comma-separated list of protocols. Based on the protocol, a matching connector implementation will be searched. When specifying multiple protocols, an implementation is searched which supports all of the listed protocols. Common client connectors include HTTP, FILE and CLAP. In Kauri you can always make use of the service protocol and the module protocol. These are available without specifying client connectors. For an example configuration, see connectors. ## 13.3 classloading.xml reference <classLoading> <required on-conflict="highest"/><!-- (default)highest|error --> <allowed on-conflict="default"/><!-- (default)dontshare|highest|error --> </classLoading> required/@on-conflict: What to do when a share-required classloader entry occurs with different versions in different modules. • highest: (default) Add the highest version to the common classloader. • error: Log the error and give an exception. allowed/@on-conflict: What to do when a share-allowed classloader entry occurs with different versions in different modules. • dontshare: (default) Don't add to the shared classloader. • highest: Use the higest version in the common classloader. • error: Log the error and give an exception. These properties allow to solve a common source of classloading annoyance: you have a dependency on artifact X, which the runtime decides to put in the shared classloader. But X has a dependency on Y, and some other project also has a dependency on Y, but another version of it. Hence, the runtime decides to put Y not in the shared classloader. Consequence: X does not have access to the classes of Y. The solution before was to add, in the pom(s), an exclusion for one of the versions of Y. This works, but takes effort and is hard to maintain. To decide what is the highest (most recent) version, we need to know how to compare version numbers. The comparison logic assumes version follow the following format: major.minor.revision-suffix in which the minor, revision, and -suffix parts are optional. A missing minor or revision number is the same as it having the value 0. Concerning the suffix: if the two version numbers are equal, and the one has a suffix and the other not, then the one without suffix is considered to be the most recent. This is because the suffix is usually used to indicate some 'in preparation' release: -alpha, -beta, -r22342, -20101023, ... If both versions have a suffix, than currently the only supported comparison is if they have the form '-r{number}', which is the format we usually use for Subversion revision-numbered snapshots. ## 13.4 Spring config reference ### 13.4.1 Introduction #### 13.4.1.1 Purpose The Kauri Runtime provides some extension elements to use in the Spring configuration. The purpose of these elements is to: • give access to the module • declare imported and exported Java-services and REST-services. #### 13.4.1.2 Namespace The extension elements are in the following namespace: http://kauriproject.org/runtime/1.0#springext The typical declarations to include in your Spring config are:  xmlns:kauri = "http://kauriproject.org/runtime/1.0#springext" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://kauriproject.org/runtime/1.0#springext http://www.kauriproject.org/schemas/runtime/springext.xsd"> In case you wonder: the springext.xsd file is not available at the URL specified in the xsi:schemaLocation attribute, and will hence not be downloaded from the network. The URL is only used as an identifier, the schema file is included within the Runtime jars. ### 13.4.2 Element description #### 13.4.2.1 kauri:module Makes available certain module context as beans within the Spring bean container. Syntax: <kauri:module restletContext="restletContext" classLoader="classLoader" handle="module" conf="confRegistry"/> All the attributes are optional. The values of the attributes are the bean names under which to make the beans available, and can be freely chosen. The following attributes are available: • restletContext: the org.restlet.Context object for the current module. Among other things, this is useful to perform internal requests. For example: restletContext.getClientDispatcher().get("module:/static/foo.html") • classLoader: makes the class loader of the current module available. Normally the context classloader will also be set to the module class loader, but it is convenient to have an explicit handle to it • handle: provides access to the API of the current module. The bean implements the org.kauriproject.runtime.rapi.KauriModule interface defined by the kauri-runtime-rapi artifact. • conf: provides access to the configuration registry. See Configuration #### 13.4.2.2 kauri:import-service Imports a Java service (= declares a dependency on a Java service). Syntax: <kauri:import-service service="..." name="..." id="..."/> Attributes: • service: the fully qualified name of a Java interface • name: (optional) a name for this dependency. If not specified, the value of the id attribute will be used as name. The name is useful for explicit wiring, see the wiring.xml reference. • id: the bean name under which to make the service available in the Spring bean container. #### 13.4.2.3 kauri:export-service Exports (= provides) a Java service. Syntax: <kauri:export-service service="..." name="..." ref="..."/> Attributes: • service: the fully qualified name of the Java interface (each export can make only the functionality of one Java interface available). • name: (optional) a name for this export. If not specified, the value of the ref attribute will be used as name. The name is useful for explicit wiring, see the wiring.xml reference. • ref: the name of the bean within the current Spring container which delivers the implementation of the exported service. #### 13.4.2.4 kauri:import-restservice Imports a REST-service (= declares a dependency on a REST-service). Syntax: <kauri:import-restservice name="..." type="..."/> Attributes: • name: name of the dependency. This is also the bean name under which the service will be made available within the Spring container. • type: (optional) a free-form string identifying the type of the service. Unlike Java services, we can't really check the type, but if a type is specified here, and this service is wired to a REST-service from another module which also specifies a type, then the types need to correspond (= the strings should be equal). The type of the bean that will be made available is org.restlet.Restlet. #### 13.4.2.5 kauri:export-restservice Exports (= provides) a REST-service. Syntax: <kauri:export-restservice ref="..." name="..." type="..."/> Attributes: • ref: name of the bean to export. The bean should be of the type org.restlet.Restlet. • name: (optional) name for this export. Used to identify the export when wiring the services in the wiring.xml By default the same as the ref attribute. • type: (optional) see description at kauri:import-restservice. # 14 Configuration ## 14.1 Introduction An application often has a number of configurable items: connection settings for a database or SMTP server, the path to the company logo, connection limits, port numbers, date formatting patterns, passwords for external services (e.g. Google maps API key), and so on. Configurability is useful both for company-internal usage (e.g. different configurations for different deployments) and standard applications installed by many users. As applications become bigger and are composed of lots of modules, each of the modules might have its configuration requirements. Rather than letting developers invent a configuration technique on the spot (property files, system properties, ...), Kauri offers a default solution, bringing both homogeneity and a larger feature set. Some of its features include: • Configuration can be defined per module (it is not one big configuration file), a module can only see its own configuration. If there are multiple instances of the same module, each instance has its own configuration. • One-stop location for configuration: the same configuration system is used for configuring modules (Kauri-provided or user-written) and for Kauri (the runtime) itself. • The configuration data format is a simple tree structure, rather than a flat set of properties. There is a convenient API for accessing the configuration data, a lot easier than, say, an XML DOM tree. • Configuration gets refreshed periodically at runtime, it is possible to register configuration-change listeners. • Configuration inheritance: a module can contain a default built-in configuration, which can be overridden by user-provided configuration. The user can also specify multiple configuration locations, between which fallback will happen, e.g. a 'development' configuration can fallback to a 'common' configuration and finally to the module built-in configuration. ## 14.2 Configuration: first steps TODO ## 14.3 Defining configuration Here we describe the structure of the configuration data. We explain this by how the configuration is defined on the filesystem. Internally, Kauri does not really care the configuration data is stored on the filesystem, other implementations are possible. ### 14.3.1 The configuration directory #### 14.3.1.1 Basics, important terminology All configuration is grouped in a so-called configuration directory. This configuration directory can contain: • one subdirectory per module, containing the configuration files for that module. The name of the directories correspond to the id's assigned to the module instances in the wiring.xml. • one subdirectory named kauri, containing the configuration files for Kauri itself. So an example configuration directory might look like: conf |-- kauri | |-- wiring.xml | -- connectors.xml |-- moduleA | |-- foo.xml | |-- bar.xml | -- foo | -- xyz.xml While on the filesystem we talk of directories and configuration files, the logical configuration model of Kauri uses the terms paths and configurations: • the path is the slash-separated file path below the module directory, and without the ".xml" extension. So in moduleA you can access configurations using the paths "foo", "bar" and "foo/xyz". • a configuration is the configuration data available at some path. • nodes: the complete set of configurations of a module form a tree. Each node in the tree can both contain a configuration and have child configurations. This is because we ignore the ".xml" extension: in our example the node "foo" both contains a configuration (loaded from foo.xml) and has the child "xyz". When starting Kauri, it uses as configuration directory by default the directory named conf in the current directory. You can specify another location through the -c option. #### 14.3.1.2 Configuration inheritance You might want to create multiple configuration directories for multiple purposes: one for development, one for test, and one for deployment. A lot of the configuration of these three cases might be the same. To avoid duplication, you can create a base configuration directory containing everything that is the same, and put in the specific configuration directories only what needs to be different. When starting Kauri, you supply the configuration directories in the order that they should be read by Kauri: [Linux] (using colon as path separator] kauri -c confs/common_conf:confs/dev_conf [Windows] (using semicolon as path separator] kauri -c confs/common_conf;confs/dev/conf Besides this, a module might also have default built-in configuration. Rather than having these defaults in code, it might be useful to have them as configuration files in the module jar. This provides a nice example of what and how to configure. The figure below illustrates the configuration inheritance. ### 14.3.2 The configuration files The configuration files themselves are XML files. They should have the extension .xml, other files are ignored. The XML files have some limitations: • There should be no mixed content. This means no element should have both text and other elements as children. In other words, only leaf elements can contain a value. This value is the content of the text-node of the element, not trimmed: all white-space between the tags is considered part of the value. • The files are parsed namespace-aware, but XML-namespaced elements and attributes are ignored. Other than this, the XML files are form-free, there is no schema to follow. You can invent elements and attributes as needed. ### 14.3.3 Inheritance (merging) between configuration files When using fallback between multiple configuration directories, or fallback to the module built-in configuration, a configuration file in a higher-prioriy location will hide the corresponding configuration file from the fallback location(s). Rather than replacing the file completely, it is possible to have inheritance within the configuration files. Let 's use the terminology base config file and child config file. By default inheritance is disabled. Inheritance is enabled for an element by means of the following attributes: • conf:inherit with as value: • shallow: means that any attributes and any element children that are not present in the child config file are copied from base config file. • deep: same as shallow, but repeat this for each of the (non-inherited) child elements. • none: in case the parent element has the attribute conf:inherit="deep", then you can disable inheritance for certain children by resetting it to none. • conf:inheritKey: if inheritance is enabled through conf:inheritKey, then this attribute determines how the system knows what child elements between the child config file and the base config file correspond. The conf:inheritKey attribute should contain a JXPath expression, that when evaluated on an element, returns a string identifying what makes this element unique among the other children of its parent element (thus not unique among all elements of the file). By default uniqueness is defined by the element name, thus the expression local-name(). Let's illustrate this with an example. Base config file: <?xml version="1.0"?> <conf> <properties> <property key="key1">value1</property> <property key="key2">value2</property> </properties> <param1>value1</param1> </conf> Child config file: <?xml version="1.0"?> <conf xmlns:conf="http://kauriproject.org/configuration" conf:inherit="deep"> <properties conf:inheritKey="@key"> <property key="key2">value2 - altered</property> <property key="key3">value3</property> </properties> </conf> The child config file contains a conf:inherit attribute on its root element, enabling the inheritance. The root element does not have a conf:inheritKey attribute, so the uniqueness is determined by element name: the <properties> element in the child config corresponds to the <properties> element in the base config. The <param1> child is missing in the child config, so it will be inherited from the base config. Since it is a deep inheritance, the inheritance will also be applied to the child elements of the <conf> element: in this case only <properties>. The children of the properties element can not be uniquely identified by name, since they are all called <property>. Rather, their uniqueness is defined by the value of the key attribute, thus we specify the attribute conf:inheritKey="@key". If you want to copy all child elements from the base config to the child config, thus without considering the uniqueness, you can specify an empty expression: conf:inheritKey="". Inheritance also works for attributes, which are of course always uniquely identified by name (XML does not allow two attributes with the same name). So the resulting config after inheritance looks like: <?xml version="1.0"?> <conf> <properties> <property key="key1">value1</property> <property key="key2">value2 - altered</property> <property key="key3">value3</property> </properties> <param1>value1</param1> </conf ## 14.4 Accessing config from Java and Spring ### 14.4.1 Basics The following Java interfaces play a role: • ConfRegistry: provides access to all the configurations (identified by path) of one module. • Conf: represents one specific configuration. It is a simple tree structure, where each node has attributes and either child elements or a value. • ConfListener: this can be implemented to get notified when configuration is updated. The ConfListener is (un)registered via the ConfRegistry. All these interfaces are part of the kauri-runtime-rapi artifact. You can get access to the ConfRegistry or directly to a specific Conf object by injecting it into beans via the Spring container. ### 14.4.2 Getting access to the ConfRegistry You can make the ConfRegistry available as a bean in your Spring container via the conf attribute of the kauri:module tag: <kauri:module restletContext="restletContext" classLoader="moduleClassLoader" conf="confRegistry"/> You can then inject the confRegistry into your beans. The ConfRegistry is useful if you want to load configuration data at runtime, and register ConfListeners. ### 14.4.3 Getting access to a specific configuration If you want to supply a bean with a specific configuration (a Conf object), and you don't need the ConfRegistry, you can directly retrieve it using the kauri:conf tag:  <bean id="myBean" class="com.mycompany.MyClass"> <constructor-arg><kauri:conf path="foo"/></constructor-arg> </bean> Suppose your module has the id "example" (in the wiring.xml), then this would inject the Conf object corresponding to the following configuration file: conf/example/foo.xml ### 14.4.4 Getting access to a specific configuration value If you want to inject simple values into beans, rather than complete configurations in the form of Conf objects, you have two options. #### 14.4.4.1 ConfPlaceholderConfigurer Spring has the concept of PropertyPlaceholderConfigurer's which are used to resolve${...} expressions in the Spring config.

Kauri provides an implementation which works on top of its configuration system. Example:

  <kauri:module restletContext="restletContext" classLoader="moduleClassLoader" conf="confRegistry"/>

<bean class="org.kauriproject.runtime.rapi.ConfPlaceholderConfigurer">
<constructor-arg ref="confRegistry"/>
</bean>

<bean id="myBean" class="java.lang.String">
<constructor-arg value="${foo:email}"/> </bean> The content of the${...} expression is as follows:

${configuration-path:jxpath-expression} The jxpath-expression is just like an XPath expression but works on top of the Conf objects. You can use an expression like "@myAttribute" to get the value of an attribute, or "foo/bar" to get the value of the element bar nested within the element foo. The root element of the configuration has no name and is not addressable. In the configuration XML file, the name of the root element thus has little importance. For the above example, supposing your module has the id "example", you would need the file conf/example/foo.xml containing: <?xml version="1.0"?> <conf> <email>billg@microsoft.com</email> </conf> #### 14.4.4.2 kauri:conf The kauri:conf tag discussed above can also be used to retrieve individual values by specifying a JXPath expression in the select attribute on kauri:conf: <kauri:conf path="configuration-path" select="jxpath-expression"/> You might as well use the ConfPlaceholderConfigurer, but this syntax opens the future possibility of returning lists of things too. ## 14.5 Accessing config from templates You can directly retrieve configuration values within templates, without having to pass them on via a resource class. This is done by means of a conf() function, which takes two or three arguments: conf(path, jxpath-expression) conf(path, jxpath-expression, default) In case you specify no default and the config is not available, the string CONF_UNDEFINED is returned. The conf function can be used within EL expressions, so in a template it will look like this: <html> <body>Hi${conf('helloworld', 'greeting-target')}</body>
</html>

Suppose the module is called 'example', then you would need the following configuration file:

conf/example/helloworld.xml

Containing:

<?xml version="1.0"?>
<conf>
<greeting-target>world</greeting-target>
</conf>

## 14.6 Accessing config from router.groovy

You can get access to the configuration from within the router.groovy by means of an available variable named 'confRegistry' which refers to the ConfRegistry associated to the module.

Inside the router.groovy one can read configuration settings from that by calling the java API of this ConfRegistry interface and the Conf instances it returns.

TODO: synopsis of the most essential methods of those, or refer to javadoc (when published)

String message = confRegistry.getConfiguration("helloworld", false).getChild("greeting-target", false).getValue();

This value can then be used in the groovy builder in any way you'ld want to.  It could be defining parts of paths to match, the name of a kauri-representation to return, a specific version number of a service to call, etc etc

## 14.7 Configuration of the configuration system

The configuration system can be configured by means of itself.

Currently the only parameter is how often the filesystem should be checked for changes to configuration files.

The configuration should be made available at the path kauri/configuration, thus typically in the following file:

conf/kauri/configuration.xml

Example configuration:

<?xml version="1.0"?>
<conf>
<!-- Interval is in milliseconds -->
</conf>

# 15 Temporary Resources

### Introduction

Getting into REST frameworks a lot of experienced web developers are faced with the daunting hurdle of "having no session management" available.
Indeed.  The 'statelessness constraint' (ie. Making sure every request can be handled in total isolation of any previous ones) is forced upon these developers by depriving them from their beloved "Session" object.

## 15.1 Usage

The temporary resources module exposes a Java service and a REST service which allow you to store temporary files, but the Java API and implementation classes can equally be used to create other services (e.g. a service for implementing HTTP-Session-like features or for writing binary blobs to your own backends).

This file upload services can be used to create HTML forms with multipart data, as demonstrated by the Kauri Forms upload-control.

#### Configuration

The tmp dir where the files will be written can be specified via the wiring.xml

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

<modules>
<artifact id="routing" groupId="org.kauriproject"  artifactId="kauri-routing-impl"/>

<artifact id="template" groupId="org.kauriproject" artifactId="kauri-template-service-impl"/>

<artifact id="tmprsrc" groupId="org.kauriproject"  artifactId="kauri-tmprsrc">
<!--  important convention: no trailing slashes since we want to leave them for the child routers -->

<inject-restservice name="store" ref="url(file:///tmp/kauri-temp-upload)" />
</artifact>
</modules>

</wiring>

By default, each temporary resource is kept for 5 minutes. Each time you access the resource (read or write) the resource, the lease timeout is reset to 5 minutes. Yan change the duration by creating a file called conf/tmprsrc/upload.xml, where tmprsrc is the id used in the wiring.xml file.

<?xml version="1.0" ?>
<conf>
<lease-refresh-time>300000</lease-refresh-time><!-- time in milliseconds -->
</conf>

## 15.2 API and Services

There is a Java API and a Rest API for working with temporary resources

#### Java API

To see how the Java service can be used, have a look at the sources for FileUploadRestService.

The 'persistData' method is of notable interest: by calling this method the uploaded file will no longer be subject to automatic cleanup.

#### Rest API

These are the various calls that you can make on the rest service.

 GET / A very basic upload form for posting files to / POST / Creates a temporary resource and returns a JSON structure. [{ "charset":"UTF-8" "mimetype":"application/pdf" "size":176607 "id":"231f5c60254d0f1f44697a6d4c53596543451d13" "filename":"example.pdf" "fieldname":"file" }] GET /{key}/info.json Returns the same info returned by a POST to / GET /{key}/lease.json Returns a JSON structure containing the lease information: { "refreshTime":300000, "expiryTime":1288360200000 } GET /{key}/data/{filename} GET /{key}/data GET /{key} Returns the actual data. PUT /{key}/data/{filename} PUT /{key}/data PUT /{key} Updates the data DELETE /{key}/data/{filename} DELETE /{key}/data DELETE /{key} Deletes the data (the lease is removed)

# 16 Error handling

## 16.1 Different ways of handling error situations

When a resource class encounters an error situation (bad client request, error from backend, ...), there are different ways to deal with it:

1. Produce the complete error response: set the appropriate status code and a response body.

2. Throw an exception. Catching the exception and creating the appropriate response becomes the responsibility of a downstream filter.

3. Set only the response status, but not the response body. The Restlet API allows the status to include a custom description and a Throwable object. Creating the response body becomes the responsibility of a downstream filter.

### 16.1.1 Case 1: resource class produces complete error response

This is interesting if you want to provide very specific error responses. This will especially be useful in Webservice (REST-API) style resources, and less for user-facing web applications.

If a resource class formats all errors it might produce itself, it is completely self-contained without relying on any downstream filters to do further work for them.

### 16.1.2 Case 2: throw an exception

When a resource class talks to back-end classes, these classes will often produce all kinds of exceptions. For example a CMS might produce something like a DocumentNotFoundException or a DocumentAccessDeniedException. Rather than handling such exceptions everywhere in all resource classes, it might be easier to let the resource classes simply ignore this exception, and let it be handled by a downstream filter. This filter can translate the exception to appropriate response status (e.g. "404 Not Found" for the DocumentNotFoundException) and generate a response body.

The exception (or more generally: the Throwable) will have to be catched and translated to an HTTP response body and status code. There are multiple ways to do this:

• Kauri: using the representation builder. One can associate a response body and status code depending on the exception class, explained here.

• JAX-RS: using exception mapping providers. You can implement an ExceptionMapper for each kind of exception you want to handle. These can be used in Kauri like any other JAX-RS provider class, see the jaxRs routing element.

• Restlet: the StatusFilter catches throwables and formats them using the StatusService registered on the Application. In Kauri, you should rather make use of the representation builder, but if you don't use it or don't configure it, the StatusFilter will produce a default response.

### 16.1.3 Case 3: set response status, but no body

Restlet has a Status object which can contain more information than just the status code (the number). It can also contain a custom description and a Throwable object.

Response.setStatus(new Status(Status status, String description, Throwable throwable));

or the shortcut:

Response.setStatus(Status status, String description, Throwable throwable);

Since you can specify a custom description and the cause-throwable, this is in many ways similar to throwing an exception, though you don't have the advantage of the flow control provided by exceptions, you will have to make sure yourself you stop further processing and return from the resource class.

The formatting of the response body can be done by:

• Kauri: the representation builder. You can provide customized responses per status code, explained here.

• Restlet: the StatusFilter. In Kauri, you should rather make use of the representation builder, but if you don't use it or don't configure it, the StatusFilter will produce a default response.

## 16.2 Throwing an exception versus setting response status

When an error condition occurs in a resource class, and you don't want to be concerned with formatting the response body, you have the choice of either throwing an exception or setting the response status.

For such error conditions, you will often have an opinion on the response status code: e.g. it might be a “400 Bad Request”.

Throwing an exception might however provide for easier flow control than setting the response status. But you will often not want to define a custom exception class and corresponding configuration of the downstream filter, but still you want to be able to set the status code, provide a description and possibly a cause-throwable.

For this case, you can use:

• In Kauri: the RestException class [Experimental! Feedback welcome.]

• In JAX-RS: the WebApplicationException class

• In Restlet: the ResourceException class

# 17 Caching of static resources

## 17.1 Introduction

The term static resources is used to describe the static/invariable elements of web pages, such as images.

In modern web sites and applications, web pages often consist of a large amount of resources: images, javascript and css files, ... When these resources can be identified as "static", the addition of "caching directives" can give hints to browsers, proxies and other actors on the Web to allow for optimal caching of the resources. This can dramatically improve loading time of such heavy pages.

## 17.2 Best practices

### 17.2.1 Convention

Gather your module's static resources in a folder static under src/main/kauri .

There you will probably want to create also the following subfolders:

static
|> image   :: static images
|> script  :: static javascript files
|> style   :: static css files

### 17.2.2 Use "static" names for static resources

Identifying static resources is one thing, but then you still have to be careful about naming them. Imagine a web application FooBar, with a nice logo with a green background. Naturally the logo image is a static resource, but what about the name ? A logical choice would be e.g. foobar_logo.png , but you can see this means trouble when you restyle your app and want to use a logo with blue background and the same "logical" name. Such problems can easily be avoided by choosing a more "unique" name.

This is even more important in case of javascript files. When using a javascript utility (e.g. some fancy jquery plugin), you have to ensure that the name unambiguously identifies the utility and the version of it. If not, caching can cause situations in which the same page is working fine for user A but giving headaches to user B who is working with some old cached version. It is useful to also indicate if the javascript file is regular, "packed" or "minified".

Some examples:

• jQuery Tooltip plugin, version 1.3
• jquery.tooltip.1.3.js  (regular)
• jquery.tooltip.min.1.3.js (minified)
• jquery.tooltip.pack.1.3.js (packed)
• foobar logo, blue version
• foobar_logo_blue_24.png (blue, width=24px)

### 17.2.3 Semi-static resources: module resources which can (only) vary per build

Some resources in your module might have a static nature, but can vary per build. Consider, for example, a stylesheet layout.css containing the global layout of your application. You don't want too aggresive caching of this resource, because you might want to change the layout in a future release of your application. Although it's good practice to add the versions to the names of your utitlity resources (see above), doing so for your own mutable code causes too much overhead.

Luckily, Kauri provides a feature for this use case. If enabled, a unique build key is generated during every build, which can also be used in resource paths. Caching will then also consider the build key (as it is a part of the resource URI), which eliminates the danger of lingering old resources when deploying a newly built release.

By convention, we place those resources in the folder static-{build}.key (literally) under src/main/kauri .

## 17.3 Add Caching to kauri module

### 17.3.1 Add caching headers via router.groovy

import java.util.List;
import org.restlet.data.CacheDirective;

builder.router {

def localInSourceMode = inSourceMode;

filter(
uri: "/static",
after : { request, response ->
if (!localInSourceMode && response.getStatus().isSuccess()) {
List<CacheDirective> cacheDirectives = response.getCacheDirectives();
cacheDirectives.clear();
cacheDirectives.add(CacheDirective.maxAge(157680000)); //cache for 5 years (expressed in seconds)
}
}) {
// various static resources cached by the filter:
router() {
// static resources
directory(
uri: "",
root: "module:/static"
)
}
}

...

}

### 17.3.2 Enable usage of semi-static resources

In the configuration below, we will only activate the caching of semi-static resources when kauri is not started in source mode (-s module-source-locations.xml), because during development it's most likely more convenient to be able to modify and test these resources without restarting let alone rebuilding the module.

#### 17.3.2.1 i) router.groovy

Extend the above configuration:

// various static resources cached by the filter:
router() {

String buildKey = localInSourceMode ? "nocaching" : confRegistry.getConfiguration("build", false).getChild("build", false).getChild("key",false).getValue();

// semi-static resources
directory(
uri: "-" + buildKey + ".key/",
root: "module:/static-{build}.key"
)

// static resources
directory(
uri: "",
root: "module:/static"
)
}

#### 17.3.2.2 ii) placeholder conf/build.xml

Create a folder conf under src/main/kauri, in which you create a placeholder file build.xml :

<!--
| This placeholder file is replaced (generated) during the build process.
|
| This placeholder file is required when running this module from source.
-->
<conf/>

#### 17.3.2.3 iii) pom.xml

Add/configure the maven antrun plugin in your pom to generate the build key during the build process.

<!--  kauri module building :: producing a conf/build.xml -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>

<id>KauriStaticResources</id>
<phase>generate-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<mkdir dir="${project.build.directory}/classes/KAURI-INF/conf"/> <tstamp> <format property="build.time" timezone="GMT + 0" pattern="yyyyMMdd'T'HHmmss'Z'"/> </tstamp> <condition property="key" value="${project.version}-${build.time}" else="${project.version}">
<contains string="${project.version}" substring="-SNAPSHOT" /> </condition> <echo file="${basedir}/target/classes/KAURI-INF/conf/build.xml" encoding="utf8"><![CDATA[<?xml version="1.0"?>
<!-- generated by the module build process -->
<conf>
<build>
<id>${project.id}</id> <by>${user.name}</by>
<time>${build.time}</time> <version>${project.version}</version>
<key>${key}</key> <java> <vendor>${java.vendor}</vendor>
<version>${java.version}</version> </java> </build> </conf>]]></echo> </tasks> </configuration> </execution> </executions> </plugin> #### 17.3.2.4 iv) Usage in templates It is convenient to keep the build key of your module in a template variable. You can do this by adding the following in e.g. your base template: <t:init> <t:variable name="fooKey" value="${inSourceMode() ? 'nocaching' : conf('build','build/key')}" />
</t:init>

You can then access the semi-static resources as in the following example:

<script type="text/javascript" src="${publicUri('service:/fooRouter')}/static-${fooKey}.key/foo.util/bar.js"/>

Naturally this example requires that you place the resource bar.js in the folder src/main/kauri/static-{build}.key/foo.util .

# 18 Packaging Kauri applications

While developing a Kauri application, you will typically launch Kauri from the command line. Kauri will by default use the conf directory in the current directory, and retrieve all needed artifacts from your local Maven repository. Because of this, no special packaging is needed to run an application during development, reducing the build-run cycle.

However, at some point, you will have to package your application to distribute it to the users or to put it on some server for deployment.

A packaged Kauri application consists minimally of:

• a configuration directory (containing at least the wiring.xml file)
• a repository containing all the artifacts (jars) used by the project: your own used modules, reused Kauri modules, and their dependencies

Besides that, it can also include logging configuration, application configuration, Java service wrapper configuration, documentation, and any other resources needed by your application.

There are basically two approaches:

## 18.1 Packaged Kauri application

### 18.1.1 What it is

A packaged Kauri application consists of a directory containing everything to run your application, except for Kauri itself.

It has no new concepts or features of its own, it is just a standard method for packaging a Kauri application.

[todo: still needs work: The directory can also contain documentation, installation scripts, and any other resources needed by your application]

A packaged Kauri application can be created by means of the Maven plugin kauri-package-plugin.

### 18.1.2 Usage

#### 18.1.2.1 Add kauri-package-plugin configuration

If you have generated your application using the archetype, then this will already be present. Otherwise, add the following plugin to your (root) pom.xml:

<project>
[...]
<build>
[..]
<plugins>

<plugin>
<groupId>org.kauriproject</groupId>
<artifactId>kauri-package-plugin</artifactId>
<version>${version.kauri}</version> <inherited>false</inherited> <configuration> <confDirectory>${basedir}/conf</confDirectory>
</configuration>
</plugin>

</plugins>
</build>
</project>

Adjust the path to the configuration directory (containing the kauri/wiring.xml file) if necessary.

It doesn't really matter to which pom.xml you add the kauri-package-plugin, since the plugin does not look at the project it is embedded in. It does its work based on the specified wiring.xml file.

#### 18.1.2.2 Creating the package

Execute the following command (in the directory containing the pom.xml):

mvn kauripackage:package

This will create the package in

target/kauri-package

### 18.1.3 Configuration properties

Name

Description

confDirectory

Location of the conf directory, containing the kauri/wiring.xml file.

packageDirectory

Path where the package should be created, default ${project.build.directory}/kauri-package includeServiceWrapper true/false, to indicate whether the service wrapper scripts should be included includeRunInstructions true/false, to indicate whether the HOW_TO_RUN.txt file should be included logConfig Path to log configuration, to be included instead of the default log configuration ### 18.1.4 Executing the plugin as part of build lifecycle If you want to execute the plugin as part of the build lifecycle, use the "attached-package" goal. warning: when adding this in the root pom, be aware that this will run first, as part of the root pom, not after all the modules have been built. Define a separate project with approriate dependencies to force correct execution order. I think this is the only solution, though have not looked too deep into it yet. (what does assembly:attached do?). Anyway, I'd recommend calling it manually for now.  <plugin> <groupId>org.kauriproject</groupId> <artifactId>kauri-package-plugin</artifactId> <version>${version.kauri}</version>
<inherited>false</inherited>
<configuration>
<confDirectory>${basedir}/conf</confDirectory> </configuration> <executions> <execution> <phase>install</phase> <goals> <goal>attached-package</goal> </goals> </execution> </executions> </plugin> ## 18.2 Packaging as a servlet webapp ### 18.2.1 What it is Using the Maven plugin kauri-package-plugin, you can produce a stand-alone war for running a Kauri application. ### 18.2.2 Usage #### 18.2.2.1 Add kauri-package-plugin configuration If you have generated your application using the archetype, then this will already be present. Otherwise, add the following plugin to your (root) pom.xml: <project> [...] <build> [..] <plugins> <plugin> <groupId>org.kauriproject</groupId> <artifactId>kauri-package-plugin</artifactId> <version>${version.kauri}</version>
<inherited>false</inherited>
<configuration>
<confDirectory>${basedir}/conf</confDirectory> </configuration> </plugin> </plugins> </build> </project> Adjust the path to the configuration directory (containing the kauri/wiring.xml file) if necessary. It doesn't really matter to which pom.xml you add the kauri-package-plugin, since the plugin does not look at the project it is embedded in. It does its work based on the specified wiring.xml file. #### 18.2.2.2 Creating the webapp Execute the following command (in the directory containing the pom.xml): mvn kauripackage:webapp This will create the webapp in target/webapp You should be able to deploy this in most Servlet containers like Tomcat, Jetty, and others. You could create a war of this for easy distribution, but for running the webapp, only "extracted wars" are supported. ### 18.2.3 Plugin configuration properties Property Description confDirectory Location of the conf directory, containing the kauri/wiring.xml file. kauriVersion Version of Kauri to include in the webapp, by default the same version as this plugin. webappDirectory Where the webapp directory should be created, default${project.build.directory}/webapp

webXmlLocation

Allows to specify a custom web.xml to be included instead of the default one.

### 18.2.4 Executing the plugin as part of build lifecycle

If you want to execute the plugin as part of the build lifecycle, use the "attached-webapp" goal.

warning: when adding this in the root pom, be aware that this will run first, as part of the root pom, not after all the modules have been built. Define a separate project with approriate dependencies to force correct execution order. I think this is the only solution, though have not looked to deep into it yet. (what does assembly:attached do?). Anyway, I'd recommend calling it manually for now.

      <plugin>
<groupId>org.kauriproject</groupId>
<artifactId>kauri-package-plugin</artifactId>
<version>${version.kauri}</version> <inherited>false</inherited> <configuration> <confDirectory>${basedir}/conf</confDirectory>
</configuration>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>attached-webapp</goal>
</goals>
</execution>
</executions>
</plugin>

### 18.2.5 Limitations

• only artifact-referred modules from wiring.xml are included (not file-based or modules scanned from a directory)
• the webapp should be run 'exploded' or 'extracted', i.e. execution directly from war is not supported (since the Kauri Runtime uses the java.io.File and ZipFile APIs)

### 18.2.6 Background

While this tool is created in the form of a Maven plugin, it does not look at the Maven project it is used in, but does its work based on the specified wiring.xml file.

Everything necessary to launch Kauri and the Kauri-based application is embedded within the webapp. So if you provide someone with this webapp, they have enough to run your application. A Maven-style repository with all needed artifacts is embedded within the webapp.

Technically, the solution consists of two parts:

• a servlet which launches the Kauri Runtime and forwards all incoming requests to the Kauri-hosted Restlet instance.

• a Maven plugin which creates a complete Servlet webapp. This plugin takes as input a wiring.xml, from which it will read the list of modules to include.

Since the HTTP server is provided by the servlet container, any server connectors defined in the connectors.xml will be disabled.

### 18.2.7 Layout of the webapp

WEB-INF
+ lib              contains the kauri-runtime-servlet jar and all its dependencies
|                  (= mainly comes down to the Kauri Runtime and all its dependencies)
|
+ repository       Maven-style repository, contains the jars of the modules listed in
|                  the wiring.xml, and their dependencies
|
+ confs
+ 1             Configuration directory.
+ kauri-auth.xml   (optional)
+ web.xml

# 19 Service wrapper

## 19.1 Introduction

In order to easily start and stop Kauri on deployment systems (often as part of the server boot process), Kauri includes the Tanuki Java Service Wrapper. This provides solutions for both Unix and Windows.

The service wrapper configuration we provide is intended for use with binary Kauri distributions and packaged Kauri applications.

## 19.2 Usage

### 19.2.1 Package your application

Packaging your application is described in detail here. In summary, assuming the kauri-package-plugin is configured in your pom.xml, it is a matter of executing:

mvn kauripackage:package

This will create the packaged application in the directory target/kauri-package.

The packaged application contains configuration files and scripts for the service wrapper. The actual wrapper binaries are part of the binary Kauri release.

### 19.2.2 Modify service-wrapper.conf

In the service directory of the packaged application, you will find a service-wrapper.conf file. Edit this file and adjust the two variables shown below:

# Environment variables
set.default.KAURI_HOME=/home/me/kauri/
set.default.KAURI_APPLICATION_HOME=/home/me/my-packaged-kauri-application

On Windows, use forward slashes in the paths, for example c:/kauri

Use absolute paths in both cases.

The KAURI_HOME variable should point to your binary Kauri installation, for example c:/kauri-{version}

The KAURI_APPLICATION_HOME variable should point to your packaged application, thus the parent directory of the service directory.

### 19.2.3 Try it

First set the KAURI_HOME environment variable:

Linux
export KAURI_HOME=/home/me/kauri

Windows
set KAURI_HOME=c:\kauri

Then launch kauri using:

Linux
kauri-service console

Windows
kauri-service

The console argument for Linux will cause the wrapper to run in the current shell, displaying any output on your shell. This is convenient in case there would be start up problems. On Windows, it is automatically in console mode.

### 19.2.4 Troubleshooting

When the wrapper is not run in console mode, you can find its output in the file:

{packaged application directory}/logs/kauri-wrapper.log

### 19.2.5 Installing the service on Windows

On Windows, you can install and uninstall Kauri as a service using the scripts install-kauri-service and uninstall-kauri-service, which you also find in the service directory.

### 19.2.6 Customizing the wrapper configuration

You can modify the wrapper configuration through the service-wrapper.conf file. This can be useful to change things like memory settings.

Most of the config is imported from a common configuration file that is part of the binary Kauri distribution. It is strongly recommended not to modify that common file, but instead make changes in the service-wrapper.conf file.

# 20 TODO - WRITE UP AND ORGANIZE

## 20.1 Kauri Project/Application Structure

### 20.1.1 The overall structure

A typical Kauri-projects will follow a recognizable structure.  Part of this structure is inherited from the Maven approach, adding onto that a number of web-dev specific parts.   The reasoning behind it boils around logical observations:

• It is the kind of standardization that pays off.
• Code gets read and searched through far more often then it is written.
• All in all developers should put their creativity in what they do, not necessarily in how they do it.

In other words: Even while most of this is optional and configurable, you don't want to needlessly stress out your colleagues by introducing wickedly deviant layouts.

Here is how it looks like.

-- my-application

|-- pom.xml  // the root pom

|-- conf
|-- kauri
|-- connectors.xml
|-- wiring.xml
|-- // further per-module-instance configuration

|-- module-source-locations.properties

|-- main-module
|-- pom.xml     // the module pom
|-- src
|-- main
|-- java
|-- // Java packages and classes
|-- kauri
|-- mockdata
|-- // mockup data structured in JSON files
|-- pages
|-- // pages
|-- spring
|-- // spring configuration
|-- static
|-- // static resources
|-- templates
|-- layout
|-- macro
|-- snippet
|-- resources
|-- // stuff that goes into the jars

|-- (optional) other-modules

The various pom.xml (project descriptor) files and their usage should be clear and comfortable to those using the Maven build-system in so called multi-project (or multi-module) setup.

For convenience this structure (pre-filled with some sample files) can be easily generated using the provided maven archetype.

The specific parts for kauri projects are described below, grouped as follows:

• project declaration
• per module contents
• spring config
• page-routed files
• templates
• static resources
• application testing and configuration

Before getting into that though: some typical questions:

#### 20.1.1.1 What is a project, what are modules?

As the above listing suggests a kauri-project is mainly a group of modules being developed, tested, released (and distributed) together.
These get started out of the need to create and eventually deploy a new web-service or web-site (ie. hosted on one associated domain-name).  In those cases these projects will at least have (at least) one module that will service as the main entry point and dispatcher: typically called the 'main-module'.

The modules however are re-usable components that are designed to be reusable across many projects. In other words: not all modules used in the application under development need to be an actual part of that very project. (They typically can be created inside some other project)

Because of this, eventually projects surface that still group a number of modules, but are not targeted at any specific web-site or -service (and thus don't have a 'main-module').  The grouping of the modules is then practically motivated by some common release cycle, feature-set, or shared ownership.

#### 20.1.1.2 When do I need a new project, and new modules?

As in most modular or component architectures the 'size' (or 'scope') of what makes up a single module is an exercise left to the application developer.  What goes together, what should be split needs your careful consideration, but can't really be outsourced to any body else (let alone a framework).

Development teams typically will take into consideration fundamental questions as completeness and atomicity of feature-sets (the thing, the whole thing and nothing but the thing) but are equally often guided by more practically comparing maintenance and development costs versus perceived opportunity gains in reuse.  These might shift over time.

The two classic reality-check observations to make in this respect are:

• Make something usable first. (only usable things ever get re-used) (The selfish code)
• Reuse is higher if you can throw away (replace) a module rather then find a new use (application) for any given one. (The Reuse-paradox)

The observation is that by seeking to add much wanted 'generic' properties to a single module, people tend to make up possible future use-cases for it that in reality will never occur.  Making it apt for reuse typically adds layers of configuration complexity that bloats the thing and thus makes it a very unappealing candidate for future reuse.  Aptness to reuse is a property of the overall architecture and design, more then it is of the one specific module.  When generalization is able to declare clean-cut interfaces (Separation of Concerns) then a countable higher degree of reuse is achieved: by replacing one module you get to reuse all the others (N+1 >> 1)

### 20.1.2 Various parts of the structure

#### 20.1.2.1 The Project Declaration (root pom.xml)

Maven organizes all build and dependency-management aspects of your project at build time in the pom.xml.
In the typical multi-module approach Kauri proposes this is called the 'root-pom'.  It will hold:

• a clear list of the various modules this project is composed off
• all shared information elements for the various contained modules
(so specific modules just bear a minimal pom.xml while inheriting the common parts)

#### 20.1.2.2 The Various modules and their contents

Each module being produced in a project requires its own subdirectory (holding its proper pom.xml)  This matches the maven approach to let each pom.xml be responsible to produce one artifact.  In the case of kauri-modules these artifacts are classic java jar files with an optional KAURI-INF map in them.

The typical maven approach is to let

 {module-dir}/src/main/java Hold the java classes, organized in packages that will be compiled to {module-dir}/target/classes and included in the root of the jar. {module-dir}/src/main/resources Hold additional 'resources' to be mixed in with the classes mentioned above. {module-dir}src/main/test Hold the junit test classes for build-time tests. (Not to be included in the jar)

To that Kauri adds:

 {module-dir}/src/main/kauri A place-holder for all kauri-specific stuff that gets folded into the jar under the mentioned KAURI-INF folder.

In that folder the following the following elements/positions have a specific function:

• KAURI-INF/spring/**.xml
• Various sping-framework bean-xml files that describe the dependency injection and configuration of the (see the Spring config reference for more details)
• Note that a selection of active bean-XML files can be made through the -p runtime-mode switch when launching the Kauri runtime.
• A list of dependencies that should be loaded for this module to run properly.  (see classloading.xml reference for syntax details)
• Note that this file will automatically be generated during build in most cases.

Next to these, you'll typically find also

• KAURI-INF/router.groovy
• A (groovy) scripted uri-matching dispatcher. (see Routing to understand what it is about, or the syntax reference to learn how to modify and extend)
• KAURI-INF/templates
• A set of xml files that are using the kauri template language to generate parts or structures of page impressions used in your web-site.
• We typically further split them in 3 groups:
• snippets: cut-paste insert-able (xhtml) pieces that occur at various places
• macros: libraries of callable macros that produce (xhtml) pieces based on some logic
• layout: generic page-layou structures that can be inherited from.
• KAURI-INF/pages
• Full page impressions that are often directly mapped on the public uri of your site.  These often are also 'templates' which are offering full page impressions. They typically combine layout-inheritting, snippet-inclusion and macro-calling, so they aggregate the lower level stuff from the templates folder.
• Additionally this folder-name is typically selected for so called ' pages' routing: a flexible mechanism to automatically upgrade chosen file and path-names to uri-template expressions used for matching.  This technique is specially useful for Prototyping

#### 20.1.2.3 Test and Deploy settings (conf, module-source-location.properties,...)

Lastly the project-folder will hold a number of runtime oriented files that allow for easily running and testing the combined modules in their project setting.

• conf/**
• module-source-location.properties
• This file allows to test specific modules in so called source mode, which picks up 'live' changes to various source files holding interpreted languages in the system (ie templates, css, js, groovy, etc ). Since this avoid rebuilding/packaing of the module it can be a great way to speed up your prototyping.

### 20.1.3 Using the archetype

TODO: write up

Things to explain here:

1. cli script windows/lunux to generate project
2. alternative when building from source
3. explanation of the project structure (possibly in other doc)
mvn archetype:generate -DarchetypeGroupId=org.kauriproject -DarchetypeArtifactId=kauri-archetype-prototyping -DarchetypeVersion={version}-dev-SNAPSHOT

## 20.2 CLI reference

still in progress, just a dump from the scripts
(note by mpo) we shouldn't forget to list other scripts in [kauri-home]/bin  next to kauri.sh (runtime) there is also kauri-deploy-repo.sh (install dependencies in m2-repo) and kauri-project-template.sh (run the archetypes)

#### Kauri run/debug actions

run             Run the Kauri Runtime (default)
debug           Run the Kauri Runtime, listed to debugger on port 5005
debug-suspend   Run the Kauri Runtime, suspend for debugger on port 5005

#### Customize startup

You can use the following environment variables to customize the startup

KAURI_CLI_CLASSPATH
additional entries to be added to the classpath
KAURI_JAVA_ARGS
additional options to be passed to the java executable
KAURI_DEBUG_ARGS
can be used to define alternative Java debug arguments
KAURI_DEBUG_SUSPEND_ARGS
can be used to define alternative Java debug arguments for suspended mode

# 21 Kauri hackers

## 21.1 Kauri source code

### 21.1.1 Getting the source

To get the source you have a few different options

• Get the source from the subversion repository: (see also the community page)
svn checkout http://kauriproject.org/svn/trunk kauri-trunk
• Download the source code of a public release from Sourceforge

### 21.1.2 Building the source

Install the basics:

• Sun Java 5 (1.5) or above. Define an environment variable JAVA_HOME pointing to your Java installation. Check everything is fine using:
Unix
$JAVA_HOME/bin/java -version Windows %JAVA_HOME%\bin\java -version • Maven 2.0.x It is a known problem that Kauri does not build on Java 1.6.0_03, due to problems with this Java version which are fixed in later versions. Then execute: mvn install To speed up the build, you can skip the testcases by using the fast profile: mvn -P fast install ### 21.1.3 Running Kauri build from source After building the source, you have two options for running Kauri: 1. Build a binary distribution and run it the same as any downloaded binary Kauri distribution. 2. More likely, run Kauri directly. Kauri will load its jars from your local Maven repository, allowing fast build-test cycles when developing on Kauri itself. Here is an example of how to run Kauri directly after building, using the template sample application: cd samples cd kauri-template-sample [Windows] ..\..\kauri [Unix] ../../kauri.sh In this case, not only Kauri will be loaded from the local Maven repository, but the application modules (in this case the template sample module) and its dependencies will also be loaded from the local Maven repository. ### 21.1.4 Using the archetypes For your convenience, here are the commands to generate projects using the archetypes (adjust version numbers as appropriate): Basic archetype: mvn archetype:generate -DarchetypeGroupId=org.kauriproject -DarchetypeArtifactId=kauri-archetype-basic -DarchetypeVersion=0.4-dev-SNAPSHOT  Prototyping archetype: mvn archetype:generate -DarchetypeGroupId=org.kauriproject -DarchetypeArtifactId=kauri-archetype-prototyping -DarchetypeVersion=0.4-dev-SNAPSHOT And add this option to specify location of the archetype repository: -DarchetypeRepository=<your-repository> ### 21.1.5 Test hints When running tests based on AbstractRuntimeTest, all warning-and-up log messages are logged to the console. If you want to see more logging output when running a testcase, you can easily enable this by passing some system properties, for example: mvn install -Dconsole-logging=debug -Dconsole-log-category=org.kauriproject.i18n The property console-logging sets the log level. The property console-log-category sets the log category for which to enable this level of logging. It is optional to specify this property, if not specified, the log level will apply to the root log category. ## 21.2 Coding style Without getting religious about coding style guidelines, it is pleasant and productive if all code follows more or less the same style. Basically, just do the same as the current sources, and follow the standard Java conventions (ClassNamesLikeThis, static finals in uppercase, etc). Opening braces are on the same line. Use some whitespace, e.g. write x = 5 + 3, not x=5+3. One special point that requires attention: use spaces for indentation, do not use tabs. For Java sources, we use 4 spaces, for XML 2 spaces. For your convenience we provide a formatter-profile with the kauri conventions for java sources which you can import in your IDE (if supported). For Javascript, please follow the Dojo style guide . For CSS, use these coding conventions Please use the following license header: /* * Copyright 2008 Outerthought bvba and Schaubroeck nv * * Licensed 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. */ ### 21.2.1 js guide #### 21.2.1.1 Intro Getting started with Javascript we recommend O'Reilly's book with the Rhino on the cover For people coming from Java, this blogpost might get some common misconceptions out of the way fast. Same is true for this (sit back and relax) "Youtube video of the Google Techtalk "Javascript the good parts" In Javascript land there are a number of techniques that enable to achieve the same thing. This page lists the ones we opt for in the coding of the needed Kauri libraries. #### 21.2.1.2 jQuery.com We have chosen to use the jQuery library as a base for the Javascript development. The parts we'll be using most have been combined in our jQuery crash-course which is mainly a list of direct pointers in to the well-done jQuery documentation. #### 21.2.1.3 Coding techniques ##### 21.2.1.3.1 Cloning a js object jQuery provides a built-in member copy strategy in its 'extend' function. It can be used to make shallow object clones easily by extending a new created object:  var clone = jquery.extend({}, original); ##### 21.2.1.3.2 OOP like inheritance ###### 21.2.1.3.2.1 Prototype definitions A more design-time (and better performing) way to let all object instances of a certain 'type' behave in the same way and share the same properties is achieved by creating actual 'classes' and subclasses. The 'classes' are created through Javascript prototype definitions:  function Base() { ... } Base.prototype.methodX = function(...) { ... }  The usage of prototype is standard Javascript practice. ###### 21.2.1.3.2.2 Subclassing Creating a subclass that inherits from the above is then done like this:  Sub.prototype = new Base(); Sub.prototype.constructor = Sub; Sub.prototype['<super>'] = Base.prototype; function Sub() { ... } Sub.prototype.methodX() { ... } The first two lines are standard Javascript way of working the '<super>' property we introduce so we can call upon super implementations from the subclasses. This last feature is offered through two additional methods: • this['<super.init'>](args,...) • this['<super.call>']('methodname', [args, ..]) The '<super>' property and these last two methods are automatically added to any subclass object created through our own$.inherit() function that takes two constructor-functions as argument, the subclass-function, resp. the superclass-constructor.

With this in place we get constructs like this:

  $.inherit(Sub, Base); function Sub() { this['<super.init>'](...); } Sub.prototype.methodX() { ... this.['<super.call>']("methodX", [...]); ... } ##### 21.2.1.3.3 Namespacing Javascript libraries have to watch out claiming names when being loaded. Since any declared function (like for class-constructors) can conflict on the global scope we recommend: • declaring them in the scope of an inline anonymous function that is passed the jQuery object • and that attaches properties to the jQuery instance (or to the jQuery.fn) The pattern looks like this:  (function($){
$.my =$.my || {};

function Base() {
...
}

$.my.Base = Base; })(jQuery); In this way there could be a$.my.Base which is kept completely distinct from say $.yourown.Base. Kauri introduces in this way the variable:$.org.kauriproject.forms

##### 21.2.1.3.4 Type checking

Javascript provides two techniques for type-of checking:

1. typeof variableName == 'lowercase-string-name-of-object-type'
Recommended use for built in Javascript object structures: Array, Number, String, Date, Object
2. variableName.constructor == namespace.constructorFunctionName
Recommended for own defined classnames.

#### 21.2.1.4 Documenting js

We use jsdoctoolkit.

The generation is triggered in the maven site building by

1. configuration in the pom
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo.javascript</groupId>
<artifactId>javascript-report-maven-plugin</artifactId>
<version>1.0-alpha-1-SNAPSHOT</version>
<configuration>
<sourceDirectory>${basedir}/src/main/resources/KAURI-INF/js/</sourceDirectory> </configuration> <reportSets> <reportSet> <reports> <!-- include the desired reports --> <!-- <report>jslint</report>--> <report>jsdoc</report> </reports> </reportSet> </reportSets> </plugin> </plugins> </reporting> 2. calling maven: mvn site A reference of supported tags can be found here. #### 21.2.1.5 File name convention We choose to keep the js file names all in lower case. #### 21.2.1.6 Testing ###### Debug code The javascript-maven-plugin can be configured to filter out all lines starting with specified character string. <configuration> <!-- .. --> <strip>/* _DEV_ */</strip> <!-- .. --> </configuration> With the current configuration, all lines starting with /* _DEV_ */ will be deleted at build time. This is handy for inserting debug code when using the unassembled code files. ###### jQuery Test Suite Explained in this document. ###### Crosscheck Chrosscheck is able to run js-tests without starting a browser, it's pure java. The next example shows how to load the jQuery and Kauri-form libraries and run a simple test. crosscheck.onSetup(function() { //loads the JavaScript library from the file //paths relative to modules/kauri-forms/kauri-forms-framework crosscheck.addPath('target/scripts/KAURI-INF/public'); crosscheck.addPath('../kauri-forms-jquery/src/main/resources/KAURI-INF/js/'); crosscheck.load('jquery-1.2.3.js'); crosscheck.load('kauri-forms.js'); }); crosscheck.addSuite({ test_jquery: function() { //any variables, objects or properties defined in 'jquery-1.2.3.js' will be accessible here. crosscheck.print("Test loaded libraries"); assertNotNull($, "jQuery not loaded.");
assertNotNull($.org, "namespace 'org' not registered."); assertNotNull($.org.kauriproject, "namespace 'org.kauriproject' not registered.");
assertNotNull($.org.kauriproject.forms, "namespace 'org.kauriproject.forms' not registered."); crosscheck.print("Test ValidationResult"); var errmsg = new$.org.kauriproject.forms.ValidationResult("{0} - {1}", "i18nkey", ["a", "b"]);
assertTrue(errmsg.getMessage() == "a - b");

crosscheck.print("Test jQuery extend");
var newObj = {};
assertNull(newObj.a);
$.extend(newObj, {a: 5, b: 10}); assertTrue(newObj.a == 5, 'object not extended.') } }); To run: java -jar crosscheck.jar [options] [test-file | test-directory]* Options: • help: print help message • hosts: colon-separated list of hosts (ie-6, moz-1.7, moz-1.8) ## 21.3 Subversion configuration ### 21.3.1 Subversion configuration Edit the file ~/.subversion/config Make sure the following line is not commented out: enable-auto-props = yes In the section [auto-props], add the following entries: *.js = svn:eol-style=native *.xml = svn:eol-style=native *.html = svn:eol-style=native *.java = svn:eol-style=native *.txt = svn:eol-style=native *.xconf = svn:eol-style=native *.xweb = svn:eol-style=native *.xmap = svn:eol-style=native *.properties = svn:eol-style=native *.css = svn:eol-style=native *.xsl = svn:eol-style=native *.xsd = svn:eol-style=native *.dtd = svn:eol-style=native *.ent = svn:eol-style=native *.nsh = svn:eol-style=native *.nsi = svn:eol-style=native *.ini = svn:eol-style=native *.conf = svn:eol-style=native *.pom = svn:eol-style=native Additionally one might want to automatically ignore some common IDE project files, by including the line: global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store .classpath .project .settings *.iws *.ipr *.iml In your IDE you just have to import this config file in the section "SVN properties configuration - automatic properties" if available. ## 21.4 Building restlet-snapshot Given the dependency Kauri has on the Restlet project (http://www.restlet.org/) one will every now and then want to check if the Restlet trunk either contains fixes for or else introduces incompatibilities with certain solutions in the Kauri trunk. To check this, one can follow the steps below to add a snapshot-version of the Reslet jars to the local maven repository: The steps below have been bundled up into a shell script available in the kauri-svn at ./tools/restlet-dependency/make_restlet4kauri.sh 1. checkout restlet svn checkout http://restlet.tigris.org/svn/restlet/trunk restlet-trunk --username {guest or tigris user name} When this finishes, you'll see a message like "Exported revision XXXX." Remember this revision number, you need it in the next step. 2. customize build • create a file called custom.properties in Restlet's build directory • maven: true • If you want Kauri-trunk to move to a snapshot version of Restlet, because some specific fixes or new features are needed, then we need a more specific version number than just 'SNAPSHOT'. It is recommended to name such versions "svn<revision-number>". • suffix-maven: -svnXXXX • version-maven: svnXXXX • Replace the XXXX with the revision number displayed after the checkout. • editions: jse • The restlet build creates a lot of file handles. More than is allowed by default on e.g. ubuntu. You can solve this by adding these lines to /etc/security/limits.conf (You can inspect the values that are currently in effect using the command 'ulimit -Hn' and 'ulimit -Hs') yourname soft nofile 4096 yourname hard nofile 10240 • example: # Custom Kauri-friendly build properties # ---------------------------------------- # Used only for the maven distribution # Possible values:${version-minor}-SNAPSHOT, ${version-minor}-M3,${version-minor}.${release-number} #version-maven:${version-minor}-SNAPSHOT
version-maven: svn6565
suffix-maven: -svn6565
# Indicates if the Maven distribution should be regenerated.
maven: true
# Indicates if the final packaging phase should be done.
package: true
# The list of generated editions ("," separated list)
#editions: jse,jee,android,gae,gwt
editions: jse,gae
• The extension org.restlet.ext.servlet is not part of the jse edition (see extension matrix). The above inclusion of the 'gae' edition will build it correctly and provide the maven artifact in the org.restlet.gae group.  Kauri's servlet-deployment system (see tools/kauri-runtime-servlet) needs it.  Alternatively you can build the ext.servlet module separately (just use maven in the right module folder), or force it to be included in the jse edition (this is not a problem since it only depends on already included jars) by adding "jse" in modules/org.restlet.ext.servlet/modules.xml.

1. build Restlet and the maven artefacts
cd restlet-trunk/build
ant rebuild
2. copy those to your local repository
cp -R dist/maven2/restlet-{version}snapshot/* ~/.m2/repository/

After this you should change the version number of the Restlet dependencies in the root pom before making a clean Kauri build: Look in Kauri's root pom.xml for the value of the version.restlet property. Do a find-and-replace over the whole source tree of this version to the new version, svnYYYY to svnXXXX.

## 21.5 Running modules from source in your IDE

### 21.5.1 Running From Source-Directory

The Kauri Runtime allows to work on 'source-directory' layouts of your modules, which avoids building and installing them into full blown module jars in the maven repository just so you can test them.

Here is what you can do in your IDE:

1. Hook up at least the Kauri Runtime project, and configure a java-application-runner to launch the main-class
org.kauriproject.runtime.cli.KauriRuntimeCli
with the arguments:
-c ${project_loc}/conf -s${project_loc}/module-source-locations.properties
-r ${system_property:user.home}/.m2/repository -z  in the context (classpath) of this 'kauri-runtime' project. Note that eclipse will have the${project_loc} property pointing to the location of the project holding the actual file/resource that is active in the IDE when starting the run.
In other words: the actual location of the files will be relative to your module-project-directory

2. So, obviously you should provide a module-source-locations.properties file in your module-project-directory. This file allows to list actual source-locations to use for distinct modules. The file follows the Java property syntax. Keys should be references to the module (group and artefactID, separated by a '!'), while the value holds the source-directory to run from:
groupid!artifactid=/path/to-the-module/

This source-directory your module is expected to stick to the maven2 directory layout. More specifically, it expects:

+ src/main/kauri
spring/*.xml
+ target/classes/

Note that the source-location paths in the property file can contain

1. Relative paths: they are considered relative with respect to the module-source-locations.properties

2. All Java System properties like ${user.home} ### 21.5.2 JUnit "Module" Tests TODO: the same approach could be used to run module-tests vis-a-vis a kauri-runtime launched with references to source-directories. This calls for some test-convenience base-class. ## 21.6 Maven Dependency plugin We included the Maven Dependency Plugin in Kauri, by adding the following in the parent pom.xml: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.0</version> </plugin> This makes it possible to do some analysis of all the dependencies - including the transitive dependencies - of each (sub)project. You can invoke any of the dependency-goals on the root level, or in a single (sub)project: mvn <goal> The most interesting goals for this purpose are: goal description dependency:analyze Very useful ! Analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared. dependency:tree Very useful ! Displays the dependency tree for this project. dependency:list Displays the list of dependencies for this project. Some other plugins do similar analysis, but they don't always seem as accurate as this dependency plugin. Maybe we could use this plugin to generate the classloader.xml files we need in our modules. Maybe dependency:copy-dependencies can be of some help, or otherwise the dependency:list with post-processing ? TODO: Take a look at how they do it @Schaubroeck. ## 21.7 Release Building These are the steps to perform an official Kauri release. All command-line example instructions are for Unix, though should be easily translatable to equivalent operations on other systems. ### 21.7.1 Requirements To do the complete release process, you should have: • commit access to Kauri's SVN •$ svn ls https://outerthought.repositoryhosting.com/svn/outerthought_kauri
##### 21.7.2.1.2 Archetype consistency

The archetype dependencies (versions!) need to be in sync with those actually shipped in the release.
Best to check a simple build of an archetype-generated project against a clean maven repo.

Specially check the restlet-dependency:

$find -name pom.xml |grep -v -P -e "target|\.svn" |xargs grep --colour "version.restlet>svn" ### 21.7.3 Configure Maven settings for Kauri repository access This is important so that the permissions of the deployed files are correct, otherwise you'll have to fix them manually afterward (or most likely, you won't notice it, and the next person trying to deploy might have problems). In the following file (create it if it does not exist): ~/.m2/settings.xml make sure the following server entries are included: <settings> <servers> <server> <id>kauriproject-website</id> <filePermissions>664</filePermissions> <directoryPermissions>775</directoryPermissions> </server> <server> <id>org.kauriproject.maven-deploy</id> <directoryPermissions>775</directoryPermissions> <filePermissions>664</filePermissions> </server> <server> <id>org.kauriproject.maven-snapshot</id> <directoryPermissions>775</directoryPermissions> <filePermissions>664</filePermissions> </server> </servers> </settings> You might want to add directives for your credentials on these servers, through more elements nested in the <server> tag:  <privateKey>/path/to/your/private-key</privateKey> <password>yourPasswordHere</password> <!-- avoid this by publishing your pubkey to the server --> ### 21.7.4 Test if you have sufficient karma and correct settings to actually deploy To avoid entering your password many times during the deployment of the artifacts to the public repository, you should add your public key to the ~/.ssh/authorized_keys2 file on kauriproject.org. If you are unfamiliar with this, stop reading here and find out how to do this. It will take you less time than entering your password a gazillion times. windows users should add the path to the private key (and when using keygenerator: export the private key instead of saving it, I have no idea why but saving does not work in this setting): <privateKey>c:\pathtoprivatekey\mykey.ppk</privateKey> You can verify it works by deploying to snapshot repository: mvn deploy ### 21.7.5 Run Maven release:prepare you should build and install /tools/kauri-genclassloader-plugin separately in windows after preparing release: find -name pom.xml |xargs unix2dos Maven release:prepare performs the steps documented here, most importantly: • updates the version numbers in the pom.xml's to the release version number, and commit them • tag the sources • update the version numbers in the pom.xml's to the next development version, and commit them This does not yet deploy anything. It is strongly recommended (read: official releases: obliged) to do this on a fresh SVN checkout to avoid non-clean situations: rm -rf kauri-all svn co https://dev.outerthought.org/svn/outerthought_kauri/trunk/ kauri-all cd kauri-all Then first do a dry run of release:prepare: mvn release:prepare -DautoVersionSubmodules=true -DpreparationGoals="clean install" -DdryRun=true As long as the effective mvn release:prepare has not been performed, you can back out with mvn release:clean Why we need the preparationGoals parameter: by default the release plugin only executes the 'verify' phase, not install, but Kauri requires the artifacts to be installed in the local repository for Kauri Runtime based test cases to run. Maven will interactively ask for: • the release artifact version numbers: examples: 1.2 (not 1.2.0), 1.2.1 • the tag name: examples: RELEASE_1_2_0, RELEASE_1_2_1 • the next development version numbers: example: 1.2-dev-SNAPSHOT #### 21.7.5.1 Optional: (recommended for official release) test the distro Before actually releasing, assemble a binary release and test that the following work on a clean system: Note: one way to do that is to clone your current directory and replace all the prepared pom's and then perform a distro build. (Don't use that changed setup for actual release building though. $ cd ..; cp -r kauri-all kauri-distro-test; cd kauri-distro-test
$find -name pom.xml.tag -execdir cp pom.xml.tag pom.xml \;$ mvn install; cd dist; mvn assembly:assembly

Then install the build distro somewhere and play around with it.  Things to check:

• check that the samples work (note that -s module-source-properties will expect at least one build)
• check that the maven archetypes work as advertised on a clean system

### 21.7.6 Actual release building

If this finished successfully, you can proceed for real:

mvn release:prepare -DautoVersionSubmodules=true -DpreparationGoals="clean install"

If the above would fail with a build failure like "The svn tag command failed. ... File ... already exists." then do an "svn up" and run the above command again. Apparently this is a problem starting from subversion 1.5.1.

To deploy the artifacts to the repository, execute:

mvn release:perform

to clean up:

cd ..
rm -rf kauri-all

### 21.7.7 Building the distribution

Binary distribution building should be performed once on a Unix-like system and once on a Windows-like system. This is to have files with proper line-endings for both systems. The knowledge about file endings is stored in Subversion, hence starting from a platform-specific SVN-download of the sources gives the best guarantees for appropriate line endings (nonetheless, either release should work on either platform, it is just a matter of polishing).

For the Windows part: don't use Cygwin, but plain Windows. The subversion embedded in cygwin is known to produce *nix line-endings for eol-style:native even when the Cygwin config is set to use DOS line endings. You can keep working from Cygwin, but you should install the windows copy of subversion yourself from http://subversion.tigris.org/project_packages.html

#### 21.7.7.1 Source distribution

Download the tagged sources and zip them:

[Windows]
set version="0.1"
set vtag="RELEASE_0_1"
svn export https://dev.outerthought.org/svn/outerthought_kauri/tags/%vtag% kauri-src-%version%
zip -r kauri-src-%version%.zip kauri-src-%version%

[Linux]
version="0.1"; vtag="RELEASE_0_1"
svn export https://dev.outerthought.org/svn/outerthought_kauri/tags/$vtag kauri-src-${version}
tar zcvf kauri-src-${version}.tar.gz kauri-src-${version}

See instructions further on, after building the binary release, on how to upload these archives to Sourceforge.

#### 21.7.7.2 Binary distribution

Starting from the exports you created for the source distributions, you can build the binary distributions:

[Windows/Linux]
mvn install
cd dist
mvn assembly:assembly

The resulting distribution files can be found in the dist/target folder

Do check the tar.gz contents for 'strange' permissions (Reported on 0.4-RC were rwsrwsrwt on the /*.txt files, but only when extracting with file-roller in gnome).  In general it is best to build zip on windows, and surely tar.gz on linux.

#### 21.7.7.3 Uploading the distributions to sf.net

In total, there are four files to upload: source archive as .zip and as .tar.gz, and binary archive as .zip and .tar.gz.

To upload, login to sourceforge.net and go to 'The Kauriproject'. Select the last tab 'project admin' => 'file manager' where all folders and uploaded files are listed.

Create a new directory for the release by clicking the icon next to the kauriproject folder and upload then the files in this new directory by selecting  'upload' on the folder icon.

### 21.7.8 Post release work

#### 21.7.8.1 Announce

• Send a mail to the discuss mailing-list.
• Follow up with notices on blog, twitter, facebook, relevant sites... (and reference the announce-mail itself)

Don't forget to update possible 'current release' references on the own website kauriproject.org

#### 21.7.8.3 These are generated with maven site plugin

$mvn site-deploy should make you happy. Published site should be in http://kauriproject.org/maven-site #### 21.7.8.4 Docs • Clone the kauri-docs-trunk branch into a snapshot kauri-docs-{release}. • Fix the javadoc: URI path in the skinconf (remove the -dev-SNAPSHOT suffix) • Make a new kauri-docs-{release} site • Update javadoc: URI path in the skinconf to point to the actual uploaded apidocs in the maven-site above • Update the links and release numbers on the http://docs.outerthought.org main home page • Generate a daisy-book for this release • Don't forget to select the correct branch: kauridocs-{release} and language: en #### 21.7.8.5 Update release on daily-builds These are provided through Hudson running at ci.outerthought.org Select the job KAURI_DAILY_RELEASE, choose configure, and change the version number to whatever the new upcoming version number is (matching the one in the pom) ## 21.8 Javascript Maven Plugin #### Javascript Maven plugins • javascript-maven-tools plugin (svn) • compression (Dojo Shrinksafe, YUI compressor) • assembly • strip debugging code • automated unit tests (JsUnit) • code quality check (JSLint) #### javascript-maven-tools We choose the javascript-maven-tools plugin for its rich featureset and active development. ##### Storage Js-files are packed in a jar file and stored in the repository. ##### Dependency Dependencies between javascript artefacts can be forced. The javascript plugin must therefore be declared as an extension in the POM for these artefacts. .. <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>maven-javascript-plugin</artifactId> <extensions>true</extensions> </plugin> .. Other js artefacts can than force the dependency as for java artefacts, but with the type set to 'javascript': .. <dependency> <groupId>..</groupId> <artifactId>..</artifactId> <version>..</version> <type>javascript</type> </dependency> .. ##### Assembly It's possible to combine different js-files in one big file during the build cycle. This prevents the designer to have to include a bunch of javascript files, and still keeps de code easy to maintain. An assembler XML-file describes which files to combine, and in what order. <?xml version="1.0"?> <assembler> <scripts> <script> <fileName>combined.js</fileName> <includes> <include>file1.js</include> <include>file2.js</include> </includes> </script> </scripts> </assembler> The descriptor-tag in the configuration of the plugin points to this file. <configuration> .. <descriptor>${basedir}/src/assembler/myAsm.xml</descriptor>
..
</configuration>
##### Strip debugging code

The pluging provides a goal that strips lines starting with a special token from the code. This is usefull for removing debug code. The token can be set in the plugin configuration with the strip-tag.

##### Compression

There are three compressors included: Dojo Shrinksafe, YUI compressor and JSMin. JSMin is de deafult one used, this can be changed in the plugin configuration by the compressor-tag. The possible values are: 'shrinksafe', 'yahooui' and 'jsmin'.

#### Configuration

Compression:

Tag

Default

Description

optimizationLevel

9

Optimization level, from 0 to 9

languageVersion

130

JS Language version (130 for JS 1.3)

compressor

jsmin

The compressor to used. Either "shrinksafe", "yahooui" or "jsmin" for default compressor, or a custom one provided as an artifact in repo org.codehaus.mojo.javascript:<xxx>-compressor.

skipStats

false

Don't display compression stats

compressedDirectory

${project.build.directory}/compressed The output directory of the compressed javascript files. buildDirectory${project.build.directory}

The output directory of the compressed javascript archive.

finalName

${project.build.finalName} The filename of the compressed js file. classifier compressed Classifier for the compressed artefact scriptClassifier Optional extension for the compressed artifact. Example "compressed" scriptsDirectory${project.build.outputDirectory}

The intput directory for the source javascript files.

Strip debugging code:

Tag

Default

Description

strip

A special token to recognize lines to be removed from scripts (debugging code).

Assembler:

Tag

Default

Description

sourceDirectory

${basedir}/src/main/javascript Location of the source files. outputDirectory${project.build.outputDirectory}

The output directory of the assembled js file.

descriptor

src/assembler/\${project.artifactId}.xml

Descriptor for the strategy to assemble individual scripts sources into destination.

descriptorFormat

default

Descriptor file format ("default" or "jsbuilder").

#### Custom Kauri build

Since there's no official build available for this plugin, and because no other version than SNAPSHOT exists, a custom build was made with the build date included. No noticeable updates were made to the source since then.

## 21.9 Kauri Forms Source Code Guide

TODO

list of source files and their responsibility

javascript extension and inherit system

build system (aggregation)

# 22 Glossary of Terms

## 22.1 Terms in use

### 22.1.1 archetype

A template for generating new Kauri projects. It frees you from the work of having to create the basic directory structure, build files, etc. See also Creating a Kauri project.

### 22.1.2 authentication method

A way for verifying the identity of a user. According to Wikipedia, it is the act of establishing or confirming something (or someone) as authentic. Some typical authentication methods are basic, digest, form-based and client certificate authentication. Sometimes also referred to as an authentication scheme or authentication mechanism.

### 22.1.3 element (XML)

An element in XML is most common kind of markup in an XML document. An element can contain content, typically text or other elements. There are two syntactical forms:

• delimited by a start-tag and an end-tag: <foo>...</foo>
• in case the element is empty, it can be written as <foo/>

### 22.1.4 JAX-RS

JAX-RS is the Java API for RESTful Web Services. It is mainly about how to implement resources using Java objects, and defines a set of Java annotations for this purpose. The specification (which is quite compact and readable) can be found at java.net.

### 22.1.5 module

A module is the unit of modularization within the Kauri Runtime. A live Kauri Runtime instance consists of a number of modules, wired together to use each other's services, some of which are also exposed externally (over HTTP). Physically, a module is a self-contained archive containing code, resources and configuration (classpath, bean container). A module is less than a Servlet war, as a typical application consists of the combination of multiple modules. A module is similar to a bundle in OSGi.

### 22.1.6 module protocol

The module protocol (or URI scheme) is used by a module to access resources contained in the module. When a module is packaged as a jar, then the URI "module:/test.txt" will resolve to the file KAURI-INF/test.txt contained in the module jar.

### 22.1.7 resource class

A resource class is a Java class which implements a corresponding Web resource. A Web resource is the intended conceptual target of a hypertext reference (Fielding). From a developer point of view, a resource class contains the code which is executed in response to a Web request. In Kauri, resource classes are either implemented using the standard JAX-RS API or using the Restlet-specific org.restlet.resource.Resource API.

See here.

### 22.1.9 Restlet

Depending on the context, the term Restlet can refer to:

### 22.1.10 REST-service or restservice

A module can provide (or export) REST-services to expose its functionality, and depend on (or import) REST-services to use external functionality. A REST-service is a service through which you communicate using the REST uniform interface. On a Java-technical level, a REST-service is an org.restlet.Restlet. Next to REST-services, a module can also use Java-services to expose or use functionality.

### 22.1.11 service protocol

The service protocol (or URI scheme) is used by a module to address its REST-services. These can be any of the imported or exported REST-services. The syntax is service:/restservice-name/path. The service protocol can be used in various locations: the routing, the templates, ... Technically, they can be resolved through org.restlet.Context.getClientDispatcher().

### 22.1.12 source mode

A shortcut to refer to a Kauri Runtime started with the option (-s) to load modules directly from your (Maven-style) source directory layout. In this mode, changes to non-Java classes are automatically picked up without need to restart Kauri, and even without need to run Maven, since resource files are directly read from the 'src' directory, rather than the 'target' directory. See docs.

### 22.1.13 URI template

A URI template is used for constructing or matching URIs. In general a URI template is a string containing variables between { and }, for example /users/{id}. The term URI template is re-used by different technologies, which always use the basic {variable} notation, but each have their own specific features:

• Restlet: supports URI templates through its Template class, supporting both construction and matching. It is mostly used for URI matching in the Restlet Routers. Restlet allows to programmatically set options for the variables, for example to specify what kind of characters should be matched by a variable.
• Kauri: supports an extended syntax for the Restlet URI templates, allowing to specify the options for the variables directly in the syntax.
• JAX-RS: cfr. the @Path annotation, allows to specify regular expressions for variables: {var:regex}
• the Internet-Draft URI template specification, which is about URI construction.

### 22.1.14 wiring.xml

The wiring.xml is Kauri's most important configuration file: it describes what modules to load and how to wire them. The wiring.xml is necessary to start Kauri, without it, Kauri does not know what modules to load, and thus would have nothing to do. See also the wiring.xml reference.

# 23 Upgrading from 0.3

[TODO: change the version properties in your pom's for Kauri, Spring, ...]

[TODO: 0.3.0 to 0.3.1: {x:**} syntax from representationbuilder config changed]

[TODO: incompatible changes in Restlet: Move of representation classes from org.restlet.resource to org.restlet.representation: ajdust your imports]

### Forms

Control event listeners should now be registered directly on the control instead of on getElement(). Mail.

### Representation builder

For exception formatting, there is no kauri_throwable_chain available anymore in the view data. This is not needed anymore as the template language now supports recursive macro calling.

### Templates

A variable (parameter) "request" containing the Restlet request object is now automatically made available. If you previously set this yourself, you don't need to do this anymore. If there is an existing parameter named "request", it will be overwritten.

### DBResources

classpath:org/kauriproject/dbresources/jpa/jparesources-beans.xml

has been renamed to

classpath:org/kauriproject/dbresources/jpa/services.xml`
 1 The first extension is the public one, the second extension serves for associating with appropriate editors on your system.