Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
package org.apache.camel.example.reportincident;

import java.util.Iterator;
import org.apache.camel.example.reportincident.model.Incident;
import org.apache.camel.example.reportincident.service.IncidentService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.PageParameters;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.markup.repeater.data.IDataProvider;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.spring.injection.annot.SpringBean;

/**
 * Homepage
 */
public class HomePage extends WebPage {

	private static final long serialVersionUID = 1L;

	private static final transient Log LOG = LogFactory.getLog(HomePage.class);

	@SpringBean (1)
	private IncidentService incidentService;

	/**
	 * Constructor that is invoked when page is invoked without a session.
	 * 
	 * @param parameters
	 *            Page parameters
	 */
	public HomePage(final PageParameters parameters) {

		LOG.debug("Spring service : " + incidentService.toString());

		// Add the simplest type of label
		add(new Label("message", "List of incidents coming from web services or file : "));

		// Add paging (2)

		DataView dataView = new DataView("pageable", new IncidentProvider()) { (3)

			@Override
			protected void populateItem(final Item item) { (5) 
				Incident incident = (Incident) item.getModelObject();
				item.add(new Label("incidentId", String.valueOf(incident
						.getIncidentId())));
				item.add(new Label("incidentDate", String.valueOf(incident
						.getIncidentDate())));
				item.add(new Label("incidentRef", incident.getIncidentRef()));
				item.add(new Label("givenName", incident.getGivenName()));
				item.add(new Label("familyName", incident.getFamilyName()));
				item.add(new Label("summary", incident.getSummary()));
				item.add(new Label("details", incident.getDetails()));
				item.add(new Label("email", incident.getEmail()));
				item.add(new Label("phone", incident.getPhone()));
				item.add(new Label("creationUser", incident.getCreationUser()));
				item.add(new Label("creationDate", String.valueOf(incident
						.getCreationDate())));

				item.add(new AttributeModifier("class", true,
						new AbstractReadOnlyModel() {
							@Override
							public Object getObject() {
								return (item.getIndex() % 2 == 1) ? "even"
										: "odd";
							}
						}));
			}
		};
		
        // dataView.setItemsPerPage(20);
        add(dataView);

        // add(new PagingNavigator("navigator", dataView));

	}

	private class IncidentProvider implements IDataProvider { (4)

		public Iterator iterator(int first, int count) {
			return incidentService.findIncident().iterator();
		}

		public int size() {
			return incidentService.findIncident().size();
		}

		public IModel model(Object object) {
			return new Model((Incident) object);
		}

		public void detach() {
			// TODO Auto-generated method stub

		}
	}

	private class IncidentDetachModel extends LoadableDetachableModel {

		private long id;

		@Override
		protected Object load() {
			return incidentService.findIncident(String.valueOf(id));
		}

		/**
		 * @param c
		 */
		public IncidentDetachModel(Incident i) {
			this(i.getIncidentId());
		}

		public IncidentDetachModel(long id) {

			if (id == 0) {
				throw new IllegalArgumentException();
			}
			this.id = id;
		}

	}

}

WicketApplication.java

Remarks :
(1) - The @SpringBean annotation is used to inject our spring IncidentService service
(2) - To set the message label of the HomePage.html, we call the method add(new Label()) and set the property "message" with the information that we want to display on the screen 'List of incidents coming from web services or file'
(3) - To populate the table of the web page, we will use a DataView object. The DataView class requires as a parameter a IncidentDataProvider which is in fact an inner class implementing the interface IDataProvider.
(4) - The class IncidentDataProvider will call our IncidentSaver service to retrieve from the database the list of Incidents reported.
(5) - The populateItem method of the DataView will map the content of our incident objects with the attributes (= items) of the web page

WicketApplication.java

To tell to the Apache Wicket framework that our application contains the page HomePage.html and class HomePage (1), we will create the class WebApplication in the directory src/main/java/org/apache/camel/example/reportincident) like this.

Code Block

package org.apache.camel.example.reportincident;

import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.
Code Block

package org.apache.camel.example.reportincident;

import org.apache.wicket.protocol.http.WebApplication;
import org.apache.wicket.spring.injection.annot.SpringComponentInjector;

/**
 * Application object for your web application. If you want to run this application without deploying, run the Start class.
 * 
 * @see org.apache.wicket.example.Start#main(String[])
 */
public class WicketApplication extends WebApplication
{    
	
