Quantcast

A Closer Look at Simple Components in Apache Tapestry

(No Ratings Yet)
Loading ... Loading ...

If you're new here, you may want to subscribe to my RSS feed. So that you can read the latest updates about Web2.0 tools, Making Money Online, Tips in SEO, Ajax and many more. Thanks for visiting ProgramimiCOM!

In the previous article, we took a look at some of the components that are used most often in Tapestry applications, and learned some important concepts related to them. At the end, we found that we needed three components for our example application. In this article, we will configure those components. We will also learn how to disable caching.TextField component

Adding a component to the Home page template is very easy. Just mark the already existing text box with a jwcid attribute and name it accordingly, perhaps like this:

<input type=”text” jwcid=”secretWord”/>

The most important part is to define the component in the page specification. Insert into the Home.page file, between <page-specification …> and </page-specification> tags the following piece of XML:

<component id=”secretWord” type=”TextField”>

<binding name=”value” value=”theWord”/>

</component>

The id attribute mentioned here must match the name we’ve used for the corresponding jwcid attribute in the page template, ‘secretWord’. The type attribute defines that this is a TextField component, exactly as we wanted.

The <binding> element is exactly what creates that global communication channel between the component and the page class. Its name=”value” attribute states that the piece of information that is communicated along the channel should be understood as a value for the component, while value=”theWord” tells us which methods on the page class to invoke in order to get or set the value associated with the component.

You have probably already guessed that ‘theWord’ is treated as an OGNL expression. It tells Tapestry that to get the value for the component it should use the getTheWord() method on the page class, while to set the value after it was received from the user, the setTheWord() method should be used.

Obviously, we don’t have any of these methods yet. In fact, we are also going to need a variable to store the value itself. The traditional path to follow to provide all this would be to create a private class member in the Home class:

private String theWord;

and then two public methods to access it:

public String getTheWord() {

return theWord;

}

public void setTheWord(String theWord) {

this.theWord = theWord;

}

However, this traditional approach has two down sides. First of all, it is quite boring to write all the predefined, truly “boilerplate” code, while it is in the spirit of Tapestry to avoid any boredom. And second, we would have to provide some additional maintenance for this private class property, which means even more code. Let me delay the detailed explanation until the next article – we have already had enough theory for today.

Right now, I will just show you the preferred way of defining a property of a page class in Tapestry. All we need in our case is this single line of code:

public abstract String getTheWord();

See, Tapestry is clever enough. When it notices a line of code like this one, it understands that we need a property named theWord. The type of that property is String, as can be guessed from the return type, and since the getter method we have provided is abstract, we trust Tapestry to create anything it will need to maintain the property.

You will see this happening quite often as we learn Tapestry: instead of hard coding something boring or verbose we shall just tell Tapestry what exactly we need, and that thing will be provided for us. For now, just add the above abstract getter to the Home page class.

Before going on to the Form component, let me show you another binding that can be used with the TextField. It is not required, but I have two reasons for doing it. First, I will be able to show you that there can be more than one binding. Second, you’ll see that some bindings are used to simply configure the component. Let’s modify the specification for the secretWord component to look like this:

<component id=”secretWord” type=”TextField”>

<binding name=”value” value=”secretWord”/>

<binding name=”hidden” value=”true”/>

</component>

This new binding simply specifies that the text box should be displayed as a password field, i.e. any input should not be displayed but masked. This is a secret word, after all!

Now, let’s take care of the Form component, to enclose the TextField.

Form component

To define this component in the Home page template, simply mark the existing HTML form with a jwcid attribute and give the component a descriptive name, like so:

<form action=”" jwcid=”secretWordForm”>

The next step is to configure the Form component in page specification:

<component id=”secretWordForm” type=”Form”>

<binding name=”listener” value=”listener:onWordSubmit”/>

</component>

Let’s concentrate on the <binding> element as everything else should be clear for you now.

The name=”listener” attribute says that what we are specifying in this binding is a listener. Listener can be understood as a special method of the page class, which is invoked when an event associated with this listener happens. Here the event is the form submission.

The value=”listener:onWordSubmit” attribute provides the name for the listener method. Note the ‘listener’ prefix. You are already familiar with two prefixes, ‘ognl’ and ‘literal’, so here is the third one for your collection. It is used to tell Tapestry that what follows is not an OGNL expression and not a literal value, it is rather the name for the listener method to be invoked when the form is submitted.

All that is left is to provide the listener method in the Home page class. There are a few ways in which a listener can be written, but again, let me delay the complete explanation until the next article. Right now, we shall create a very simple listener like this:

public String onWordSubmit() {

return “Secret”;

}

This is an ordinary public method, and its only “special feature” is that it returns a String containing the name of the next page to show. Normally, before returning this name we would do something, say, manipulate some data, but for now let’s just leave everything very simple.

We can already run the new application and see how it works. Hit the F6 key, and NetBeans will compile, package and deploy everything for you. The Home page will appear, looking exactly like its mock up, but if you try to enter a word into the text box, it will be masked, like a password. Finally, press the Submit button, and you will see the Secret page – i.e. its mockup with both views shown as we didn’t add any functionality for that page yet.

Phew… I feel like this article is becoming too lengthy, and there are still a lot of things to discuss and play with. [In fact, we had to break it into two parts. –Ed.] Let me take a break here and continue the general discussion in the next article.

Source Code

To wrap up what was already done, here is the source code for the template, specification and class for the Home page:

Home.html:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>

<html>

<head>

<title>Guess the Word</title>

</head>

<body>

<h2>Guess the Word</h2>

<form action=”" jwcid=”secretWordForm”>

Enter the secret word:

<input type=”text” jwcid=”secretWord”/>

<input type=”submit” value=”Submit”>

</form>

</body>

</html>

Home.page:

<?xml version=”1.0″?>

<!DOCTYPE page-specification PUBLIC

“-//Apache Software Foundation//Tapestry Specification 4.0//EN”

“http://tapestry.apache.org/dtd/Tapestry_4_0.dtd”>

<page-specification class=”com.devshed.tapestry.guesstheword.Home”>

<component id=”secretWord” type=”TextField”>

<binding name=”value” value=”theWord”/>

<binding name=”hidden” value=”true”/>

</component>

 

<component id=”secretWordForm” type=”Form”>

<binding name=”listener” value=”listener:onWordSubmit”/>

</component>

 

</page-specification>

Home.java:

package com.devshed.tapestry.guesstheword;

import org.apache.tapestry.html.BasePage;

public abstract class Home extends BasePage {

 

public Home() {

}

 

public abstract String getTheWord();

 

public String onWordSubmit() {

return “Secret”;

}

 

}

However, there is one technical issue we need to care of before leaving.

How to disable caching

Tapestry strives to be as efficient as possible, so it caches page templates and specifications in order not to reload them every time when they are needed. This is a very useful behavior in a production application; however, during development it can become annoying, as we might not immediately see the changes we have just made to the page.

Thankfully, there is a way to ask Tapestry not to cache any pages in our development environment.

