Search

Dark theme | Light theme

September 22, 2008

Add CDATA section to output with XMLSerializer in Cocoon 2.2

We can use Cocoon to put the contents of XML elements in a CDATA section. To achieve this we must configure the XMLSerializer. In Cocoon 2.2 we add a new bean definition to the file src/main/resources/META-INF/cocoon/spring/block-servlet-service.xml.

<bean name="org.apache.cocoon.serialization.Serializer/cdata-xml" class="org.apache.cocoon.serialization.XMLSerializer"
 scope="prototype" parent="org.apache.cocoon.serialization.AbstractTextSerializer">
 <pipeline:component mime-type="text/xml;charset=utf-8"/>
 <property name="format">
  <props>
   <prop key="encoding">UTF-8</prop>
   <prop key="cdata-section-elements">contents title</prop>
  </props>
 </property>
</bean>

In line 7 we define the XML elements we want to enclose in CDATA. We can use this serializer in our sitemap.xmap and the contents and title elements will have CDATA sections. Suppose we have the following input.xml file:

<root>
 <title>My special title.</title>
 <contents>Simple content with &lt;b&gt;html&lt;/b&gt; code.</contents>
 <field>Another field</field>
</root>

When we run it through the following pipeline:

<map:match pattern="output.xml">
 <map:generate src="input.xml"/>
 <map:serialize type="cdata-xml"/>
</map:match>

We get the following output:

<xml version="1.0" encoding="UTF-8"?><root>
 <title><![CDATA[My special title.]]></title>
 <contents><![CDATA[Simple content with <b>html</b> code.]]></contents>
 <field>Another field</field>
</root>

September 21, 2008

Debugging Cocoon 2.2 in NetBeans

Most of the time when we work with Cocoon we are writing XSLT to do transformations. But sometimes we write Java code to extend the functionality of Cocoon. And that means we want to be able to debug our Java code in NetBeans. Luckily this is easy to accomplish. First we must start Jetty with mvndebug. This will enable us to attach the NetBeans debugger to Jetty, which runs our Cocoon application.

We open a command prompt and go to the directory with our Cocoon application. In the directory we run the following command: mvndebug jetty:run. Maven now starts in debug mode. And because Jetty runs in the same process as Maven we also run Jetty in debug mode.

Now in NetBeans we go to Run | Attach Debugger. We get a dialog window with settings. We can leave the settings as-is and press the OK button. NetBeans will now attach the debugger to Jetty. In NetBeans we can set breakpoints in our Java code and debug our code.

September 15, 2008

Use properties from the Spring configurator in Cocoon 2.2 sitemap

Cocoon 2.2 has a new mechanism for working with configurations: the Cocoon Spring Configurator component. Adding the configurator to our application is easy, because we only have to add <configurator:settings/> to a Spring configuration file. Now we have support for running modes, property handling and Spring bean configurations. Just like that.

We will use a small example to see how properties are handled by the configurator. Suppose we have a simple Cocoon 2.2 block with a sitemap.xmap. In the sitemap.xmap we use the property enable.internal-only (see line 6.):

<?xml version="1.0" encoding="UTF-8"?>
<map:sitemap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://apache.org/cocoon/sitemap/1.0 http://cocoon.apache.org/schema/sitemap/cocoon-sitemap-1.0.xsd"
 xmlns:map="http://apache.org/cocoon/sitemap/1.0">
    <map:pipelines>
        <map:pipeline id="internal-resource" internal-only="${enable.internal-only}">
            <map:match pattern="resource/internal/**">
                <map:read src="resource/internal/{1}"/>
            </map:match>
        </map:pipeline>
        <map:pipeline id="external-resource">
            <map:match pattern="resource/external/**">
                <map:read src="resource/external/{1}"/>
            </map:match>
        </map:pipeline>
    </map:pipelines>
</map:sitemap>

To give the property a value we have different alternatives, not to say a lot of alternatives. For this example we create a new property file: src/main/resources/META-INF/cocoon/properties/sample.properties. In the file we define enable.internal-only=false. Now when we run the application we can access the pipeline internal-resource because the value of the property enable.internal-only is false.