	/**
	 * Init
	 */
    public void init() {
        super.init();
        addComponentInstantiationListener(new SpringComponentInjector(this)); (2)
    }

	
    /**
     * Constructor
     */
	public WicketApplication()
	{
	}
	
	/**
	 * @see org.apache.wicket.Application#getHomePage()
	 */
	public Class<HomePage> getHomePage() (1)
	{
		return HomePage.class;
	}

}

Step 3 : web.xml configuration

Tip

To inject Spring into Wicket, we have used the approach described on the following web site of Apache Wicki documentation and added the line addComponentInstantiationListener(new SpringComponentInjector(this)); into the class (2)

Step 3 : web.xml configuration

Now that the code/web pages are ready, we have to create the web.xml file in the directory src/main/webapp/WEB-INF

Code Block
xml
xml

<?xml version="
Code Block
xmlxml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	version="2.4">

	<display-name>reportincident.web</display-name>

	<context-param>
		<param-name>contextClass</param-name>
		<param-value>org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext</param-value> (2)
	</context-param>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> (1) 
	</listener>

	<filter>
		<filter-name>camel.example.reportincident.web</filter-name>
		<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
		<init-param>
				    <param-name>applicationClassName</param-name>
				    <param-value>org.apache.camel.example.reportincident.WicketApplication</param-value>
				<param-name>applicationFactoryClassName</param-name>
				<param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value>
    	</init-param>
	</filter>
	<filter-mapping>
		<filter-name>camel.example.reportincident.web</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


</web-app>

    <param-name>applicationFactoryClassName</param-name>
		    <param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value> (1)
    	</init-param>
	</filter>
	<filter-mapping>
		<filter-name>camel.example.reportincident.web</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>


</web-app>

Remarks :

(1) - Wicket applications have a global application object which is a subclass of Application. This global application object is only created once per application and is never serialized (since it contains no user-specific data and thus remains the same across all nodes in the cluster). These qualities make it a good candidate to act as a service locator for the rest of the application. Wicket allows you to provide a custom factory for creating this object, the wicket-contrib-spring project provides such a factory (SpringWebApplicationFactory) that, instead of creating an instance, pulls it out of the spring application context. Wicket keeps the instance of the application object in a threadlocal variable and provides various helper methods in components to get to it, so it is easy to retrieve dependencies in wicket components. 
(2) - Spring DM provides a dedicated, OSGi-aware, web application context (called OsgiBundleXmlWebApplicationContext) that offers the same functionality and behaviour to its Spring-MVC brethren, XmlWebApplicationContext. The application context is aware of the web application BundleContext  and thus is able to load resources from the OSGi space, import and export OSGi services and support the BundleContextAware and component scanning across the bundles included in the classpath.

Step 4 : Add spring stuffs

