blob: 44d5877d9b41ae22bc5bbd8fd9be3e64bc0c7c63 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="sample-application">
<title>A Sample Application</title>
<para>
The @snaps.product.name@ Zip file comes with a sample application that you may have already deployed to verify
your @snaps.product.name.short@ install. In this chapter you will look at it in more detail to see how an
application can be composed and see all the Snaps features in action.
</para>
<section id="sample-application-structure">
<title>Structure of the sample application</title>
<para>
The application is very simple, it consists of just a front end, composed of four bundles, a host with
three Snaps.
</para>
<para>
<imagedata fileref="images/sampleApp.png"/>
</para>
<para>
The host and three snaps show their <literal>Snap-ContextPath</literal>s. The Cat and Dog snaps both
contribute content while the final snap just contributes styling information in the form of <literal>css</literal>
files. The following sections look at each of these in detail.
</para>
</section>
<section id="sample-application-host">
<title>The Host bundle</title>
<para>
This bundle is very simple with no Java code. It defines the Snaps filter in its <literal>web.xml</literal>
just as you have seen in the <link linkend="using-snaps-configuring-the-host">Using Snaps</link> section. The
menu bar uses the taglibs support to render links for each registered Snap.
</para>
<programlisting>
<![CDATA[<ul>
<li><a href="<c:url value="/"/>">Home</a></li>
<snaps:snaps var="snaps">
<c:forEach var="snap" items="${snaps}">
<c:if test="${snap.contextPath ne '/styles'}">
<li><a href="<c:url value="${snap.contextPath}${snap.properties['link.path']}"/>">
${snap.properties['link.text']}</a>
</li>
</c:if>
</c:forEach>
</snaps:snaps>
</ul>]]>
</programlisting>
<para>
This is very similar to an example you have already seen. It puts the links in a list and adds a link at the
beginning to return to the host. The properties it is referencing are located in the snaps themselves at
<literal>/META-INF/snap.properties</literal>.
</para>
</section>
<section id="sample-application-new-content">
<title>Adding New Content</title>
<para>
If you now deploy both the Dog and Cat snaps, two new items will appear on the menu bar, each providing content
from their respective snaps.
</para>
<para>
<imagedata fileref="images/sampleCat.png"/>
</para>
<para>
If you look at the Cat page you will see it is also displaying some properties. The Cat Snap is a little more
complex, it has it's own <literal>DispatcherServlet</literal> defined in its <literal>web.xml</literal> and a
controller defined using annotations. If you look at the controller code you will see where these two properties
come from.
</para>
<programlisting>
<![CDATA[@Controller
public class CatController {
@RequestMapping("/meow")
public ModelAndView cat(HttpServletRequest request) throws IOException {
URL host = request.getServletContext().getResource("host:/WEB-INF/sample.properties");
Properties host_props = new Properties();
if(host != null){
host_props.load(host.openStream());
}
URL snap = request.getServletContext().getResource("/WEB-INF/sample.properties");
Properties snap_props = new Properties();
if(snap != null){
snap_props.load(snap.openStream());
}
return new ModelAndView("index").addObject("host", host_props.getProperty("some.property"))
.addObject("snap", snap_props.getProperty("some.property"));
}
}]]>
</programlisting>
<para>
There are two properties files called <literal>sample.properties</literal> located at the same path within both
the Cat snap and the host. Each contains a property called <literal>some.property</literal> but with distinct
value. Looking at the code above you can see the <code>host:</code> prefix being used to ensure the first lookup
only looks in the host and skips the snap. These values are then placed in the Model for the JSP page to render.
</para>
</section>
<section id="sample-application-dynamic-styling">
<title>Re-styling</title>
<para>
Finally the Blue styling snap shows how Snaps can be used in other ways. Deploying this will cause all requests
to <literal>/styles</literal> to be redirected and the application will change in appearance but not content. All
this happens without re-deploying the host bundle, although you may need to do a full refresh to clear your browser's
cache.
</para>
<para>
<imagedata fileref="images/sampleBlue.png"/>
</para>
This is the same page as before, being rendered by the host and the Cat snap, but with the style information now coming
from the Blue snap.
</section>
</chapter>