September 12, 2008

Shutdown Jetty started by Maven in NetBeans

We can start Jetty with the jetty:run command in NetBeans, but because of an issue for Windows users (see issue 138116) we cannot shutdown Jetty from within NetBeans. We can of course start the Windows TaskManager and kill the process by hand, but wouldn't it be nice of we could just stop Jetty from within NetBeans?

Luckily this is not so difficult to achieve. First we must change our pom.xml and add some elements to the Jetty plugin definition. Let's look at a sample from our project's pom.xml:

<plugin>
 <groupId>org.mortbay.jetty</groupId>
 <artifactId>maven-jetty-plugin</artifactId>
 <version>6.1.7</version>
 <configuration>
   <connectors>
  <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
    <port>8888</port>
    <maxIdleTime>30000</maxIdleTime>
  </connector>
   </connectors>
   <contextPath>/</contextPath>
 </configuration>
</plugin>

Now we must add stopKey and stopPort elements to the configuration element. The stopKey is a text string supplied with the stop command. And the stopPort is the port number Jetty will listen to for stop commands. So now we get the following definition (see line 12-13):

<plugin>
 <groupId>org.mortbay.jetty</groupId>
 <artifactId>maven-jetty-plugin</artifactId>
 <version>6.1.7</version>
 <configuration>
   <connectors>
  <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
    <port>8888</port>
    <maxIdleTime>30000</maxIdleTime>
  </connector>
   </connectors>
   <contextPath>/</contextPath>
   <stopKey>stop</stopKey>
   <stopPort>8889</stopPort>
 </configuration>
</plugin>

Next we must invoke the jetty:stop command to stop a running Jetty instance. We right-click on our project and select Custom | Goals.... We get a dialog window where we can fill in values. We fill the Goals field and Remember as field with the value jetty:stop. We click the OK button to close the dialog.

And now we can execute the jetty:stop command right from within NetBeans. We right-click on our project, select Custom | jetty:stop and NetBeans will stop a running Jetty instance.

September 11, 2008

Your first Cocoon application using Maven 2 in NetBeans

This blog post is a copy of the original Your first Cocoon application using Maven 2 tutorial, but this time we are going to use NetBeans to build the application!

To create a new Cocoon block we go to File | New Project. We get a new dialog window with a list of project categories. We start by selecting the Maven category and then select Maven Project.

Click on the Next button and we get a new screen where we can select the Maven Archetype. We need to scroll down the list until we get to Archetypes from Maven repositories. We click on the plus-sign to get a new list of archetypes. We scroll down to Cocoon 2.2 Archetype: Block and select it.

We click on the Next button to go to the last screen. Here we type myBlock1 at the Project Name input field. We type 1.0.0 in the Version input field and press the Finish button.

NetBeans will now generate a new project based on the Cocoon 2.2 block archetype. When we look at the project we can see a lot of directories are created and some sample files.

To run the block as Java web application we first go to the project properties. We right-click on the project and select Properties from the popup menu. In the project properties dialog window we must select the Actions category. Make sure Use external Maven for build execution is checked. See also Use external Maven to work with Cocoon. Then we redefine the Run project action and set Execute Goals to jetty:run. The Set Properties field must be empty. We click the OK button to finish up.

Now we can run the project (for example by using the shortcut Shift+F6 in Windows) and NetBeans will start Jetty. We can open a web browser and go to http://localhost:8888/myBlock1 and we get the sample page.

Because of an issue for Windows users (see issue 138116) we cannot shutdown Jetty from within NetBeans. We must use the task manager (or another tool) to kill the Jetty process. Or read Shutdown Jetty started by Maven in NetBeans.

September 10, 2008

Using JTattoo look-and-feel with NetBeans

NetBeans is a normal Java Swing application. This means we can use different look-and-feel packages available for Swing to change the default look-and-feel. I like the JTattoo look-and-feel package. JTattoo provides several themes we can use.

To use JTattoo with NetBeans we must first download the JAR file. Next we must give some startup parameters when we start NetBeans. First we must add the JTattoo.jar file to the classpath with -cp:p JTattoo.jar. Next we must define the look-and-feel we want to use with the --laf startup parameter.