To allow our web bundle to have access to the osgi (1) service org.apache.camel.example.reportincident.service.IncidentService, we have to add the following line in the file called }} applicationContext that we create in the directory {{src/main/webapp/WEB-INF.

Code Block
xml
xml
<?xml version="1.0"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/osgi
                    http://www.springframework.org/schema/osgi/spring-osgi.xsd">
                    
 <osgi:reference id="incidentService" interface="org.apache.camel.example.reportincident.service.IncidentService"/> (1)
 
</beans>

...

"org.apache.camel.example.reportincident.service.IncidentService"/> (1)
 
</beans>

Step 4 : Adapt the pom.xml file

The pom of this project is different from the bundles projects because :
(1) - the packaging here is war and not bundle,
(2) - The MANIFEST.MF file generated must be copied in the WAR
(3) - we must tell to maven that the plugin in charge to generate the MANIFEST.MF file must be called during the goal/phase : process-classes
(4) - we want to define the web application context <Webapp-Context> who will be published by PAX Web

Code Block
xml
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>org.apache.camel.example</groupId>
	<artifactId>reportincident.web</artifactId>
	<packaging>war</packaging> (1)
	<version>1.0-SNAPSHOT</version>
	<name>Report Incident Web Bundle</name>

	<properties>
		<wicket.version>1.3.5</wicket.version>
		<jetty.version>6.1.4</jetty.version>
		<felix-version>1.4.3</felix-version>
		<spring-version>2.5.6</spring-version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.apache.camel.example</groupId>
			<artifactId>reportincident.service</artifactId>
			<version>1.0-SNAPSHOT</version>
			<scope>provided</scope>
		</dependency>
		
		<!-- SPRING DEPENDENCIES -->
	    <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring-version}</version>
			<scope>provided</scope>
		</dependency>
	    <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring-version}</version>
			<scope>provided</scope>
		</dependency>
		<!-- 
	    <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-version}</version>
			<scope>provided</scope>
		</dependency>
		 -->
		<!--  WICKET DEPENDENCIES -->
		<dependency>
			<groupId>org.apache.wicket</groupId>
			<artifactId>wicket</artifactId>
			<version>${wicket.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.apache.wicket</groupId>
			<artifactId>wicket-spring-annot</artifactId>
			<version>${wicket.version}</version>
			<scope>provided</scope>
		</dependency>
        <dependency>
            <groupId>org.apache.wicket</groupId>
			<artifactId>wicket-extensions</artifactId>
			<version>${wicket.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- LOGGING DEPENDENCIES - LOG4J -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.4.2</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.14</version>
			<scope>test</scope>
		</dependency>

		<!--  JUNIT DEPENDENCY FOR TESTING -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.2</version>
			<scope>test</scope>
		</dependency>

		<!--  JETTY DEPENDENCIES FOR TESTING  -->
		<dependency>
			<groupId>org.mortbay.jetty</groupId>
			<artifactId>jetty</artifactId>
			<version>${jetty.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.mortbay.jetty</groupId>
			<artifactId>jetty-util</artifactId>
			<version>${jetty.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.mortbay.jetty</groupId>
			<artifactId>jetty-management</artifactId>
			<version>${jetty.version}</version>
			<scope>provided</scope>
		</dependency>
	</dependencies>
	<build>
		<resources>
			<resource></dependency>
	</dependencies>
	<build>
		<resources>
			<resource>
				<filtering>false</filtering>
				<directory>src/main/resources</directory>
			</resource>
			<resource>
				<filtering>false</filtering>
				<directory>src/main/java</directory>
				<includes>
					<include>**</include>
				</includes>
				<excludes>
					<exclude>**/*.java</exclude>
				<filtering>false<</filtering>excludes>
				<directory>src/main/resources</directory></resource>
			</resource>resources>
		<testResources>
			<resource><testResource>
				<filtering>false</filtering>
				<directory>src/maintest/java</directory>
				<includes>
					<include>**</include>
				</includes>
				<excludes>
					<exclude>**/*.java</exclude>
				</excludes>
			</resource>testResource>
		</resources>testResources>
		<plugins>

			<plugin>
				<inherited>true</inherited>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
		<testResources>
			<testResource><source>1.5</source>
					<filtering>false<<target>1.5</filtering>target>
				<directory>src/test/java</directory>	<optimise>true</optimise>
				<includes>	<debug>true</debug>
					<include>**</include>configuration>
				</includes>plugin>

				<excludes><plugin>
					<exclude>**/*.java</exclude><groupId>org.mortbay.jetty</groupId>
				</excludes><artifactId>maven-jetty-plugin</artifactId>
			</testResource>
		</testResources>
		<plugins>plugin>


			<plugin>
				<inherited>true</inherited>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compilerwar-plugin</artifactId>
				<configuration>
					<source>1.5</source>
					<target>1.5</target><version>2.1-alpha-2</version>
					<optimise>true</optimise><configuration>
					<debug>true</debug><archive>
						</configuration>!-- add the generated manifest to the war --> (2)
			</plugin>

			<plugin><manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
				<groupId>org.mortbay.jetty</groupId>	</archive>
				<artifactId>maven	<!-jetty-plugin</artifactId> 
				</plugin>


	<webResources>
						<plugin><resource>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId><directory>src/main/resources/META-INF/spring</directory>
				<version>2.1-alpha-2</version>
			<targetPath>META-INF/spring</targetPath>
						<configuration></resource>
					<archive></webResources>
						<!-- add the generated manifest to the war -->
						<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
					</archive>configuration>

			</plugin>


			<!-- to generate the MANIFEST-FILE required by the bundle -->
			<plugin>
		<webResources>
		<groupId>org.apache.felix</groupId>
				<resource><artifactId>maven-bundle-plugin</artifactId>
							<directory>src/main/resources/META-INF/spring</directory>
<version>${felix-version}</version>
				<extensions>true</extensions>
				<targetPath>META-INF/spring</targetPath><executions> (3)
					<execution>
	</resource>
					<<id>bundle-manifest</webResources>id>
						 --><phase>process-classes</phase>
				</configuration>

			</plugin><goals>

			<plugin>
				<groupId>org.apache.maven.plugins</groupId><goal>manifest</goal>
				<artifactId>maven-eclipse-plugin</artifactId>
				<configuration></goals>
					<downloadSources>true<</downloadSources>execution>
				</configuration>executions>
			</plugin>

			<!-- to generate the MANIFEST-FILE required by the bundle -->	<configuration>
					<supportedProjectTypes>
			<plugin>
				<groupId>org.apache.felix</groupId>
<supportedProjectType>bundle</supportedProjectType> (3)
						<artifactId>maven-bundle-plugin</artifactId>
<supportedProjectType>war</supportedProjectType>
					<version>${felix-version}</version>supportedProjectTypes>
				<extensions>true</extensions>	<instructions>
				<executions>		<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
					<execution>	<Bundle-ClassPath>
							<id>bundle-manifest</id>
.,
							<phase>processWEB-classes<INF/phase>classes,
						<goals></Bundle-ClassPath>
							<goal>manifest</goal>
<Import-Package>
							</goals>
javax.servlet;version="[2.5.0, 3.0.0)",
							</execution>javax.servlet.http;version="[2.5.0, 3.0.0)",
				</executions>			javax.servlet.resources;version="[2.5.0, 3.0.0)",
				<configuration>
			org.apache.camel.example.reportincident.service,
		<supportedProjectTypes>
						<supportedProjectType>bundle</supportedProjectType>org.springframework.web.context;version="[2.5.6, 3.0.0)",
						<supportedProjectType>war</supportedProjectType>
					</supportedProjectTypes>	org.springframework.web.context.support;version="[2.5.6, 3.0.0)",
					<instructions>
						<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
		org.springframework.osgi.web.context.support,
							<Bundle-ClassPath>org.xml.sax;resolution:=optional,
							.org.w3c.dom;resolution:=optional,
							WEB-INF/classes,*
						</BundleImport-ClassPath>Package>
						<Import-Package>
							javax.servlet;version="[2.5.0, 3.0.0)",<Private-Package>org.apache.camel.example.reportincident</Private-Package>
							javax.servlet.http;version="[2.5.0, 3.0.0)",<Export-Package></Export-Package>
							javax.servlet.resources;version="[2.5.0, 3.0.0)",<Webapp-Context>reportincidentweb</Webapp-Context> (4)
							org.apache.camel.example.reportincident.service,<_failok>true</_failok>
					</instructions>
							org.springframework.web.context;version="[2.5.6, 3.0.0)",
							org.springframework.web.context.support;version="[2.5.6, 3.0.0)",
							org.springframework.osgi.web.context.support,
							org.xml.sax;resolution:=optional,
							org.w3c.dom;resolution:=optional,
							*
						</Import-Package>
						<Private-Package>org.apache.camel.example.reportincident</Private-Package>
						<Export-Package></Export-Package>
						<Webapp-Context>reportincidentweb</Webapp-Context>
						<_failok>true</_failok>
					</instructions>
				</configuration>

			</plugin>
		</plugins>
	</build>
</project>

...

</configuration>

			</plugin>
		</plugins>
	</build>
</project>

Remark : To deploy the war in your maven repository, execute the following maven command

Code Block
mvn clean install

Build and Package the application

Build

To build the project, you must execute for each project the following maven commands :

Project name

maven command

reportincident.activemq

clean install org.ops4j:maven-pax-plugin:eclipse

reportincident.camelqueueservice

clean install org.ops4j:maven-pax-plugin:eclipse

reportincident.db

mvn clean install

reportincident.features

mvn clean install

reportincident.model

mvn clean install org.ops4j:maven-pax-plugin:eclipse

reportincident.persistence

mvn clean install org.ops4j:maven-pax-plugin:eclipse

reportincident.routing

mvn clean install org.ops4j:maven-pax-plugin:eclipse

reportincident.service

mvn clean install org.ops4j:maven-pax-plugin:eclipse

reportincident.web

mvn clean install

reportincident.webservice

mvn clean install org.ops4j:maven-pax-plugin:eclipse

Info

We will try to provide for the next version of this tutorial a parent pom.xml containing the modules list to be build (wink)

Package

To simplify our deployment procedure, we will use the provisioning mechanism of Apache Servicemix called 'Feature'. In a feature xml file, we will define the bundles that we will package and their dependencies. The bundles can be linked to a feature and features can be linked together. This file will be packaged in a jar.

...