In NetBeans, click on the Tools menu and then choose Server Manager. In the Server Manager dialog, choose the Platform tab and then enter into the VM Options text box the following option:

-Dorg.apache.tapestry.disable-caching=true

The result should look like this:

image005.jpg

Close the dialog, and that’s it. If however Tomcat was running when you applied the setting, you will need to restart Tomcat.

To do this, click on the Runtime tab on the left side of NetBeans IDE and expand the Servers node to see the Bundled Tomcat node:

image0061.jpg

Right click on the Bundled Tomcat node and choose Restart. As simple as that.

What comes next

In the next part of this tutorial I will explain in more detail how properties of the page class can be defined in Tapestry and when one way is more preferable than the other.

Next we are going to have a more detailed look at the listener methods as there are three ways to write them.

It might also be useful for the future to get familiar with the two ways of submitting the form.

Finally, we shall complete the GuessTheWord project and become familiar along the way with If, Else and PageLink components.

See you in the next article then.

by Alexander Kolesnikov

Introducing Simple Components in Apache Tapestry

(No Ratings Yet)
Loading ... Loading ...

In the previous article, you witnessed the interplay between a Tapestry page and its components (granted, we had only one simple component there, but you get my point). Page class, when rendering its page, finds any components mentioned in the template and asks those components to display themselves, as they know better how to do that. Components, in their turn, might need some information to display themselves, and they ask the page class to provide the necessary information by calling some of its methods.

How to configure components, their type, which methods of the page class to call to provide them information – all these details are provided in the page specification.

Today you are going to see more components of those most often used in Tapestry application, and you are going to learn some important concepts related to them. First of all, we shall experiment with that very simple Tapestry application created in the previous article, but then we shall start working on another project, which is slightly more complex.

Implicit components

Launch your NetBeans and open the FirstTapestry project we’ve created in the previous article. Let’s concentrate on how we have configured the Insert component used in this project.

First of all, we used a standard <span> HTML element and marked it as a Tapestry component:

<span jwcid=”now”>…</span>

We have also given a name to this component, now. If you don’t like this name, use any other name; there’s no problem with that.

And then, to define what this component actually is, we have configured it in the page specification:

<component id=”now” type=”Insert”>

<binding name=”value” value=”currentDate”/>

</component>

This is what we did in the previous article. There is, however, an alternative way to achieve the same goal. Let’s change the Home.html template to look like this (I am showing only the line that should be changed):

<p>Now is <span jwcid=”@Insert” value=”ognl:currentDate”>8:27, the 1st of April 2007</span>.</p>

Then remove the Insert component configuration from Home.page, and leave the page specification empty:

<?xml version=”1.0″?>

<!DOCTYPE page-specification PUBLIC

“-//Apache Software Foundation//Tapestry Specification 4.0//EN”

“http://tapestry.apache.org/dtd/Tapestry_4_0.dtd”>

<page-specification class=”com.devshed.tapestry.first.Home”>

 

</page-specification>

Press F6 to run the project and make sure that it works exactly as before.

 

In some cases, after making a change in an HTML template, you will not see your change immediately reflected in the running application. This is because, by default, Tapestry caches page templates for higher efficiency. See the How to disable caching section in the next article for an explanation of how to change settings and make your application more responsive during development.

Let’s see what we have done here. In the page template, instead of giving a name to our one and only component, we have directly specified its type: Insert. The ‘@’ symbol in front of the component type tells Tapestry that this is a type of component and not just a name that we have chosen for it.

Now the page class will know immediately what kind of component we have used. But which method should it invoke to provide data to this component? The piece of information which was previously contained in the <binding> element of page specification:

<binding name=”value” value=”currentDate”/>

has turned into an additional attribute of <span> element:

value=”ognl:currentDate”

Clearly, there is no need to provide any details in the Home.page file anymore, so we have left the page specification empty.

This way of configuring Tapestry components (everything moves to the page template, nothing is left for the page specification) is termed “an implicit component” as opposed to the “declared component” we’ve dealt with before.

However, I hear you asking the question: why in one case did we use “curentDate”, while in the other case we used “ognl:currentDate”? And what exactly does this ‘ognl:’ prefix mean?

What is OGNL?