Suppose we saved the JTattoo.jar file in d:/java/look-and-feel/JTattoo.jar and we want to use the AluminiumLookAndFeel class we must start NetBeans with the following command:

netbeans -cp:p d:/java/look-and-feel/jtattoo.jar --laf com.jtattoo.plaf.aluminium.AluminiumLookAndFeel

Or try other look-and-feels:

Use external Maven to work with Cocoon 2.2 in NetBeans

Update: since NetBeans 6.5 we don't have to use the external Maven. We can use the internal Maven from NetBeans! So if you use NetBeans 6.1 you must apply what is described in this post, otherwise you are already to go.

Working with Cocoon 2.2 is a blessing compared to the previous versions. Cocoon 2.2 is now based on the Spring framework and uses Maven for the build process. Especially the dependency mechanism of Maven makes creating a new Cocoon application a lot easier. And if there is one IDE out there with superb Maven support than it is NetBeans.

NetBeans already has the Cocoon Maven archetypes available. To create a new Cocoon block for example is as easy as clicking on several menu options. The only thing we need to consider is that the Cocoon Maven plugin doesn't (yet) support the Maven 2.1-SNAPSHOT version, which is used by the NetBeans. Luckily we can define an external Maven in NetBeans to be used.

Make sure we have installed Maven 2.0.9 on our computer. Then in NetBeans we go to Tools | Options | Miscellaneous | Maven 2. Here we can define the path to our Maven 2.0.9 in the field External Maven Home.

After we have defined the path to Maven we can select a project and go to Project properties. In the Actions section we can select the checkbox Use external Maven for build execution.

September 5, 2008

Running the Cocoon 2.2 samples

Because Cocoon 2.2 now uses Maven we don't have to download the source code anymore. But if we want to see the samples web application we still do have to download the source code. We can checkout or export the source code from http://svn.apache.org/repos/asf/cocoon/trunk. We must have Maven 2.0.9 installed and in our path before we can continue. Now we can go the directory where we put the source code. We must first set the environment variable MAVEN_OPTS and give it the value -Xmx256m. This is to make sure Maven can compile all Cocoon sources. Then we type:

mvn -P allblocks install -Dmaven.test.skip=true

With this command all Cocoon code and samples are compiled. We don't need the tests to be executed for our sample web application. Once Maven is finished, we must go to the directory core/cocoon-webapp. We can now start the samples web application by typing:

mvn -P allblocks jetty:run

In our web browser we open http://localhost:8888/ and we get our sample application start screen. If we click on the samples link we get an overview page of all the samples of all the blocks of Cocoon 2.2.

Using Cocoon 2.2 without installing Cocoon

Cocoon is a very powerful XML publishing framework. With version 2.2 Cocoon switched from a "checkout the source, set your environment variables and run the build script" installation to building with Maven 2. And that makes life so much easier. We now only have to create a Maven project described by a pom.xml file. In this file we define our dependencies for Cocoon. So we don't need to download the source code and build it, we only have to define a Cocoon dependency. Maven will make sure the dependencies are downloaded if necessary and we are ready to go.

So if we don't have to download the source code anymore, how do we get Cocoon libraries in our project? Well that is the "magic" of Maven. The Cocoon libraries are available on the internet in Maven repositories. Maven will download the libraries from these repositories to our local computer. And once they are downloaded to our local computer we can use them for compiling and running our Cocoon application.

The following code is an example extract for a Cocoon application with the core dependencies defined:

<dependency>
 <groupId>org.apache.cocoon</groupId>
 <artifactId>cocoon-core</artifactId>
 <version>2.2.0</version>
</dependency>
<dependency>
 <groupId>org.apache.cocoon</groupId>
 <artifactId>cocoon-servlet-service-components</artifactId>
 <version>1.0.0</version>
</dependency>

September 4, 2008

Use Saxon in Cocoon 2.2

Saxon is a great XSLT engine and supports XSLT 2.0. I normally use it for almost of all my transformations. But getting it to work in Cocoon 2.2 needs some steps. We will see which steps are necessary to get Saxon working in a Cocoon 2.2 block.

