...
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 |
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 version=" | ||||
Code Block | ||||
xml | xml | <?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 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 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 |
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.
...