“OGNL stands for Object-Graph Navigation Language; it is an expression language for getting and setting properties of Java objects” – this is a quotation from the OGNL project website (http://www.ognl.org/).

Different software projects, including Tapestry, use OGNL to simplify the basic operations of accessing properties of Java classes.

When in a page specification we write something like value=”currentDate”, Tapestry automatically treats whatever it finds inside of double quotes as an OGNL expression and asks OGNL to handle it. According to the rules of OGNL, ‘currentDate’ means that the getCurrentDate() method should exist somewhere in the page class – so Tapestry goes and invokes this method. Or it complains, if you forgot to write it. This is how it works in page specifications.

In page templates however, if you write value=”currentDate”, the contents between the double quotes are treated verbatim, as a literal value. Try to make this change and see what happens. Instead of going to the page class and invoking an appropriate method, Tapestry will simply use the ‘currentValue’ string as a value for the Insert component, so instead of the current date and time you will see:

Now is currentDate.

That’s not very illuminating. So we have to tell Tapestry that ‘currentDate’ should be treated as an OGNL expression, and we use the ‘ognl:’ prefix to do this.

By the way, you are free to use the ‘ognl:’ prefix in page specification too:

<binding name=”value” value=”ognl:currentDate”/>

This will work perfectly well, however it is not required as OGNL is the default option here. If, however, you wanted to provide a literal value in a page specification, you would have to use either the ‘literal:’ prefix:

<binding name=”value” value=”literal:my birthday”/>

or single quotes inside of double quotes:

<binding name=”value” value=”’my birthday’”/>

This was a very simple example of an OGNL expression. However, imagine that a method called on the page class returned some Person object. Say, this object had an Address object as its property, and what we actually wanted to display is the town property of the Address object. In Java code, to obtain the desired value, we would write something like:

person.getAddress().getTown()

In OGNL this looks simpler:

person.address.town

This is again a basic example, but as we advance to the more involved parts of this tutorial, you will see some more complicated and powerful examples of OGNL expressions. For now, to complete our first acquaintance with OGNL, let’s do a simple experiment.

Add another method to the Home.page class:

public String getSomeMessage() {

return “. Welcome to Tapestry!”;

}

Then change the OGNL expression we use to obtain a value for our Insert component to be:

“ognl:currentDate + someMessage”

Run the application and you should see something like this:

image0011.jpg

To resolve the expression we have passed to it, OGNL invoked two methods on the page class, getCurrentDate() and getSomeMessage(), and put the results returned from them together. The resulting string was used as a value for the insert component. Here you can already see that OGNL can be quite helpful.

But let’s return to the two ways of defining a component: explicit component and declared component. Which approach is better? Well, it depends, first of all, on the component itself, but also on your personal preferences.

Implicit vs. declared components

You have seen just one Tapestry component so far, so this discussion will be unavoidably abstract, but I still think it will be useful to prepare you to understand what will come later.

The obvious advantage of the implicit components (fully described in the HTML template) is that you can see everything related to this component in one place: how and where it is used on the page, what its type is and what it is bound to in the page class. You don’t have to look into another file or page specification to find out any additional information.

The obvious disadvantage of this approach is that if a component has several bindings (in some cases there can be three or even more bindings), the page’s HTML code gets cluttered with weird nonstandard attributes and maybe also complex OGNL expressions.

The advantage of the declared components is that you have them listed all neat and orderly in the page specification. Having multiple bindings is not a problem and complex OGNL expressions are welcome here.

The disadvantage of the declared components is obvious when you have a component without any bindings (you will see one such component soon), or with only one simple binding. The proper specification for such a component will be more verbose than its implicit declaration.

In practice, I find myself combining the two approaches. When a component has no bindings, I define it implicitly. When it has more than one binding, I declare it in page specification. In the case of simple components, like Insert, I might define them either way depending on the complexity of the page design. If the page is large and its design is complex, I will prefer declared components over implicit ones.

It is the time now to have more practice and to meet more components. Let’s create another project, this time having two Tapestry pages.

GuessTheWord project

Create a new Web Application project in exactly the same way as we have created the first project, but give it a different name – say, GuessTheWord.

Add to the project the tapestry41 library that we have created in the previous article (right-click on the Libraries folder, choose AddLibrary…).

Configure the servlet in the deployment descriptor. Again, all settings will be the same; only the name for the servlet will be different. Here is what the Servlets page of your web.xml editing tool should look like:

image002.jpg

Also, change welcome file to app, as we did before, and delete the index.jsp file as it is not needed.

Now, create the skeletons for two Tapestry pages, i.e. all the necessary files, but without any contents. The first page is the default one, Home. As for the second, let it be named Secret.

So our task is to, first, create two HTML files, Home.html and Secret.html. Both should be located in the WEB-INF directory of the new project, and both should have the same default content created by NetBeans.

Next, create two page specification files, Home.page and Secret.page (right-click WEB-INF, New > Empty File…). As for the contents for these files, the Home.page in the previous project is empty right now (after we made that Insert an explicit component), so you can just copy its contents to both the new Home.page and the Secret.page files.

We need, however, to change the class attribute of the <page-specification> element in both files. Let it be com.devshed.tapestry.guesstheword.Home for the Home.page and com.devshed.tapestry.guesstheword.Secret for the Secret.page.

Finally, we need to create the com.devshed.tapestry.guesstheword package and two classes in it, both abstract and extending the Tapestry’s BasePage: Home and Secret. See the previous article for the details on how to create a package and a class in NetBeans. Here is the code for the Secret class; the Home one should be different only in its name (comments are not shown):

package com.devshed.tapestry.guesstheword;

import org.apache.tapestry.html.BasePage;

public abstract class Secret extends BasePage {

 

public Secret() {

}

}

Remember a useful shortcut: after typing in “extends BasePage”, press Ctrl-Space, and NetBeans will find the required class in the available libraries and write an import statement automatically. These new IDEs are so helpful!

Creating mock ups

Let me repeat this: it makes sense to start a Tapestry project from a series of mock ups, as they can be converted into Tapestry pages very easily. So let’s visualize first what we want to do in the new project.

The default page should display a very simple HTML form with a text field to enter a word and a button to submit it. It might look like this:

image003.gif

And here is the HTML code for the Home page mock up:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>

<html>

<head>

<title>Guess the Word</title>

</head>

<body>

<h2>Guess the Word</h2>

<form action=”">

Enter the secret word:

<input type=”text”/>

<input type=”submit” value=”Submit”>

</form>

</body>

</html>

The Secret page is going to be very simple. It will either greet the user if the word was guessed correctly or inform him or her of failure and provide a link to the Home page to go and try again. So the same page will contain two views but only one of them will be shown at a time. However, the mock up will display both views as it doesn’t contain any dynamic functionality yet:

image0041.gif

Here is the HTML code for the Secret page mock up:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>

<html>

<head>

<title>Guess Result</title>

</head>

<body>

<!– This will be shown if the guess was successful –>

<h2>Congratulations!</h2>

<p>You have guessed the secret word properly,

and here is the hidden wisdom:</p>

<p><i>Lorem ipsum dolor sit amet, consectetur

adipisicing elit, sed do eiusmod tempor

incididunt ut labore et dolore magna aliqua.</i></p>

 

<!– And this will be shown if case of failure –>

<h2>This was a wrong word</h2>

<p><a href=”">Go back and try again.</a></p>

</body>

</html>

Which components shall we need?

Now let’s think about which components we are going to need on these two pages.

First of all, the text box for entering a secret word should obviously be a component as the page class will need to know which word was entered by the user. Page class will have a property to store the entered word. Imagine: the HTML page produced by the page class and sent to the user on the one hand, and the server where the page class lives on the other hand can be thousands of miles apart. And still, there is some sort of data connection between Tapestry components on the page and the corresponding properties of the page class.

When the HTML page is rendered for the first time to be shown to the user, Tapestry components will display the initial values of the properties connected to them. When the user has filled in the form and submitted it, the page class will receive the new values and put them into the properties in place of the initial values.

But, yes, to send new values to the server, some form should be submitted. So the text box component, to work properly, should be surrounded by a form component. Right now, we have an HTML form on the page mock up, so we need only to make it a Tapestry component.

All in all, we need two components for the Home page.

The Secret page is very simple; all its text is hard-coded. However, we shall need to define whether the secret word was guessed properly, and if it was, show the greeting. This is one component, a conditional one. If the word was wrong however, we need to display an alternative message. You will see that Tapestry employs for this purpose yet another component.

Finally, the link leading back to the Home page should be a component too. This is because in Tapestry you don’t need to know URLs corresponding to different pages and use them to create links. You only need to tell the framework which page you want to see when the link is clicked, and there is a simple component intended exactly for this purpose.

Having an idea now of what kind of functionality we are going to need on our pages, we can go to the Tapestry 4.1 website (http://tapestry.apache.org/tapestry4.1/) and check which components are available there.

We shall find that, quite conveniently, Tapestry has a TextField component for displaying text boxes. There is also a Form component to contain the TextField. Naturally, the component named If will check if some condition is true and show or hide accordingly anything surrounded by this component. There is also a component named Else that should be placed after an If component. It will show its contents when the condition of the If component evaluates to false. Finally, there is a PageLink component, and its purpose is to provide a link to another page of the Web application.

You see, Tapestry provides everything we need. In the next article, we will configure the components on the pages.

by Alexander Kolesnikov

Creating Your First Tapestry Project

(No Ratings Yet)
Loading ... Loading ...

In the previous article, we began moving from theory to practice by preparing our work place and setting up our system. In this article, we actually get our hands dirty (at least figuratively) by building our first Tapestry project.From now on, I am going to use NetBeans. If you prefer to use Eclipse, the steps will be similar, but the details might differ. The good news is that when we come to writing code, the differences in IDEs will not matter that much.

Fire up your NetBeans. In the menu, choose File > New Project…, then select Web Application like so:

image002.gif

Press Next, and in the next dialog enter the name for your new project, say, FirstTapestry. I would advise you to store all your projects in a separate folder; in this case I named it NBProjects. Make sure that the bundled Tomcat is selected for the server. Also note that Context Path reflects the name of your application — this is what will be appended to the hosting server’s domain name to form your application’s context.

Have a look at the screenshot to make sure everything is set properly:

image003.jpg

Press Next. The next dialog allows you to choose a framework to use in your application, but only two choices are available for now, JavaServer Faces and Struts. We are not going to use either of them. In the future, the Tapestry module for NetBeans will hopefully be completed and then we might be able to have our application preconfigured for Tapestry while we’re right in the process of setting up a new project. For now, simply press Finish, as we are going to create the necessary configuration by hand.

Let’s have a look at the structure of the new project created for us by NetBeans:

image004.gif

You can see that the structure of a NetBeans Web project does not directly reflect the standard structure of a Java Web application. It has its own logic, more convenient for development. However, when at some stage we shall want to deploy and test our application, it will be packaged for us exactly as required by standards.

Now, let’s have a look at what we have here.

The Web Pages folder contains the future Web application. You can see the familiar standard subfolders here, META-INF and WEB-INF. If we need to, we can add some other folders, say, for images and styles. There is also a basic default JSP page, index.jsp. We shall leave it so far, but it won’t be needed in the future.

The Configuration Files folder contains quite conveniently everything we might want to configure. Most importantly, you see the deployment descriptor, web.xml - we are going to work with it in one of the next sections.

Have a look at the MANIFEST.MF file. It is very simple, and we are not going to add anything to it. It will simply be put into the META-INF directory at the packaging stage.

Also, have a look at the context.xml file. This one is Tomcat specific and simply tells the server what to add to its domain name in order to form our application’s context - remember, we specified this when setting up the project. Here are the contents of the context.xml:

<?xml version=”1.0″ encoding=”UTF-8″?>

<Context path=”/FirstTapestry”/>

Very simple, and nothing to change so far, so let’s go on.

The next important folder for us is the one called Source Packages. This is where we shall place the source files for page classes and any other classes that might be needed for our application.

Finally, there is a folder named Libraries. This is where we shall put JAR files containing Tapestry and everything it depends on.

As for the remaining folders — Server Resources, Test Packages and Test Libraries — we shall not need them for our first simple application. However, we are going to leave them just because one day you might want to extend this basic application and create on its basis something more impressive.

Adding Tapestry

So far, we have dealt with a generic Java Web application. Now we are going to add Tapestry. Basically, Tapestry is just a set of libraries that bring with them a lot of important and useful functionality.

One way to obtain these libraries is to go to the Tapestry website (http://tapestry.apache.org/download.html) and download a binary package acceptable for your platform. I recommend that you choose version 4.1.1. Although it is stated that it is “still undergoing lots of active development,” it is also considered to be “stable enough.” The downside of this approach, i.e. downloading the libraries from the Tapestry website, is that the libraries are packaged in a somewhat inconvenient way — every single library is put into a separate subfolder.

For our purposes, it will be more convenient to put all the JAR files together into one folder. You can repackage them yourself, or you can simply download the package that I have already created for you; please go to the beginning of this article and click on the appropriate link.

Unpack the libraries into some folder on your hard drive. In my case, I have put them all into the tapestry41 folder in my home directory.

Now, if you expand the Libraries folder in the Projects view of your NetBeans IDE, you will see that it already contains JDK and Bundled Tomcat libraries. Right-click (or Ctrl-click on a Mac) on the Libraries folder and choose Add Library… The Add Library dialog will appear, similar to this one:

image005.gif

We don’t have any Tapestry libraries here yet, so we need to add one. Press the Manage Libraries… button. The Library Manager dialog will open as shown below:

image006.jpg

Now press the New Library… button and in the dialog that opens, enter a name for the new library, such as Tapestry41. Press OK.

Back in the Library Manager, make sure that the name of the new library is selected in the Libraries view on the left side and press the Add JAR/Folder… button. In the Browse Jar/Folder dialog that opens, navigate to the folder where you have unpacked all the Tapestry-related JAR files and select them all, then press the Add JAR/Folder button. Yes, I know, it’s too many dialogs and buttons for such a simple operation, but we need to do this only once; any other projects you create in the same IDE will simply make use of this new library. The final result should look like this:

image007.jpg

Press OK and then, back in the Add Library dialog, choose the newly added library and press the Add Library button. Phew… A bunch of files gets added to the Libraries folder of your project and now, not only is the IDE aware of all the classes you will need for Tapestry development, but these libraries will also be packed into the final package with the application we are going to create.

Deployment descriptor

The next task is to configure the deployment descriptor in a Tapestry specific way. A deployment descriptor is an XML file and I am used to editing it by hand, but NetBeans provides a handy and easy to use editor for this purpose. Double-click web.xml file, and you will see the editor:

image008.jpg

We don’t have to enter anything at the first page, although you might want to enter the application’s name into the Display Name box. The really important page is the next one, Servlets. Tapestry comes with a ready to use servlet; all we need to do is configure it properly.

Right now, the Servlets page is almost empty, so press the Add Servlet Element… button. In the Add Servlet dialog that opens, enter the information as shown here:

image009.gif

As you will see in a later tutorial, it is convenient to give the servlet the name of the application itself. The Servlet Class will be always the same for all of our Tapestry applications. Now, the important piece of information is the URL Pattern(s). It tells the servlet container exactly which requests should be passed to our servlet. The pattern specified here is understood relative to the application context. This means that if we host our application at the www.example.com server, all requests to http://www.example.com/FirstTapestry/app will be passed to the Tapestry servlet, and the Tapestry framework will step in and show its miracles.

You might have noticed that sometimes I refer to Tomcat as a server, while at other times as a servlet container. In fact, it is both. A Web server is a piece of software that serves Web pages to site visitors. A servlet container is a piece of software that knows how to deal with servlets — and other Java classes as well. A combination of a Web server and a servlet container, like Tomcat, allows Java Web applications to run on the Internet.

Tomcat is the most popular choice but not the only one. The other quite popular and free option is Jetty. Yet another choice, Gaucho Resin, is not free but has a very good reputation.

Application servers like JBoss, Geronimo, WebSphere or WebLogic have in them a Web server and a servlet container as well, but they also have plenty of other goodies in addition to them. By the way, JBoss, Geronimo and WebSphere Community Edition all use Tomcat for their servlet container.

Press the OK button in the Add Servlet dialog. You will see that the information we have just entered is now shown on the Servlets page. The last piece of the configuration will deal with the default page of the application. Click on the Pages tab of the Deployment Descriptor editing tool, and you will see the page for editing welcome files:

image010.jpg

You remember that when no specific page is mentioned in a request, for example a visitor of our application is trying to navigate to http://www.example.com/FirstTapestry/, the Web server needs to decide which page to show. Here we can configure this, and currently the index.jsp page, generated automatically by NetBeans, is the only option.

If we wanted to have some default page which is not a part of the application itself, we could perhaps use the existing one, or use a static page, like index.html, and on it we could provide a link to the Tapestry application, i.e. to the Tapestry servlet.

However, in many cases we will want our Tapestry application to step in straight away, without any additional pages on the way to it. Let me show you my favorite trick to achieving this goal (although there may be other solutions too).

In the Welcome Files text box, instead of index.jsp enter just app, as if our default page was named ‘app’. Let’s see what will happen now if someone decides to navigate to our application’s context: http://www.example.com/FirstTapestry/. To decide which page to show, Tomcat will look into the application’s deployment descriptor: what is the welcome file? Hmm… There should be some file named ‘app’. Let’s try it then — and Tomcat will pass the request to http://www.example.com/FirstTapestry/app, which is exactly the path to which the Tapestry servlet is mapped, so our Tapestry application will handle the request properly.

For now, save the deployment descriptor with all the changes. You can also delete the index.jsp page, as it is not needed anymore.

We have finished with configuration issues and have arrived at the most interesting step — creating the application itself.

The First Tapestry Page

Every Tapestry page is represented by a Java class. This page class can render an HTML page using an HTML template that we provide to it. To know exactly which components were used in the page by the developer and how they should be configured, the page class will read an XML document called page specification.

So a Tapestry page consists of three entities:

  • A page class. If no class is specified, Tapestry will use its BasePage class, but this would be useful only for a very basic page. Normally, we extend the BasePage.

  • An HTML template with Tapestry components inserted into it in one way or another.

  • A page specification that links components in the template with their behavior in the page class and also provides all sorts of additional information.

The default page of a Tapestry application is named Home; this will be shown if no specific page was mentioned in the request. Now we are going to create this Home page, which means creating a Java class named Home, a page template named Home.html and a page specification named Home.page.

When creating a Tapestry page, it makes sense to begin with a page mock up. Just create an HTML page that shows what you want to achieve, properly designed, showing one of the moments in the life of your future application.

All the Tapestry artifacts, including page templates and page specifications, live inside the WEB-INF directory. Right-click this directory in the Projects view of NetBeans IDE and select New > HTML… in the context menu. In the New HTML File dialog enter the name for the new page: Home. The result should look like this:

image011.jpg

Press Finish, and NetBeans will create a simple HTML page for you. All we want for now is to display the current date and time, so edit the page like this:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”>

 

<html>

<head>

<title>My First Tapestry Page</title>

</head>

<body>

 

<h1>My First Tapestry Page</h1>

 

<p>Now is 8:27, the 1st of April 2007.</p>

 

</body>

</html>

Right-click the Home.html file in the Projects view, select View from the context menu, and you will preview the page in a Web browser.

Now, let’s convert this simple HTML page into a Tapestry page template. We want to display dynamically the time and date for the moment when the application runs. All we need to do is surround the piece of text, which we are going to dynamically replace, with a span element.

Span is a standard HTML element normally used to assign some additional style to a piece of markup. In this case, instead of adding a style, we shall give the span an attribute named jwcid with some value in it. Here I have made the change:

<p>Now is <span jwcid=”now”>8:27, the 1st of April 2007</span>.</p>

When Tapestry sees that some HTML element is marked with the jwcid attribute (’jwcid’ stands for Java Web Component ID), it knows that this element at run time should be replaced by a Tapestry component. However, for a Web browser this attribute means nothing, so it will ignore it. View the page in a Web browser, as before, and you will not see any changes.

That’s it, our HTML template is ready. Tapestry can see that we have used a component and named it ‘now’. But what kind of component is it, what exactly will it display dynamically instead of the <span>? To find out, Tapestry will look into the page specification, and this is what we are going to create next.

Right-click on the WEB-INF folder and in the context menu choose New > File/Folder… In the New File dialog that opens choose Other for the category and Empty File for file type, as the next screenshot shows:

image012.jpg

Press Next, in the next dialog enter Home.page for file name and then press Finish.

Enter the following content into your new empty file:

<?xml version=”1.0″?>

<!DOCTYPE page-specification PUBLIC

“-//Apache Software Foundation//Tapestry Specification 4.0//EN”

“http://tapestry.apache.org/dtd/Tapestry_4_0.dtd”>

<page-specification class=”com.devshed.tapestry.first.Home”>

 

<component id=”now” type=”Insert”>

<binding name=”value” value=”currentDate”/>

</component>

 

</page-specification>

You can see that this is an XML document. The DOCTYPE thing is not for human readers, we just leave it as it is and copy it from one page specification to another.

Note the opening <page-specification> tag. In its attribute we have specified a Java class to use for this page. It doesn’t exist yet, but we are going to create it soon.

NetBeans doesn’t highlight the syntax of the Home.page file as it does with any other XML files. This is because it doesn’t know that files with the .page extension contain XML. However, we can teach NetBeans to recognize .page files by changing its preferences. I don’t want to bother you describing yet another sequence of dialogs and buttons; try to figure out how to do this yourself, or ask me at the discussion page. A hint: use the advanced options of the editor.

The descriptions of the components used on the page go between opening and closing <page-specification> tags. In our case, there is only one component with the ID now. Tapestry can see that the type of this component is Insert — the simplest and perhaps most often used of Tapestry components. At run time, the Insert component simply replaces the corresponding HTML element with whatever was given to it as its value.

The way to give an Insert component a value is through its binding, appropriately named value. This line of code:

<binding name=”value” value=”currentDate”/>

is understood by Tapestry in the following way: to obtain the value, evaluate the currentDate expression. Which means: go to the page class, find a method named getCurrentDate(), invoke it, and whatever it returns will be the value you are looking for. So the next step is to create the page class with the getCurrentDate() method in it.

Right-click the Source Packages folder and choose New > Java Class… In the New Java Class dialog enter Home for the Class Name and com.devshed.tapestry.first (or anything else) for the Package. Press Finish, and the new class will be created.

To serve as a page class, the new class should extend the BasePage class that comes with Tapestry. Also, we want it to implement the getCurrentDate() method; this method simply returns a new Date object. Here is how the completed page class should look (comments are omitted for brevity):

package com.devshed.tapestry.first;

 

import java.util.Date;

import org.apache.tapestry.html.BasePage;

 

public abstract class Home extends BasePage {

 

public Home() {

}

 

public Date getCurrentDate() {

return new Date();

}

}

To help NetBeans find the BasePage class and write an appropriate import statement, use the convenient Ctrl-Shift-F shortcut.

Please note that the class is made abstract. This is quite normal from Tapestry’s point of view because the framework in many cases will implement for us some additional functionality, so it will create a concrete implementation by extending our page class at run time. In the following articles we shall get used to abstract methods and classes.

So we have created a template, a specification and a page class for the Home page. We have configured the Tapestry servlet so that a request to a default page comes straight to it. Now is the time to run our Tapestry application!

Press F6, or an appropriate button at the toolbar (you will recognize it by its tooltip saying “Run Main Project (F6)”). NetBeans will compile and package the application, then it will start Tomcat; you will see all this happening by the messages running in the Output window at the bottom. Finally, a browser window opens — and we see our first Tapestry page, so simple but glorious!

image013.gif

Try to reload the page and you will see that the current time changes as you do this. Imagine what is happening here: every time you send a request to the application, the page class takes its HTML template and builds an HTML page to return to you. Doing this, the page class notices that the page contains an Insert component. That component inserts into the page a date returned by a method of the page class. That method is invoked, and the new date, displayed as a string, is inserted into the resulting HTML page. Then you see it.

This is not a very exciting project, indeed, but the fact that it works confirms that we have configured our working environment properly, and this was our main aim for today.

What comes next

In the next part of our Tapestry tutorial we are going to create a more interesting application, although it will also be rather simple. The aim will be to show you some of the most often used Tapestry components, to demonstrate two alternative ways of declaring a component and to discuss different ways of adding a property to a page.

See you in the next article and don’t forget to visit the discussion page.

by Alexander Kolesnikov

Book Review: The Apache Modules Book

(No Ratings Yet)
Loading ... Loading ...

The Apache Modules Book is the latest open-source software development book from Prentice Hall. The book forms part of the Open Source Development Series from Prentice Hall, which includes other titles such as Understanding AJAX and Embedded Linux. Dan Wellman looks at this book chapter by chapter to see whether it’s a worthy addition to an open source developer’s library.Prentice Hall are renowned as a leading publisher of developer focused and educational books, and are America’s leading publisher of academic textbooks. It was written by Nick Kew, and features a foreword from Rich Bowen, both prominent figures in the world of Apache. Nick has decades of professional software and system experience and is a member of both the Apache core development team, and the Apache Software Foundation. The book is priced at a very reasonable $49.99 and the ISBN is 0132409674.

219tvrtds7l_aa_sl160_.jpg

The book is separated into just 12 chapters. Often technical code-based books can run up to as many as 50 chapters, and many are so big that they are broken down into parts before being broken down further into chapters. Each of these chapters focus on a specific aspect of either the Apache server itself, or the process of creating new modules.

The first chapter is purely concept-based and gives an introduction to the Apache Server and its origins and history. It gives a detailed description of the Apache Software Foundation, including who they are, what they represent, the different levels of developer participation, the development process and information regarding the Apache License (the full license is also included at the end of the book in Appendix A and the Contributor License Agreement as Appendix B).

Chapters Two Through Five

Chapter two looks at the architecture of Apache and the platform with respect to application programming; it describes in great detail the different operational phases of Apache, what MPMs are and how they interact with the platform. It discusses the basic concepts and structures of the server, looks at some of the configuration basics and gives an overview of how requests are processed by the server. Again, this chapter serves as an introduction to bring you up to speed with how the server works, but unlike chapter one, there are detailed examples of the underlying code of some of the Apache header files, which is a helpful start for people that have only a basic understanding of Apache.

Chapter three delves into the Apache Portable Runtime (APR), which provides a portable, platform-independent layer for applications. APR modules consist of APIs and implementations of the functions contained in the API, and provide a useful abstraction layer between the applications programmer and the native system. Each of the APR functions are listed and described in detail, often with basic examples of use. Information is also provided here that describes processes such as memory management and resource pooling, buckets and brigades and the database module.

Chapter four moves on to discuss programming techniques and best practices that should be used when developing custom Apache modules. This is another scenario-based chapter in which points that are made are reinforced with code examples. The information in these three chapters gives you the foundation you’ll need before beginning modular application development using Apache as a platform. This is a complex subject and at least a fundamental understanding of C is required. Without the information in the first few chapters a lot of the examples later in the book wouldn’t make sense, so it’s great that Nick included this kind of information for newcomers to the field.

Chapter five sees the creation of an actual module that is used and executed by Apache. No programming manual that introduces developers to a new language or platform would be complete without the Hello World! application, so it’s great to see this tradition continued here. Where the preceding chapters were a little complex in places, with some of the examples and topics referring to advanced features and practices, it’s refreshing to come back to a chapter that serves as a beginning and where the examples require a little less brain power to follow.

Chapters Six Through Ten

The next three chapters look at some request handling fundamentals in more detail. Chapter six looks at the request processing cycle and metadata handlers in great detail and focuses on subjects such as the metadata sent to the server in an HTTP request, how the modules of Apache can hook into this metadata, internal redirection and how the request processing flow is interrupted and diverted to error documents. To show some of the examples illustrated in this chapter working, a new module is also written.

Chapter seven moves on to look at the Apache access, authentication and authorization (AAA) framework in great detail and again provides a lot of example code, although no new modules are produced during this chapter. As the author points out, the need to write modules that deal specifically with AAA is less pressing with the improvements in this area in Apache 2.2; however, including this information helps to refine your knowledge of the subject and prepares you just in case you ever need it.

Chapter eight moves on to discuss the modules that play a part in the filter chain part of the request cycle, and how to develop your own modules that work with filters. Two example modules are created in this chapter, each exposing different aspects of this large topic. Again this is a great chapter for expanding your all-round working knowledge of Apache, and where words fail to completely describe different filter concepts, flow diagrams are included to maximize your learning of the subject. The chapter goes into fine detail about the input and output filters, the code that drives them and the function of each. These three chapters also contain a lot of information on how Apache works that will be of use to anyone that wants to learn about the web server, not just those interested in writing custom modules.

In chapter nine, the author looks at the different methods for exposing your custom modules to configuration, so that administrators or users can control how your modules function. Apache, as any administrator will know, is configured with the use of directives added to the httpd.conf file, and this chapter looks in detail at how similar configuration settings are created to apply to your module.

Chapter ten looks at extending the API in order to implement new API functions, implement new hooks, and provide services. Processing hooks work with the requests that the server receives and a thorough explanation of how hooks work is also provided. A lot of information is also given in this chapter about how modules can interact with each other through exported functions and services.

The Last Two Chapters and Final Thoughts

The next chapter begins with a brief look at the way Apache has evolved over previous versions of the software with regard to databases and looks at the classic LAMP architecture. The Apache database framework is examined in detail, as well as the DBD architecture, The chapter also covers using DBD in a module and discusses, with full examples, how to write your own driver to add support for a database type not supported by the DBD module. This is one area in which Nick Kew is highly respected, having written the dbd_apr module himself.

The final chapter looks at the all-important aspect of debugging modules that you have written. No one writes a complete module for the first time without making a single error, and this chapter provides the means for tracking down and eliminating bugs in your code. It deals specifically with the make up and use of the error log, running Apache under a widely-used debugger and how to trace server crashes. It also looks at using a diagnostic module that looks for problems in filter modules, and the author gives a personal example of how this module had been used to track down a problem with the third-party library libxml2. All in all this is an excellent way to end the main body of the book, but there is also a lot of information that can be found in the appendices.

The book’s main focus is using Apache and the HTTP protocol as a basis for applications programming and it helpfully provides the entire HTTP 1.1 protocol as Appendix C. This is great because it means that you can get by using just this one book to learn how to program modules and as the reference you’re going to need with respect to HTTP; you don’t need to rush off and buy a separate book or spend time looking for the references elsewhere.

One final “feature” of the book that is worth mentioning is that it is Safari Books Online Enabled. Safari Bookshelf is an electronic reference library that allows you to search thousands of online technical reference manuals. You get a 45-day free trial and access to the online version of the book is obtained using the coupon code found in the first few pages of the book. Now if you leave the book at home but find that your need to access it while at work, you can just log on and dive in.

Overall, I thought the book was very well written; the subject is broken into well sized chapters that flow smoothly, the style is engaging and Nick Kew does an excellent job of bringing a complex and code-heavy subject to life, a character that many technical reference books simply lack. As the sole book in existence dedicated to teaching people how to write custom Apache Modules to turn Apache into an application platform, it is a must for anyone that is interested in this area of programming.

by Dan Wellman 

Preparing the Workspace for Apache Tapestry

(No Ratings Yet)
Loading ... Loading ...

In the previous article of this series I explained, in the historical perspective, why Tapestry is a very attractive and advanced framework for building Java Web applications. Now we are moving from theory to practice. But before doing anything, we need to prepare the workplace.

There are two possible approaches to explaining how to get and install all the necessary pieces of software.

One approach is to describe every step in great detail, with screenshots and extensive comments. However, I expect that many readers will find this approach too tedious, especially when the installation process is straightforward and is also described elsewhere (say, in the documentation that comes with the downloads).

The second approach, and the one that I am going to take, is to explain in detail only those steps in installation and configuration that are not trivial, and give only general directions for the trivial ones.

This second approach, although more efficient, leaves a possibility that some readers will be stuck with a problem of one sort or another. However, DevShed provides a discussion page where everyone can ask a question, and I will be always there to answer it. So I suggest that if you have a problem following my instructions, or any other problem indeed, ask a question at the discussion page, and I will give as detailed explanations there as might be needed.

We shall need the following three pieces of software:

  • Java Development Kit (JDK). This one is needed to make your computer able to compile and run Java programs.

  • An Integrated Development Environment (IDE). The two most popular free choices are NetBeans and Eclipse. I will cover Eclipse configuration in wide strokes, while more detailed instructions will be given for NetBeans configuration only.

  • A servlet container. The most popular choice is Apache Tomcat, and it is also bundled with NetBeans, so this is exactly what we will use for this tutorial.

All of this software is available for free, so you can simply download and install it.

If you will follow my choice of IDE and decide to use NetBeans, there is a way to get everything installed in one go using a bundle. Refer to the instructions below.

JDK

Before installing a JDK, first of all please check to see whether you have installed it already. To do this, try to invoke the Java compiler. Open a command prompt or a console window and enter the following command:

javac -version

If your computer replies similar to this:

C:>javac -version

javac 1.5.0

javac: no source files

Usage: javac <options> <source files>

where possible options include:

… other output goes here …

then you already have a JDK. Still, check the version. Although Tapestry can work with a version of JDK as low as 1.3, we are going to use annotations in these tutorials, and annotations appeared in version 1.5 only.

If however your computer replies that javac isn’t a recognized command, or your version is lower than 1.5, you need to install an appropriate JDK.

To do this, go to the Java.sun.com website and in the menu choose Downloads > Java SE (http://java.sun.com/javase/downloads/index.jsp).

Here you have two options: to download and install JDK itself (the current version is JDK 6) or download and install JDK together with NetBeans IDE (currently JDK 6 with NetBeans 5.5). The latter makes sense if you agree with my suggestion to use NetBeans as the IDE for this tutorial.

The JDK + NetBeans package is available for Windows, Linux and Solaris only, not for Mac OS X, but Macs have a JDK already installed on them anyway.

If your Mac came with JDK 1.4.2 or earlier on it, please check the Java FAQ at Developer.apple.com (http://developer.apple.com/java/faq/) to find out how to upgrade to a higher version.

After downloading a JDK, please follow the provided installation instructions specific to your platform. Or ask me at the discussion page if you have any difficulties.

If you are installing JDK together with NetBeans, simply accept all the default options during the installation.

IDE

Eclipse

Eclipse is a very popular tool among Java developers, and if you are used to it, you might prefer to use Eclipse for Tapestry development too.

There are a number of sources explaining how to set up Eclipse for building Tapestry applications. One of them is the book by Kent Tong (http://agileskills2.org/EWDT/index.html) which I have already mentioned in the previous article. You will find detailed instructions on downloading and installing everything in the freely available first chapter of this book.

However, Kent Tong uses a “bare bones” Eclipse, while I find the Eclipse Web Tools Platform more convenient to use for Web development. You can find detailed instructions on how to configure Eclipse WTP for working with Tapestry at the Tapestry Wiki website (http://wiki.apache.org/tapestry/HowToSetupEclipseWtp).

NetBeans

One of the benefits of using NetBeans for this tutorial is that you don’t need to bother downloading and wiring together different pieces of software. In fact, you might have already installed everything you need in the previous section if you chose JDK + NetBeans package.

If not, go to the NetBeans website (http://www.netbeans.info/downloads) and download the IDE for your platform (it is available for Windows, Mac OS X, Linux and Solaris). Then install NetBeans following the available instructions with all default options.

Servlet Container (Tomcat)

Hmm… Almost nothing to write here. If you are using Eclipse, you will find out how to download and install Tomcat following the links given above. If you’ve installed NetBeans however, you already have Tomcat bundled with it.

So let’s go on.

The Standard Structure of a Java Web Application

Before looking inside of a Java Web application, let’s have a look at the surrounding world. First of all we need to agree on what “application context” means, as this term can have different meanings.

Say we have created an application named TestApp and uploaded it to our server; let its domain name be http://www.example.com/. If someone wants to use our application, they should navigate to www.example.com/TestApp/. We can think that at this location some folder or directory is located that contains all the files of our application. That folder, together with its URL, like http://www.example.com/TestApp/, is the context of our application, and the location of all the files, accessible from the Web, is defined relative to the application’s context.

Say we have a page named somepage.html that is stored at the top level of the application’s directory. Its location within the application will be /somepage.html - relative to the context. Its full URL will depend on the context’s URL; in our example it will be http://www.example.com/TestApp/somepage.html. It is clear, isn’t it?

Another important piece of information to understand is a Web server’s behavior in relation to the default page. Say you decided to navigate to the application’s context: http://www.example.com/TestApp/. This tells the Web server working at www.example.com from which folder to serve pages to you. But which page exactly will it show you now? By default, it will try to find in this folder a page named index.html, or index.htm, and if there is such a page, the Web server will show it. There are also other ways to configure the default page, as you will see later.

But what happens if there is no default page in the application? The Web server will try to show you all the contents of the folder, so you could pick for yourself exactly what you want to see, or, if this is forbidden by its settings, it will report an error.

These are all basics, of course, but it is important to understand them clearly.

Now, how might the contents of a Java Web application’s folder look? Here is an example:

image001.gif

You can see in the picture that TestApp folder contains:

  • A couple of pages: index.html and somePage.jsp;

  • A few directories: images, styles, META-INF and WEB-INF.

The index.html page is the default page; it will be shown by the Web server if no page was specified for the given application context. The JSP page, somePage.jsp shows simply where JSP pages are placed if they are used in the application - directly under the context, as any other pages.

In fact, you can create as many subfolders as you wish and put your HTML and JSP pages into them, as long as you don’t name your subfolders ‘WEB-INF’ or ‘META-INF’.

It is logical, but not required, to put all the application’s images into one folder, in our example images, and to do the same with all the styles, in our example they are put into the styles subfolder.

The special elements of the application are META-INF and WEB-INF directories. As for the META-INF directory, it will simply contain the manifest file, a kind of description of the package that we shall create from our application at a later stage. We shall not discuss it in more detail.

It is the WEB-INF directory which is all-important. It contains all the inner workings of a Java Web application; it is the heart of it.

This is important: you should always name this directory properly: WEB-INF, in all capitals. If you name it ‘Web-inf’ or ‘web-inf’, your application will not work, and it might be difficult to guess why it doesn’t work.

You can see that the WEB-INF directory contains two subdirectories, classes and lib, and a file named web.xml. Again, we have no freedom here; everything should be named as shown, as everything has its special purpose.

The deployment descriptor, which is web.xml file, serves to tell the Web server all of the most important details about our application and its configuration. In one of the next sections we shall look at the deployment descriptor in more detail.

The functionality of the application that we shall create will be implemented as Java classes, and these will go into the ‘classes’ subdirectory.

Finally, we are going to reuse functionality created by other developers — most importantly Tapestry libraries. This comes packed as JAR files and we shall put any libraries we might need into the ‘lib’ folder.

This is the standard structure that every Java Web application should conform to, whether it was built using just servlets or some more advanced framework. Please note that the WEB-INF directory is protected by the server; you cannot navigate into it. For instance, if you try to navigate to http://www.example.com/TestApp/WEB-INF/web.xml, the Web server should tell you that you are wrong. It is only for the Web application to decide how and when to use the contents of the WEB-INF.

So you have installed an IDE and everything required for development. You have a general idea of the structure of the future application. It is the time to create our first Tapestry project. That will be covered in the next article. See you in the next Tapestry tutorial and don’t forget to visit the discussion page.

by Alexander Kolesnikov

Solving Problems with Recursion

(No Ratings Yet)
Loading ... Loading ...

Recursion is a way to solve a problem by…reducing it to the same problem. What? It may be counterintuitive, but many turn-based games (including chess) use exactly this technique to make a computer player “think.” Mohamed Saad explains the concept, along with when (and when not) to use recursion in your programming. Check out the Connect4 example!Recursion: Solving problems the recursive way

In this article, I will introduce the concept of recursion, one of the most amazing programming constructs, as you will see. Recursion is quite counter-intuitive, and you will certainly find it weird at first, but once grasped, it becomes a seriously powerful weapon in your programming arsenal. Let’s start with the definition.

What is Recursion?

Recursion is a totally different method of solving problems. Conventional problem solving methods consists of decomposing the solution into steps, and executing each step in turn. Well…enter recursion. The recursive way of solving a problem is to reduce the problem into another problem that is exactly of the same type, and solving the new one instead. And how do you solve the new one? Guess what? You just reduce it into another problem of exactly the same type, and so on, and so on, and so on…

Ok, before it gets too weird, let’s see an example of a real-life problem, and how we can use recursion to solve it.

Real Life Example

Let’s assume you have moved to a new apartment. You are exploring the neighborhood, and you suddenly discover that you don’t know your house number. You looked at the building, didn’t find a number there. You knocked on a random apartment, and asked, “what is the number of this building,” and the guy who opened the door smiled and said, “I don’t know the number of this building, but if you look at the number of the building next to us and add 1, you will know our building number.”

Now, let’s pause for a moment. The problem you are trying to solve is “knowing the number of your house.” Let’s look at the proposed solution to this problem. What was the suggestion? You were asked to look at the number of the building next to you and add 1. Your problem was thus reduced into a problem of exactly the same nature! At first your problem was “to find the number of a house,” and your problem now became “finding the number of a house.”

11.jpg

Fig 1. You never knew knowing your house number could get you into so much trouble, did you?

The Plot Thickens

To confuse things even more, let’s say you visited the house next to you, but you still found no number. You knocked on the door, and asked about the house number. Guess what they said to you? “We don’t know, but look at the house next to us, add 1, and you will know our house number.”

Déjà vu anyone? This game could take a while. You should repeat this again and again, till you find a house with a number you know. You add 1, and know the number of the one next to it, and so on, until you reach your house.

Notice that in every step, your problem was always reduced to exactly the same kind of problem (knowing a house number). This is the heart of recursion. We have just made our first recursive solution to a problem.

Before we go any further, I want to make two very important notes. These notes are going to be extremely useful when we start dealing with recursion in programming.

Note 1: In every step of solving a recursive problem, the problem always reduces to a problem of exactly the same nature.

This one is obvious, but now look at number 2.

Note 2: At a certain point, you should just solve the problem you have immediately rather than reducing it any further.

This note is extremely important. Let’s return back to our house numbers problem. If you just keep asking and you are always asked to see the next house, you will spend your entire lifetime looking at buildings! At a certain point, you have to find a house with a number that you know. At this point, the recursion stops, and you start to solve all the problems you left open.

Let me stress this again: you can’t keep reducing your problem into a similar problem forever, or else you are never going to stop. At a certain point, you have to just stop and solve the problem at hand. This point is sometimes called the stopping condition.

Now, I can already hear you screaming, “What does this have to do with programming?!” Well, a lot, actually. When you are writing a program, you are solving a problem (or a set of problems). If you write your solution to the problem in a recursive way, what will it look like? Basically the function you write to solve the problem is going to eventually call itself. What for? This comes from our definition of recursion. We reduce a problem to a problem of exactly the same nature. This is why the function calls itself to solve the new instance of the problem…

Sounds complicated? Don’t worry. Let’s look at our first programming example, a really simple one.

First Programming Example

As promised, this one is going to be easy. We will take a well known problem, and see how we can solve it recursively. The problem is searching an array. You are given an array, and you want to search for a certain value inside the array. The non-recursive approach to this problem would be to iterate through the array looking for the value we search for. When it is found, we stop and report success, and if not, we report failure.

Now, let’s think recursively. We want to reduce the problem of searching an array into a problem of…well…searching an array. After all, this is how recursion works.

Think of this approach. To search an array whose length is n for the value of v, do the following.

If the element is in the very last position, report as success

If n