We first must have a Cocoon block to which we will add Saxon support. Next we create the directory src/main/resources/META-INF/cocoon/avalon. In this directory we can add component definitions, which are used by our block. In this directory we add the file cocoon-core-xslt-saxon.xconf. The contents of the file contains the Saxon transformer definition:

<?xml version="1.0" encoding="UTF-8"?>
<components>
    <component role="org.apache.excalibur.xml.xslt.XSLTProcessor/saxon"
             class="org.apache.cocoon.components.xslt.TraxProcessor">
        <parameter name="use-store" value="true"/>
        <parameter name="transformer-factory" value="net.sf.saxon.TransformerFactoryImpl"/>
    </component>
</components>

Notice we use /saxon at the end of value for the role attribute and we need this name for further configuration. We now create another file in the src/main/resources/META-INF/cocoon/avalon directory with the name sitemap-transformers-saxon-transformer.xconf. In the file we add a transformer definition to reference the Saxon transformer component. Notice the xslt-processor-role must be saxon like we defined in our component definition:

<map:components xmlns:map="http://apache.org/cocoon/sitemap/1.0">
 <map:transformers>
  <map:transformer name="saxon" src="org.apache.cocoon.transformation.TraxTransformer">
   <xslt-processor-role>saxon</xslt-processor-role>
  </map:transformer>
 </map:transformers>
</map:components>

Now we only need to a dependency to our pom.xml to include the Saxon library in our application classpath:

<dependency>
 <groupId>net.sf.saxon</groupId>
 <artifactId>saxon</artifactId>
 <version>8.7</version>
</dependency>

And now we can use the Saxon transformation in our Cocoon 2.2 block.

September 2, 2008

Context sensitive code completion in NetBeans

Working with the NetBeans Java editor is such a joy. Recently I discovered that code completion is context sensitive. When we create a new variable and press Ctrl+Space after the new keyword we get a list of classes in alphabetical order. But notice the classes which are extended from the base class are at the top of the list. The following screenshot shows all allowed classes for the variable with base type java.lang.Number:

Instant messaging everywhere

For my work I am at different locations for different projects. Sometimes I work at clients with complete internet access, but most of the times we are behind firewalls and proxy servers. I like to keep in touch with friends and colleagues by instant messaging now and then. Normally I use Pidgin, but this doesn't work if I am behind firewalls and proxy servers.

Ah, up until yesterday, because yesterday I discovered Meebo. With Meebo I can login to different instant messaging accounts like ICQ, GoogleTalk, MSN and AIM. Once I am logged in I can open new chat sessions with all my friends and colleagues right from the browser. And because I do it via the browser I don't get in trouble with firewalls and proxy servers.

Update: And now Meebo also has a Firefox addon, which makes it even easier to use Meebo.

September 1, 2008

NetBeans with newer subversion client

Today I got this message in NetBeans: This client is too old to work with working copy 'projectX'; please get a newer Subversion client. That was a first for me. It is true I checked out the sources from a Subversion repository with a newly installed TortoiseSVN and probably the Subversion version was newer than the client in NetBeans.

Luckily it is easy to change the default client and use a newer client for Subversion. We only have to go to Tools | Options | Miscellaneous | Versioning | Subversion. There we have a input field Specify the SVN home folder with a Browse button. Here we can specify where we installed our latest Subversion client software.

Another way to use a newer Subversion client is to put the latest Subversion client in the PATH environment variable and then start NetBeans.

NetBeans can suggest variable names

I am lazy and I type rather less than more if needed (which explains why my NetBeans tips are so short...). This applies to developing Java code as well. If the NetBeans editor can help me, I like it. When we create a variable in our Java code we can let NetBeans help us with typing the name of the variable. The following screenshot show the default names NetBeans suggests if we press Ctrl+Space after a type declaration:

The name is simply based on the type of the variable, which can be useful for simple code. We can even start typing the beginning of the variable name and then press Ctrl+Space as shown in the following screenshot and NetBeans will append the suggestion: