DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

The Latest Frameworks Topics

article thumbnail
Reload Your Plugins Without Restarting Eclipse
When you are developing Eclipse plugins, sometimes its annoying that the changes in the plugin.xml won't reflect immediately. You need to restart the target Eclipse to see the changes. This will be painful if you are playing with trial-n-error stuff like the menu urls. In this tip, I'll explain how to make Eclipse reread your plugin.xml without restarting the target. Create a plugin, launch as an Eclipse Application (you don't even need to Debug, just Run would do) Check the UI contributions of your plugin. Make the desired change in your plugin.xml. Right now, I've changed a Command's name; added a Command contribution to an existing menu; added a new view and made changes to an existing perspective In your target, open the Plug-ins Registry view and in the pull down menu, check the 'Show Advanced Operations' Right click your plugin and select Disable. Then right click again and select Enable. Since you have made changes to the current perspective by adding a view, you would be greeted with this Dialog. Say Yes. There you go. Now all the changes in the plugin.xml would reflect in the UI While this may not be applicable for all the changes you make in plugin.xml, this should cover up for most the changes From http://blog.eclipse-tips.com
December 2, 2009
by Prakash
· 13,314 Views
article thumbnail
Integrating JBoss RESTEasy and Spring MVC
Building websites is a tough job. It's even tougher when you also have to support XML and JSON data services. Developers need to provide increasingly sophisticated AJAXy UIs. Marketing groups and other business units are becoming more savvy to the benefits of widgets and web APIs. If you're a Java developer who needs to implement those sexy features, you're likely going to accomplish that work with a dizzying variety of frameworks for web development, data access and business logic. The Spring Framework has a strong presence based on the premise of seamless (no pun intended) integration of all of those frameworks. The Spring framework integrates with a host of JEE standard technologies, such as EJBs and JSP. Spring MVC is a sub-project of the larger Spring Framework that has its own Controller API and also integrates other web development frameworks such as JSF, Struts and Tiles. While the Spring Framework also integrates with new JEE technologies as they develop, however, for a variety of reasons the Spring framework has not integrated with the tour de force JAX-RS standard which delivers an API for constructing RESTful services. There are six implementations of the JAX-RS standard, and each provides some level of integration with Spring. Most of those integrations work with the Spring framework proper, but don't take advantage of the benefits of Spring MVC. JBoss RESTEasy integrates with both the Spring Framework proper and also with the Spring MVC sub-project. In this article, we're going to explore how to use RESTEasy along with Spring MVC application. We'll deep dive into the internals of Spring MVC, we'll discuss JAX-RS and how they related to MVC web development. We'll also touch on quite a few technologies beyond Spring MVC and RESTEasy, including Jetty and maven. We're also going to discuss theoretical concepts relating to REST and Dependency Injection. This article has to cover quite a bit of ground and you'll be gaining quite a few tools you can use to develop complex web applications. If you follow this article, you'll be constructing an end-to-end web application, however, feel free to skim the article to find material that's relevant to you. REST and JAX-RS REST has been an increasingly trendy topic over the last three years. We as a development community have been looking at REST as an effective way to perform distributed programming and data-oriented services. In fact, the Java community's REST leaders got together and created a standard spec to standardize some RESTful ideas in JSR 311 - JAX-RS the Java API for XML and RESTful Services. The focus of JAX-RS was to create an API that Java developers could use to perform RESTful data exchanges. However, the Java community quickly saw the similarities between JAX-RS and MVC (Model View Control) infrastructures. James Strachan, a long time Java community member and open source contributor (to things like DOM4J, Groovy - he created the language, and recently the Apache Camel and CXF ESBs) suggested that JAX-RS as the one Java web framework to rule them all?. Jersey, the production ready JAX-RS reference implementation, has a built in JSP rendering mechanism. The RESTEasy community built a similar mechanism in HTMLEasy. The Jersey and and HTMLEasy approaches work well for simpler websites, but they don't solve some of the more complex needs of an application. If you want more complex functionality, you'll need a more sophisticated web-development platform, such as Spring MVC. A combination of Spring MVC and RESTEasy will have the following benefits compared to the simpler approaches: Session based objects Freedom of choice - chose the right tool for the job Spring MVC integrates with a whole bunch of MVC frameworks, including Spring MVC, Struts2 and now RESTEasy Spring MVC integrates with a whole bunch of View frameworks, including JSP, JSF, Tiles and much more Integrated AJAX components - the freedom of choice can make end-to-end AJAX calls a breeze, assuming you chose the appropriate framework More control over URL mapping This article tackles some more advanced topics. If you want some relevant background, we have a reference section at the end of this article. Before we take a look at code, let's take a more in depth view of Spring MVC. Spring MVC Spring MVC is broken down into three pluggable sub-systems: Handler Mapping - Map a URL to Spring Bean/Controller. Spring allows quite a few methods to perform this mapping. It can be based on the name of a Spring bean, it could be a URL to bean map, it could be based on an external configuration file or it could be based on annotations. Handler Mappings allow you to configure complex mappings without resorting to complex web.xml files. Handler Adapter - Invoke the Controller. Hander Adapters know what type of spring beans they can call and performs invocations on the types of beans it knows about. There are Handler Adapters for Spring MVC classic, spring @MVC, Struts, Struts2, Servlets, Wicket, Tapestry, DWR and more. View Mapping - Invoke the View. View Mappers know how to translate a logical view name produced by a Controller into a concrete View implementation. A name like "customers" may translate into any of the following technologies: JSP/JSTL, JSF, Velocity, FreeMarker, Struts Tiles, Tiles2, XSLT, Jasper Reports, XML, JSon, RSS, Atom, PDF, Excel, and more RESTEasy plugs into Spring MVC in all three sub-systems. JAX-RS Resources/Controllers are defined by annotations; therefore RESTEasy provides a ResteasyHandlerMapper that knows how to convert a URL to a RESTEasy managed JAX-RS controller method. Once RESTEasy determines which method to invoke, the ResteasyHandlerMapping performs the invocation. The invocation can either be an object, which invokes the default JAX-RS behavior which transforms the resulting Object to a Represetation such as XML or JSON. Additionally, you return a traditional Spring ModelAndView which can refer to a logical view name and a map of data to be rendered by the View. The default JAX-RS behavior creates a ResteasyView which uses JAX-RS's configurable MessageBodyReader and MessageBodyWriter transformation framework. RESTEasy can produce XML and JSON using JAXB, but can be configured to use other view technologies such as Jackson, which is a performant and flexible JSON provider, Flex AMF. This separation of Controller and View concepts allows you to mix and match your Controller and View technologies. RESTEasy Resources can call any Spring managed Views and other Controller technologies can be rendered by a ResteasyView. You can either use RESTEasy as your sole MVC framework, if it fits your needs, or you can augment an existing Controller infrastructure with data services provided by RESTEasy. Just as importantly, you can leverage all of the other functionality that Spring provides, such as DAO abstraction, transaction management and AOP. Your First SpringMVC/RESTEasy Application Before we start reviewing the project, let's review a quick checklist of items we will be reviewing. The project files fall into two categories: configuration and source code. All of the code that will be covered is available in the RESTEasy repository and can be downloaded (as a tar.gz file), or browsed. Here is a list of files that each category will require. Configuration Files: web.xml - servlet configuration with Spring MVC artifacts - Spring MVC's DispatcherServlet, and map to /contacts/* springmvc-servlet.xml - a Spring application context configuration with all of the Spring beans this project needs, including RESTEasy setup (one line) and JSP configuration pom.xml - maven 2 dependency configuration, including required repositories, RESTEasy dependencies and embedded Jetty setup Source Code: The code we're going to show you can be broken down into four layers: Controller - Controlling the flow between the HTTP request, the Model and the View ContactsResource.java - a RESTful Controller with JAX-RS annotations and some traditional HTML controller methods. It will be annotated with Spring's @Controller and @Autowired annotations as well. Model - the domain model and service objects in our case. In our case, we have 2 domain objects: Contact and Contacts; and 1 Service object: ContractService Contact.java - a JAXB domain object with contact information Contacts.java - a JAXB wrapper object that wraps a Contact List ContactService.java - a Map based repository of Contact instances View - How the domain model is transformed for consumer use. JAX-RS performs automated conversion to XML based on annotations on our domain model. We'll be using JSP for object to HTML conversion. contacts.jsp - a bare bones HTML view of our Contacts Test - JAX-RS provides quite a bit of functionality, we're writing quite a bit of code, and all of that is wrapped in quite a bit of configuration. This article will focus on testing our code, configuration and deployment in an automated JUnit test. ContractTest.java - a RESTEasy ReSTful Unit test for the ContractsResource functionality, embedded server included There's a lot of ground to cover, and we'll cover the most interesting pieces of the source first. Our first pass will cover the web.xml and springmvc-servlet.xml configuration files as well as the ContactsResource.java and ContactTest.java source files. Our second pass will cover the remaining topics. Core RESTEasy/Spring MVC artifacts web.xml Spring MVC's entry point is the DispatcherServlet. There are two parts in setting up the DispatcherServlet, the first is to map the servlet to the URL pattern which must follow the rules specified in Section 11.2 of Servlet API Specification. The next step is configure the behavior of the the servlet by providing the configuration file which we call 'springmvc-servlet.xml'. By default, DispatcherServlet looks for a configuration file at "WEB-INF/{servlet-name}-servlet.xml" to find it's configuration, but we're going to use a Spring configuration from the classpath so that the configuration can be reused later in our junit test case. springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc-servlet.xml springmvc /contacts/* All requests will be forwarded to the Spring MVC DispatcherServlet. One can get much more sophisticated, but this is one of the simplest simplest web.xml you can create to integrate with Spring. Note that there isn't any reference here to a RESTEasy servlet. Other JAX-RS/Spring integrations require you to have an implementation specific Servlet to serve XML or JSon and a separate Spring MVC DispatcherServlet mapping to server HTML requests. RESTEasy integrates with DispatcherServlet to allow Spring MVC to direct the URL to either RESTEasy Resources or Spring MVC Controllers. Next, let's take a look at the Spring MVC configuration. springmvc-servlet.xml In our basic project, there are five things we need to do in the springmvc-servlet.xml file. Register the Spring namespace Register the package(s) to scan for Spring MVC annotations. Configure the context annotation processor. Import the springmvc-resteasy.xml configuration file which specifies the default RESTEasy/Spring MVC integration Spring beans. Configure the ViewResolver bean to configure the presentation layer to use JSP. Let's inspect the springmvc-servlet.xml file and focus on each of the above items. The springmvc-servlet.xml file itself is pretty short and shows off some of the features from Spring 2.5: Demystifying the Spring Configuration Spring allows for custom namespaces to reduce the verbosity of the configuration files. We make use of the namepsace by registering it in lines 3 and 4. Line 6 (component-scan) informs spring about which package(s) we want to scan and create the custom component object instances, such as controllers and service objects. We tell Spring about the packages we're interested in by using the custom namespace and set the base-package attribute with the packages we're interested in (org.jboss.resteasy.examples.springmvc ). Later on, you'll see that we're going to be using two Spring annotations that allow the Spring runtime to glean Dependency Management information directly from the object itself: @Controller and @Service. Line 7 (annotation-config) tells Spring that our application will be using annotations on how to configure the beans created by the (component-scan) operation of line 6. Spring looks for annotations such as Spring's @Autowired and @Required; JEE's @Resource; and JPA's @PersistenceContext and @PersistenceUnit to describe dependencies between bean instances. annotation-configSpring also looks for life-cycle annotations such as JSR 250's @PostConstruct and @PreDestroy. Our environment requires a dependency between our Controller and Service objects, and the annotation-config declaration will assist us to configure that relationship in Java code. Line 8 (import) is all the XML that is necessary to configure a RESTEasy environment in Spring MVC. The nice thing about the integration with RESTEasy is that most of the configuration is done for you within an embedded configuration file called springmvc-resteasy.xml. Lines 9-14 tell Spring how we intend to handle the rendering of our presentation layer. In our case, we want to use JSTL views that translate view names (such as "contact") to a JSP page found in the /WEB-INF/ directory (specifically /WEB-INF/contacts.jsp in our case). For more information about setting up Spring views, take a look at the spring documentation. Next, let's take a look at how you can mix and match Spring and JAX-RS annotations in a Controller/Resource. ContactsResource.java MVC Controllers control the flow between the Model and the View. Resource is REST's equivalent to Controllers, and we'll be using the term Resource and Controller interchangably. In our case, our resource handles requests to /contracts and /contracts/{id}. Our ContractsResource must perform quite a few functions on those two URL templates: Retrieve all Contacts - Display the results in either HTML, XML or JSon. For clarity, we'll break out the data oriented functionality (XML and JSon) from the user oriented functionality (HTML) into two distinct URLs - /contacts for HTML and /contacts/data for XML and JSon. REST allows a client to select which format it prefers to receive the data in through a process called Content Negotiation. Content Negotiation can happen through HTTP headers, URI or query parameters. Our ContractsResource will use different URIs to differentiate between data oriented and user views, and will use HTTP headers to differentiate between XML and JSon data views. Save a Contact - Create or Updating data is a pretty standard requirement. The Save a Contact functionality mirrors the Content Negotiation needs of Retrieve all Contacts. User oriented data exchange comes in the form of HTML form data, and data oriented exchange usually occurs in XML and JSon. These differing requirements require ContractResource to have two distinct JAX-RS Java methods; we'll also separate the URLs for clarity purposes. View a Contact - We'll create a single view for viewing a single contact that returns XML or JSon. We leave the user oriented view as an exercise for the reader. Here's another view of our requirements: Functionality URL Format Java Method User Oriented View All /contacts HTML viewAll() Data Oriented View All /contacts/data XML or JSon getAll() User Oriented Save /contacts/ Form data saveContactForm() Data Oriented Save /contacts/data XML or JSon saveContact() Data Oriented View Single /contacts/data/{lastName} XML or JSon get() Note that we mixed and matched HTML and data oriented functionality in this requirement. Now that we have our requirements in place, let's take a look at the ContactsResource code. There are quite a few new Spring and JAX-RS annotations which we'll explain right after the code: @Controller @Path(ContactsResource.CONTACTS_URL) public class ContactsResource { public static final String CONTACTS_URL = "/contacts"; @Autowired ContactService service; @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("data") public Contacts getAll() { return service.getAll(); } @GET @Produces(MediaType.TEXT_HTML) public ModelAndView viewAll() { // forward to the "contacts" view, with a request attribute named // "contacts" that has all of the existing contacts return new ModelAndView("contacts", "contacts", service.getAll()); } @PUT @POST @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("data") public Response saveContact(@Context UriInfo uri, Contact contact) throws URISyntaxException { service.save(contact); URI newURI = UriBuilder.fromUri(uri.getPath()).path(contact.getLastName()).build(); return Response.created(newURI).build(); } @POST @PUT @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.TEXT_HTML) public ModelAndView saveContactForm(@Form Contact contact) throws URISyntaxException { service.save(contact); return viewAll(); } @GET @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) @Path("data/{lastName}") public Contact get(@PathParam("lastName") String lastName) { return service.getContact(lastName); } } This code is packed with annotations and Java code that's indicative of JAX-RS Resources and Spring applications. There is also a RESTEasy custom annotation. The Spring IoC annotations are well documented, but we are using them in unusual ways for our integration: @Controller tells the Spring runtime that it needs to create an instance of ContractsResource at startup time. Do you remember the component-scan directive that was used in the Spring configuration section? The combination of the directive and the annotation tell Spring that a singleton instance of ContractsResource must be created at startup. Spring has a more generic @Component, but the use of @Controller allows for more precise definition of bean usage and also allows for future upgrades that involve AoP to create more precise targeting. While @Controller is usually associated with Spring @MVC annotated controllers and not other Controller infrastructures, but even thought it's not a Spring MVC controller, we use it to tell Spring that this indeed is a Controller That association of @Controller to Spring MVC annotated controllers is a loose coupling in the Spring runtime. We'll use JAX-RS annotations to configure the handling of URL and HTTP handling behavior. You could theoretically add additional Spring @MVC annotations such as @RequestMapping (which is an equivalent of JAX-RS @Path) to our ContactsResource, if you really wanted to @Autowired tells the Spring runtime that instances of ContractResource require an instance of ContactService. We'll be coding the ContactService later in this article. You can take a look at the Spring reference documentation for more information about @Autowired and @Controller. The last Spring artifact that we use is ModelAndView: It is Spring MVC's encapsulation of which logical View to use and which Model variables should be passed into the View. In our case, we're going to create a Model variable called "contacts" that is a List of all Contact objects we have in the system. We're passing that variable to the a logical view named "contacts" which will map to "/WEB-INF/contacts.jsp" based on the Spring configuration that we previously discussed. The JAX-RS annotations are also well documented, but it's definitely worth while to give a brief overview: @Path tells the RESTEasy (or other JAX-RS environments) how to map URLs to java methods. Adding @Path at the class level tells, in our case "/contacts", indicates that all methods must be prefixed with that URL. The @Path value can either be a hard coded URL such as "/contacts" or it can be a URI template such as "data/{lastName}". You can even specify regular expressions for more sophisticated filtering in the URI template. @GET, @PUT and @POST are used in combination with @Path to indicate which specific HTTP methods are handled by individual Java methods @Produces and @Consumes are used to further filter how a request should be handled based on content negotiation based on the Accept and Content_Type HTTP header. JAX-RS provides a set of default mime type values in the MediaType class. @PathParam is a method parameter annotation that indicates how a URI template variable is mapped to a method parameter. There are quite a few other method parameter level annotations that you could use to map HTTP headers, cookies, query parameters and form parameters to member variables @Context is an interesting JAX-RS parameter that allows dependency injection of request level information such as HttpRequest, HttpResponse and UriInfo (which as you can probably guess encapsuldates information about the request URI). It's important to note that Spring by default manages beans such as ContactsResource as a singleton; if ContactsResource was a Prototype or Request scoped bean, you would be able to use the @Context annotation on member variables in addition to method variables. For more on Spring scoping see the Spring Framework documentation. The last annotation we need to talk about is @Form. It's a RESTEasy custom annotation that describes that a member variable encapsulates data from HTML forms. If you recall, we used the JAX-RS @FormParam annotation on our Contact domain object. @Form and @FormParam are used in concert to allow for better maintenance of form based processing systems. JAX-RS 2.0's stated goals include a more robust, uniform Form processing annotation system. The functionality to code ratio is pretty high because of all of the declarative coding conventions of these annotations. Now that we've discussed the most involved pieces of the puzzle, let's take a look at completing the project. Additional Artifacts pom.xml Our pom.xml includes dependency management, description of required Maven repositories, a description of which JDK we're going to use and a Jetty web server configuration. We'll cover the repository selection, the dependencies specific to RESTEasy and a jetty-maven integration External Repositories jboss jboss repo http://repository.jboss.org/maven2 scannotation http://scannotation.sf.net/maven2 java.net http://download.java.net/maven/1 legacy maven repo maven repo http://repo1.maven.org/maven2/ Project Dependencies Now that we've informed Maven which additional repositories are required, we can now include the dependencies the our sample project will require. The section of the pom.xml file, should include the following two dependencies for Spring and RESTEasy functionality - resteasy-spring and resteasy-jaxb-provider: org.jboss.resteasy resteasy-spring 1.2.RC1 org.jboss.resteasy resteasy-jaxb-provider 1.2.RC1 org.mortbay.jetty maven-jetty-plugin 6.1.15 test The resteasy-spring dependency includes the adapter that integrates RESTEasy into Spring's MVC and provides most the required Java dependencies for RESTEasy and Spring. It also contains Spring configuration needed within the embedded spring-resteasy.xml file that will be used in the Spring configuration section. The other RESTEasy dependency that's included, resteasy-jaxb-provider, contains classes that convert the payload into various formats before sending it to the client. The last dependency to focus on is the maven-jetty-plugin which allows us to easily startup our project in a Jetty webserver environment. Note: If you're follow the link above to the RESTEasy repository's version of pom.xml, you will have to modify the version of resteasy-spring and resteasy-jaxb-provider to the latest version that has been deployed, specifically 1.2.RC1 at the time this article was written. The RESTEasy repository contains a soon-to-be-deployed version number which will not work unless you build the entire RESTEasy project. Maven Jetty Plugin One last interesting item of pom.xml is the configuration of the Jetty web server resteasy-springMVC org.mortbay.jetty maven-jetty-plugin 6.1.15 / 2 ... This will allow us to startup Jetty against localhost:8080. You can learn more about the maven Jetty plugin and a variety of configuration options. Let's start with the domain model and move on to the service object. From there, we'll discuss the JAX-RS Resource/Controller. From there, we'll explore the unit test and finally we'll write the JSP View and start up our server. Contact.java Our DTO is going to be deceptively simple. It will perform a dual responsiblity of JAXB XML binding and Form parameter binding. Both sets of functionality will be configured through annotations and will be managed through JAXB and JAX-RS: import javax.ws.rs.FormParam; import javax.xml.bind.annotation.XmlRootElement; @XMLRootElement public class Contact { private String firstName, lastName; // default constructor for JAXB (also required by JPA/Hibernate if you use them) public Contact(){} // helper constructor for our Controller/Service operations public Contact(String firstName, String lastName){ this.firstName = firstName; this.lastName = lastName; } @FormParam("firstName") public void setFirstName(String firstName) { this.firstName = firstName; } public String getFirstName() { return firstName; } @FormParam("lastName") public void setLastName(String lastName) { this.lastName = lastName; } public String getLastName() { return lastName; } // equals and hasCode are added for the Map based Service object public boolean equals(Object other){ .. } public long hashCode(){ .. } } The annotation on the setters tells JAX-RS to bind any incoming form parameters to the appropriate setter. The @XMLRootElement annotation is enough to tell JAXB that the Contract object must be bound to getters and setters must be bound to an XML document that will look like: Richard Burton Contacts.java The Contacts class is a simple wrapper around a List of Contact instances: @XmlRootElement public class Contacts { private Collection contacts; public Contacts() { this.contacts = new ArrayList(); } public Contacts(Collection contacts) { this.contacts = contacts; } @XmlElement(name="contact") public Collection getContacts() { return contacts; } public void setContacts(Collection contact){ this.contacts = contact; } } Contacts has the @XmlRootElement, just like Contact. The @XmlRootElement annotation tells JAXB to transform objects of this type to an XML structure that has as its top level element. In addition, we've added the @XmlElement annotation to the getContacts() method. By default, JAXB renders all JavaBean elements and uses the JavaBean name as the element. JAXB handles Lists as special cases: all List elements are translated to XML elements using the JavaBean name. @XmlElement(name="contact") tells JAXB that we opted to override the default name ("contracts") in favor of our own name ("contract" - no 's'). The Contracts object will bind to XML that looks like: Richard Burton Solomon Duskis Now that we have our Domain model in place, let's start using it in our Service tier. ContactService.java Since the purpose of this article is JAX-RS centric, we're not going to create an elaborate service layer, but we'll add once since creating more robust Spring applications do require service or data access layers. If you're interested in seeing a RESTEasy/Spring application with database access, look here. Our ContractService performs simple in-memory storage of Contacts by last name: @Service public class ContactService { private Map contactMap = new ConcurrentHashMap(); public void save(Contact contact){ contactMap.put(contact.getLastName(), contact); } public Contact getContact(String lastName){ return contactMap.get(lastName); } public Contacts getAll() { return new Contacts(contactMap.values()); } } There are two items of interest that are noteworthy: Notice the use of Spring's @Service annotation. Do you remember the component-scan directive that was used in the Spring configuration section? The combination of the directive and the annotation tell Spring that a singleton instance of ContractService must be created at startup. Spring has a more generic @Component, but the use of @Service allows for more precise definition of bean usage and also allows for future upgrades that involve AoP to create more precise targeting. Notice the use of ConcurrentHashMap. It's a JDK 1.5 addition that adds performance in multi-threaded environments. It's an easy way to boost performance in distributed REST applications Next, let's take a look at the JSP that contacts.jsp We've explored the Model and Controller aspects of MVC. The last piece to the puzzle is the View. Most JAX-RS based interactions perform a more automated conversion of objects like our Contact to a data-oriented view, such as XML or JSon. Traditionally, Java EE MVC has been done with a more manual View management with languages such as JSP. Our JSP will take a Contracts instance created in ContractsResources.viewAll() and render it in basic HTML: Hello Contacts! Hello ${contact.firstName} ${contact.lastName} Save a contact, save the world: First Name: Last Name: This JSP loops over all contacts and adds links to their data-oriented View. It also creates a simple HTML form for creating a new Contact. While this JSP is simple, it will help us exercise three of our ContactsResource Controller: viewAll(), .saveContactForm(), and get(). It could also be a spring board for more complicated AJAX/JSon interaction, but that's beyond the scope of this article. The code and configuration is now complete, so let's run this project! Jetty Running Jetty is rather simple. You've seen most of the details of the pom.xml when we previously discussed it. Running jetty through maven involves running the following command: mvn jetty:run (If you haven't done so already, download the file as a tar ball, and change the pom.xml's version of the two RESTEasy dependencies to 1.2.RC1) That command will launch Jetty, and allow you to browse our project at http://localhost:8080/contacts. Add a few contacts, and view them either as a group at /contacts in HTML, as a group in XML at /contact/data, or individually as XML by following the links found at /contacts. Congratulations. You now have a running Spring MVC/RESTEasy application. We need one more thing to consider this application complete: a JUnit test. ContractTest.java RESTEasy provides a mechanism for easily launching a Spring MVC/RESTEasy application. RESTEasy also comes with a robust REST client framework. This article will cover bits and pieces of the test, but you can view the entire code in the RESTEasy SVN. To start, we're going to set up an interface that the RESTEasy client can use to create a client for our application. It consists of abstract methods annotated with JAX-RS annotations: @Path(ContactsResource.CONTACTS_URL) public interface ContactProxy { @Path("data") @POST @Consumes(MediaType.APPLICATION_XML) Response createContact(Contact contact); @GET @Produces(MediaType.APPLICATION_XML) Contact getContact(@ClientURI String uri); @GET String getString(@ClientURI String uri); } All methods on ContactProxy inherit the ContactsResource.CONTACTS_URL path ("/contacts") as the root URL, just like a server-side JAX-RS resource. This interface's has three methods: Create a contact - the createContact method maps to a POST to "/contacts/data". The method accepts a Contact object which will be converted to XML before it's sent to the server. The result is a JAX-RS Response object which contains the response status and headers. One of those headers includes the LOCATION of the new contact Get an XML Contact - Given a URL to a Contact, such as the URL returned by the createContact method's response's LOCATION header, GET an XML response and create a Contact object from it. Get a Response as a String - Given a URL, such as a Contact URL or anything else on the server, retrieve a String result. This interface will be used by RESTEasy to construct a concrete instance that uses the JAX-RS annotations to perform the actual HTTP calls. Next, let's create the embedded server and use RESTEasy to create that instance of a ContactProxy: private static ContactProxy proxy; private static TJWSEmbeddedSpringMVCServer server; public static final String host = "http://localhost:8080/"; @BeforeClass public static void setup() { server = new TJWSEmbeddedSpringMVCServer("classpath:springmvc-servlet.xml", 8080); server.start(); RegisterBuiltin.register(ResteasyProviderFactory.getInstance()); proxy = ProxyFactory.create(ContactProxy.class, host); } @AfterClass public static void end() { server.stop(); } JUnit invokes methods annotated by @BeforeClass before any test methods run. Methods annotated by @AfterClass are triggered by JUnit before after all test methods are complete. In our case, the setup method will instantiate a server that contains a SpringMVC Servlet on port 8080 that is configured by the same Spring XML configuration file we used in Jetty. It also invokes the two lines of code required to create a RESTEasy client. RegisterBuiltin sets up the RESTEasy run time, and must be run one time per client. ProxyFactory.create tells RESTEasy to read the annotations on the ContactProxy interface and to create a Java Proxy instance that knows how to perform the HTTP requests we'll need for our test: @Test public void testData() { Response response = proxy.createContact(new Contact("Solomon", "Duskis")); String duskisUri = (String) response.getMetadata().getFirst(HttpHeaderNames.LOCATION); Assert.assertTrue(duskisUri.endsWith(ContactsResource.CONTACTS_URL + "/data/Duskis")); Assert.assertEquals("Solomon", proxy.getContact(duskisUri).getFirstName()); ... } This test creates a new Contact, checks the server's response to make sure that the URL is consistent with the test's expectations. It then re-retrieves the Contact and confirms that the firstName is indeed what was sent sent in. While this is a pretty trivial looking test, it performs quite a bit of HTTP activity and business logic. Conclusion This article discussed quite a bit of philosophy and design considerations in building a RESTful web application with RESTEasy and Spring MVC. We also built an end to end application with RESTEasy, Spring MVC, Maven, Jetty and JUnit. Even though the content in this article was significant, the code presented here is relatively short compared to other Java alternatives. We touched on subjects like designing REST Applications, creating Spring applications, the RESTEasy client infrastructure and testing RESTful applications. Each of those subjects merit their own articles. There were also other subjects that we simply couldn't fit into this article (as long as it is), including JavaScript to the toolkit to allow closer integration between the browser and your RESTful application, integrating with Flex and more. The code presented in this article can serve as a spring board (again, no pun intended) for all of those ideas. About the Authors Solomon Duskis Solomon Duskis is a Senior Manager at SunGard Consulting Services. He's been developing for 22 years -- 12 years in professional capacity. He has experience in various industries such as Finance, Media, Insurance and Health. He contributes to Open Source projects such as JBoss Resteasy and the Spring framework. He is a published author of Spring Persistence - A Running Start, and the upcoming book Spring Persistence with Hibernate. Richard Burton Richard Burton is the co-founder of a small independent consulting firm called SmartCode LLC. He is an Open Source fanatic with over 10 years of experience in various industries such as Automotive, Insurance, Finance and fondly remembers the .com era. In his spare time, he contributes to Open Source projects such as SiteMesh 3, Struts 2, and more. Reference REST Roy Fielding's REST Thesis - Architectural Styles and the Design of Network-based Software Architectures(December 2000) Bill Burke's (August 2008 - DZone) How to GET a cup of coffee (October 2008 - InfoQ) Roy Fielding REST APIs Must Be Hypertext Driven (October 2008 - Untagled Roy's blog - take a look at the URI: roy.gbiv.com ) JAX-RS Bill Burke's (September 2008 - DZone) An overview of JAX-RS 1.0 Features James Strachan's JAX-RS as the one Java web framework to rule them all? (January 2009 - James' blog) RESTEasy RESTEasy project A blog about Spring + RESTEasy Getting Started with RESTEasy Spring Spring 2.5 reference Oh, just search google for "spring framework" Spring MVC Spring MVC Reference Spring MVC Step By Step Spring MVC Tutorial
October 15, 2009
by Solomon Duskis
· 141,158 Views · 1 Like
article thumbnail
Managing Eclipse RCP Launch Arguments
in my last post i discussed how to best manage run configurations for eclipse rcp applications . but there was one related topic i wanted to discuss in more detail, and that is how to manage launch arguments. what are launch arguments? launch arguments are arguments that are added to the command line when you execute your application. these arguments come in two flavors: program arguments – arguments that are eclipse-specific. for example, the -clean argument will clear the configuration area on startup. vm arguments – arguments that make sense to the java vm. for example, the -xmx argument allows you to set the maximum heap size for the vm. both of these argument types can be set on the arguments tab in the run configurations dialog. launch arguments and the target platform we oftentimes want to apply the same launch arguments to all of our run configurations, and one way to handle that is to specify them on your target platform . on the target platform preference page there is a section where you can add whatever arguments you wish. the arguments associated with a target platform will be added to run configurations generated from the manifest editor . they will not be added to configurations generated by the product configuration editor. also, because the manifest editor link does not regenerate a configuration each time, you will need to explicitly delete a configuration if you want to recreate it using new target platform arguments. launch arguments and products a second way to manage arguments is to add them using the launching tab of the product configuration editor. when you add arguments in this way, two things will happen: the arguments will be added to your run configurations if you launch using the link in the product configuration editor . because this link regenerates the run configuration each time, consistent use of the link guarantees that your configuration is in synch with your product definition. the arguments will also be added to your deployed application in the form of an ini file. this is a nice feature, but it means that you need to be careful when adding arguments that are only useful during development. for example, you may want to use -clean to clear the configuration area when you’re developing, but you probably do not want to ship this argument to your customers. launch arguments best practices my approach is to add arguments using the product configuration editor and to always launch my applications using the link in that editor. this guarantees that my run configurations are always in synch with my product definition. i also take care to not add arguments that would be detrimental to a deployed application. some, such as -consolelog, i consider harmless in a deployed app and i just leave those in. if for some reason i absolutely have to add an argument that should not be deployed, i usually clean it out of the ini file during the build process. it’s pretty rare for me to have to do this, though. from http://www.modumind.com
September 9, 2009
by Patrick Paulin
· 10,751 Views
article thumbnail
Spring Integration: A Hands-On Tutorial, Part 1
This tutorial is the first in a two-part series on Spring Integration. In this series we're going to build out a lead management system based on a message bus that we implement using Spring Integration. Our first tutorial will begin with a brief overview of Spring Integration and also just a bit about the lead management domain. After that we'll build our message bus. The second tutorial continues where the first leaves off and builds the rest of the bus. I’ve written the sample code for this tutorial as a Maven 2 project. I’m using Java 5, Spring Integration 1.0.3 and Spring 2.5.6. The code also works for Java 6. I've used Maven profiles to isolate the dependencies you’ll need if you’re running Java 5. The tutorials assume that you're comfortable with JEE, the core Spring framework and Maven 2. Also, Eclipse users may find the m2eclipse plug-in helpful. To complete the tutorial you'll need an IMAP account, and you'll also need access to an SMTP server. Let's begin with an overview of Spring Integration. A bird's eye view of Spring Integration Spring Integration is a framework for implementing a dynamically configurable service integration tier. The point of this tier is to orchestrate independent services into meaningful business solutions in a loosely-coupled fashion, which makes it easy to rearrange things in the face of changing business needs. The service integration tier sits just above the service tier as shown in figure 1. Following the book Enterprise Integration Patterns by Gregor Hohpe and Bobby Woolf (Addison-Wesley), Spring Integration adopts the well-known pipes and filters architectural style as its approach to building the service integration layer. Abstractly, filters are information-processing units (any type of processing—doesn’t have to be information filtering per se), and pipes are the conduits between filters. In the context of integration, the network we’re building is a messaging infrastructure—a so-called message bus—and the pipes and filters and called message channels and message endpoints, respectively. The network carries messages from one endpoint to another via channels, and the message is validated, routed, split, aggregated, resequenced, reformatted, transformed and so forth as the different endpoints process it. Figure 1. The service integration tier orchestrates the services below it. That should give you enough technical context to work through the tutorial. Let’s talk about the problem domain for our sample integration, which is enrollment lead management in an online university setting. Lead management overview In many industries, such as the mortgage industry and for-profit education, one important component of customer relationship management (CRM) is managing sales leads. This is a fertile area for enterprise integration because there are typically multiple systems that need to play nicely together in order to pull the whole thing off. Examples include front-end marketing/lead generation websites, external lead vendor systems, intake channels for submitted leads, lead databases, e-mail systems (e.g., to accept leads, to send confirmation e-mails), lead qualification systems, sales systems and potentially others. This tutorial and the next use Spring Integration to integrate several of systems of the kind just mentioned into an overall lead management capability for a hypothetical online university. Specifically we’ll integrate the following: • a CRM system that allows campus and call center staff to create leads directly, as they might do for walk-in or phone-in leads • a Request For Information (RFI) form on a lead generation ("lead gen") marketing website • a legacy e-mail based RFI channel • an external CRM that the international enrollment staff uses to process international leads • confirmation e-mails Figure 2 shows what it will look like when we’re done with both tutorials. For now focus on the big picture rather than the details. Figure 2. This is the lead management system we'll build. For this first tutorial we're simply going to establish the base staff interface, the (dummy) backend service that saves leads to a database, and confirmation e-mails. The second tutorial will deal with lead routing, web-based RFIs and e-mail-based RFIs. Let's dive in. We’ll begin with the basic lead creation page in the CRM and expand out from there. Building the core components [You can download the source code for this section of the tutorial here] We’re going to start by creating a lead creation HTML form for campus and call center staff. That way, if walk-in or phone-in leads express an interest, we can get them into the system. This is something that might appear as a part of a lead management module in a CRM system, as shown in figure 3. Figure 3. We'll build our lead management module with integration in mind from the beginning. Because we’re interested in the integration rather than the actual app features, we’re not really going to save the lead to the database. Instead we’ll just call a createLead() method against a local LeadService bean and leave it at that. But we will use Spring Integration to move the lead from the form to the service bean. Our first stop will be the domain model. DZone readers get 30% off Spring in Practice by Willie Wheeler and John Wheeler. Use code dzone30 when checking out with any version of the book at www.manning.com. Create the domain model We’ll need a domain object for leads, so listing 1 shows the one we’ll use. It’s not an industrial-strength representation, but it will do for the purposes of the tutorial. Listing 1. Lead.java, a basic domain object for leads. package crm.model;... other imports ...public class Lead { private static DateFormat dateFormat = new SimpleDateFormat(); private String firstName; private String middleInitial; private String lastName; private String address1; private String address2; ... other fields ... public Lead() { } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } ... other getters and setters, and a toString() method ...} There is nothing special happening here at all. So far the Lead class is just a bunch of getters and setters. You can see the full code listing in the download. If you thought that was underwhelming, just wait until you see the LeadServiceImpl service bean in listing 2. Listing 2. LeadServiceImpl.java, a dummy service bean. package crm.service;import java.util.logging.Logger;import org.springframework.stereotype.Service;import crm.model.Lead;@Service("leadService")public class LeadServiceImpl implements LeadService { private static Logger log = Logger.getLogger("global"); public void createLead(Lead lead) { log.info("Creating lead: " + lead); } This is just a dummy bean. In real life we’d save the lead to a database. The bean implements a basic LeadService interface that we've suppressed here, but it's available in the code download. Now that we have our domain model, let’s use Spring Integration to create a service integration tier above it. Create the service integration tier If you look back at figure 3, you’ll see that the CRM app pushes lead data to the service bean by way of a channel called newLeadChannel. While it’s possible for the CRM app to push messages onto the channel directly, it’s generally more desirable to keep the systems you’re integrating decoupled from the underlying messaging infrastructure, such as channels. That allows you to configure service orchestrations dynamically instead of having to go into the code. Spring Integration supports the Gateway pattern (described in the aforementioned Enterprise Integration Patterns book), which allows an application to push messages onto the message bus without knowing anything about the messaging infrastructure. Listing 3 shows how we do this. Listing 3. LeadGateway.java, a gateway offering access to the messaging system. package crm.integration.gateways;import org.springframework.integration.annotation.Gateway;import crm.model.Lead;public interface LeadGateway { @Gateway(requestChannel = "newLeadChannel") void createLead(Lead lead);} We are of course using the Spring Integration @Gateway annotation to map the method call to the newLeadChannel, but gateway clients don’t know that. Spring Integration will use this interface to create a dynamic proxy that accepts a Lead instance, wraps it with an org.springframework.integration.core.Message, and then pushes the Message onto the newLeadChannel. The Lead instance is the Message body, or payload, and Spring Integration wraps the Lead because only Messages are allowed on the bus. We need to wire up our message bus. Figure 4 shows how to do that with an application context configuration file. Listing 4. /WEB-INF/applicationContext-integration.xml message bus definition. The first thing to notice here is that we've made the Spring Integration namespace our default namespace instead of the standard beans namespace. The reason is that we're using this configuration file strictly for Spring Integration configuration, so we can save some keystrokes by selecting the appropriate namespace. This works pretty nicely for some of the other Spring projects as well, such as Spring Batch and Spring Security. In this configuration we've created the three messaging components that we saw in figure 3. First, we have an incoming lead gateway to allow applications to push leads onto the bus. We simply reference the interface from listing 3; Spring Integration takes care of the dynamic proxy. Next we create a publish/subscribe ("pub-sub") channel called newLeadChannel. This is the channel that the @Gateway annotation referenced in listing 3. A pub-sub channel can publish a message to multiple endpoints simultaneously. For now we have only one subscriber—a service activator—but we already know we're going to have others, so we may as well make this a pub-sub channel. The service activator is an endpoint that allows us to bring our LeadServiceImpl service bean onto the bus. We're injecting the newLeadChannel into the input end of the service activator. When a message appears on the newLeadChannel, the service activator will pass its Lead payload to the leadService bean's createLead() method. Stepping back, we've almost implemented the design described by figure 3. The only part that remains is the lead creation frontend, which we'll address right now. Create the web tier Our user interface for creating new leads will be a web-based form that we implement using Spring Web MVC. The idea is that enrollment staff at campuses or call centers might use such an interface to handle walk-in or phone-in traffic. Listing 5 shows our simple @Controller. Listing 5. LeadController.java, a @Controller to allow staff to create leads package crm.web;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import crm.integration.gateways.LeadGateway;import crm.model.Country;import crm.model.Lead;@Controllerpublic class LeadController { @Autowired private LeadGateway leadGateway; @RequestMapping(value = "/lead/form.html", method = RequestMethod.GET) public void getForm(Model model) { model.addAttribute(Country.getCountries()); model.addAttribute(new Lead()); } @RequestMapping(value = "/lead/form.html", method = RequestMethod.POST) public String postForm(Lead lead) { lead.setDateCreated(new Date()); leadGateway.createLead(lead); return "redirect:form.html?created=true"; } This isn't an industrial-strength controller as it doesn't do HTTP parameter whitelisting (for example, via an @InitBinder method) and form validation, both of which you would expect from a real implementation. But the main pieces from a Spring Integration perspective are here. We're autowiring the gateway into the @Controller, and we have methods for serving up the empty form and for processing the submitted form. The getForm() method references a Countries class that we've suppressed (it's in the code download); it just puts a list of countries on the model so the form can present a Country field to the staff member. The postForm() method invokes the createLead() method on the gateway. This will pass the Lead to the dynamic proxy LeadGateway implementation, which in turn will wrap the Lead with a Message and then place the Message on the newLeadChannel. There are a few other configuration files you will need to put in place, including web.xml, main-servlet.xml and applicationContext.xml. There's also a JSP for the web form. As none of these relates directly to Spring Integration, we won't treat them here. Please see the code download for details. With that, we've established a baseline system. To try it out, run mvn jetty:run against crm/pom.xml and point your browser at http://localhost:8080/crm/main/lead/form.html You should see a very basic-looking web form for entering lead information. Enter some user information (it doesn't matter what you enter—recall that we don't have any form validation) and press Submit. The console should report that LeadServiceImpl.createLead() created a lead. Congratulations! Even though we now have a working system, it isn't very interesting. From here on out (this tutorial and the next) we'll be adding some common features to make the lead management system more capable. Our first addition will be confirmation e-mails; the next tutorial will present further additions. Adding confirmation e-mails [The source for this section is available here] After an enrollment advisor (or some other staff member) creates a lead in the system, we want to send the lead an e-mail letting him know that that's happened. Actually—and this is a critical point—we really don't care how the lead was created. Anytime a lead appears on the newLeadChannel, we want to fire off a confirmation e-mail. I'm making the distinction because it points to an important aspect of the message bus: it allows us to control lead processing code centrally instead of having to chase it down in a bunch of different places. Right now there's only one way to create leads, but figure 2 revealed that we'll be adding others. No matter how many we add, they'll all result in sending a confirmation e-mail out to the lead. Figure 4 shows the new bit of plumbing we're going to add to our message bus. Figure 4. Send a confirmation e-mail when creating a lead. To do this, we're going to need to make a few changes to the configuration and code. POM changes First we need to update the POM. Here's a summary of the changes; see the code download for details: • Add a JavaMail dependency to the Jetty plug-in. • Add an org.springframework.context.support dependency. • Add a spring-integration-mail dependency. • Set the mail.version property. These changes will allow us to use JavaMail. Expose JavaMail sessions through JNDI We'll also need to add a /WEB-INF/jetty-env.xml configuration to make our JavaMail sessions available via JNDI. Once again, see the code download for details. I've included a /WEB-INF/jetty-env.xml.sample configuration for your convenience. As mentioned previously, you'll need access to an SMTP server. Besides creating jetty-env.xml, we'll need to update applicationContext.xml. Listing 6 shows the changes we need so we can use JavaMail and SMTP. Listing 6. /WEB-INF/applicationContext.xml changes supporting JavaMail and SMTP The changes expose JavaMail sessions as a JNDI resource. We've declared the jee namespace and its schema location, configured the JNDI lookup, and created a JavaMailSenderImpl bean that we'll use for sending mail. We won't need any domain model changes to generate confirmation e-mails. We will however need to create a bean to back our new transformer endpoint. Service integration tier changes First, recall from figure 4 that the newLeadChannel feeds into a LeadToEmailTransformer endpoint. This endpoint takes a lead as an input and generates a confirmation e-mail as an output, and the e-mail gets pipes out to an SMTP transport. In general, transformers transform given inputs into desired outputs. No surprises there. Figure 4 is slightly misleading since it's actually the POJO itself that we're going to call LeadToEmailTransformer; the endpoint is really just a bean adapter that the messaging infrastructure provides so we can place the POJO on the message bus. Listing 7 presents the LeadToEmailTransformer POJO. Listing 7. LeadToEmailTransformer.java, a POJO to generate confirmation e-mails package crm.integration.transformers;import java.util.Date;import java.util.logging.Logger;import org.springframework.integration.annotation.Transformer;import org.springframework.mail.MailMessage;import org.springframework.mail.SimpleMailMessage;import crm.model.Lead;public class LeadToEmailTransformer { private static Logger log = Logger.getLogger("global"); private String confFrom; private String confSubj; private String confText; ... getters and setters for the fields ... @Transformer public MailMessage transform(Lead lead) { log.info("Transforming lead to confirmation e-mail: " + lead); String leadFullName = lead.getFullName(); String leadEmail = lead.getEmail(); MailMessage msg = new SimpleMailMessage(); msg.setTo(leadFullName == null ? leadEmail : leadFullName + " <" + leadEmail + ">"); msg.setFrom(confFrom); msg.setSubject(confSubj); msg.setSentDate(new Date()); msg.setText(confText); log.info("Transformed lead to confirmation e-mail: " + msg); return msg; } Again, LeadToEmailTransformer is a POJO, so we use the @Transformer annotation to select the method that's performing the transformation. We use a Lead for the input and a MailMessage for the output, and perform a simple transformation in between. When defining backing beans for the various Spring Integration filters, it's possible to specify a Message as an input or an output. That is, if we want to deal with the messages themselves rather than their payloads, we can do that. (Don't confuse the MailMessage in listing 7 with a Spring Integration message; MailMessage represents an e-mail message, not a message bus message.) We might do that in cases where we want to read or manipulate message headers. In this tutorial we don't need to do that, so our backing beans just deal with payloads. Now we'll need to build out our message bus so that it looks like figure 4. We do this by updating applicationContext-integration.xml as shown in listing 8. Listing 8. /WEB-INF/applicationContext-integration.xml updates to support confirmation e-mails The property-placeholder configuration loads the various ${...} properties from a properties file; see /crm/src/main/resources/applicationContext.properties in the code download. You don't have to change anything in the properties file. The transformer configuration brings the LeadToEmailTransformer bean into the picture so it can transform Leads that appear on the newLeadChannel into MailMessages that it puts on the confEmailChannel. As a side note, the p namespace way of specifying bean properties doesn't seem to work here (I assume it's a bug: http://jira.springframework.org/browse/SPR-5990), so I just did it the more verbose way. The channel definition defines a point-to-point channel rather than a pub-sub channel. That means that only one endpoint can pull messages from the channel. Finally we have an outbound-channel-adapter that grabs MailMessages from the confEmailChannel and then sends them using the referenced mailSender, which we defined in listing 6. That's it for this section. We should have working confirmation e-mails. Restart your Jetty instance and go again to http://localhost:8080/crm/main/lead/form.html Fill it out and provide your real e-mail address in the e-mail field. A few moments after submitting the form you should receive a confirmation e-mail. If you don't see it, you might check your SMTP configuration in jetty-env.xml, or else check your spam folder. Summary In this tutorial we've taken our first steps toward developing an integrated lead management system. Though the current bus configuration is simple, we've already seen some key Spring Integration features, including • support for the Gateway pattern, allowing us to connect apps to the message bus without knowing about messages • point-to-point and pub-sub channels • service activators to allow us to place service beans on the bus • message transformers • outbound SMTP channel adapters to allow us to send e-mail The second tutorial will continue elaborating what we've developed here, demonstrating the use of several additional Spring Integration features, including • message routers (including content-based message routers) • outbound web service gateways for sending SOAP messages • inbound HTTP adapters for collecting HTML form data from external systems • inbound e-mail channel adapters (we'll use IMAP IDLE, though POP and IMAP are also possible) for processing incoming e-mails Enjoy, and stay tuned. Willie is a solutions architect with 12 years of Java development experience. He and his brother John are coauthors of the upcoming book Spring in Practice by Manning Publications (www.manning.com/wheeler/). Willie also publishes technical articles (including many on Spring) to wheelersoftware.com/articles/.
August 18, 2009
by Willie Wheeler
· 249,407 Views · 3 Likes
article thumbnail
Custom Controller Factory in ASP.NET MVC
After discussing custom route handler and IRouteHandler as two extensibility points in ASP.NET MVC to customize the behavior of routing system, now I want to continue discussing thirteen major extensibility points in ASP.NET MVC by focusing on custom controller factories and building such controller factories. When ASP.NET MVC receives a request, it needs to manage how to handle it with a specific controller and the action methods in it. The component that is responsible to map an incoming request to a specific controller and decide which controller to use is controller factory. There is a default controller factory in ASP.NET MVC that maps incoming requests to a controller with a Controller postfix. The built-in controller factory is the registered controller factory by default and is implemented in DefaultControllerFactory class. Also it’s possible to extend its behavior with minor changes by deriving from this base class. But in some circumstances you may need to have a fully customized behavior for your controller factories. One common example is when you use Dependency Injection frameworks where you need to use a customized factory. Fortunately, most of the DI frameworks provide such a customized controller factory out of the box, but if you were faced with a case to implement such a factory, you can implement the IControllerFactory interface and register your own custom controller factory. IControllerFactory is an interface with two methods: CreateController: Getting the RequestContext instance and the string value of controller name, returns the controller to be used. ReleaseController: Gets a controller instance and releases this controller. Implementation of a controller factory is comparatively easy, and can be done with less amount of work to be done. In this post I implement a basic controller factory that loads controllers based on the user’s language, so a specific controller can be loaded for a specific language. In this sample application, I define the type name of controllers in web configuration file based on a pattern that corresponds to a specific culture, and implement a controller factory that loads the appropriate controllers group based on the client’s preferences. First I define my type patterns in my configuration file as application settings. Here I have two cultures: if the user uses Farsi, then the Farsi controllers will be loaded, otherwise the default English language will be used. Now I write my controller factory by implementing the IControllerFactory interface and its two methods. using System; using System.Configuration; using System.Web.Mvc; using System.Web.Routing; namespace IControllerFactorySample.ControllerFactories { public class CustomControllerFactory : IControllerFactory { #region IControllerFactory Members public IController CreateController(RequestContext requestContext, string controllerName) { if (string.IsNullOrEmpty(controllerName)) throw new ArgumentNullException("controllerName"); string language = requestContext.HttpContext.Request.Headers["Accept-Language"]; string controllerType = string.Empty; if (language == "fa-IR") controllerType = string.Format (ConfigurationManager.AppSettings["FarsiControllerTypePattern"], controllerName); else controllerType = string.Format (ConfigurationManager.AppSettings["EnglishControllerTypePattern"], controllerName); IController controller = Activator.CreateInstance(Type.GetType(controllerType)) as IController; return controller; } public void ReleaseController(IController controller) { if (controller is IDisposable) (controller as IDisposable).Dispose(); else controller = null; } #endregion } } In the CreateController function, I detect the client’s language using the HTTP headers of the request, and load the appropriate type name based on the user’s culture. Then I use reflection APIs to load the type and create an instance of the controller to be returned. Note that this implementation doesn’t mandate the Controller postfix for controller names, so rather than defining my Home controller as HomeController class, I just can use Home name. I have defined my controllers in Fa and En sub-folders inside Controllers folder, so my controller factory can load them based on the type name patterns. Besides, in the ReleaseController method, I dispose the controller as expected. The third and last step is to add this controller factory as the default factory to ASP.NET MVC. This can be done in Global.asax and its Application_Start method where I use ControllerBuilder.SetControllerFactory to add my factory type as the default controller factory to ASP.NET MVC. using System.Web.Mvc; using System.Web.Routing; using IControllerFactorySample.ControllerFactories; namespace IControllerFactorySample { public class MvcApplication : System.Web.HttpApplication { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Home", action = "Index", id = "" } // Parameter defaults ); } protected void Application_Start() { RegisterRoutes(RouteTable.Routes); ControllerBuilder.Current.SetControllerFactory(typeof(CustomControllerFactory)); } } } As you see, building a controller factory is very straightforward and you can get it done in a few simple steps. If I run the application and set my preferred language to Farsi, then Farsi controllers will be used to serve the requests, otherwise English controllers will be loaded. As always, the sample application for this post is available for download.
May 12, 2009
by Keyvan Nayyeri
· 27,885 Views · 1 Like
article thumbnail
Introduction to the Open eHealth Integration Platform
The Open eHealth Integration Platform (IPF) is an extension of the Apache Camel routing and mediation engine and comes with comprehensive support for message processing and connecting information systems in the healthcare sector. It is available under the Apache License version 2.0. IPF and Camel both focus on a domain-specific language (DSL) to implement and combine Enterprise Integration Patterns (EIPs) in integration solutions. IPF leverages the Groovy programming language for application development and for extending the Apache Camel DSL. One example of a healthcare-related use case of IPF is the implementation of interfaces for transactions specified in IHE profiles. The use of IPF to implement actor interfaces for the IHE PIX and PDQ profiles was tested successfully at the 2009 Connect-a-thon. The actual actors were proprietary systems that were IHE-enabled via IPF-based integration solutions. It is important to note that usage of IPF is not just limited to the healthcare domain. It can also be used to build integration solutions for several other domains. However, this article will focus primarily on the healthcare-specific features of IPF. Riding the Camel IPF is built on top of the Apache Camel routing and mediation engine. This section deals briefly with the concepts behind Camel. For a more detailed overview, read Jonathan Anstey's excellent introductory article Apache Camel: Integration Nirvana. Apache Camel is about Enterprise Integration Patterns (EIPs). EIPs have previously been described by Gregor Hohpe and Bobby Woolf in their book Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions. They represent experiences of integration architects and can be used as building blocks for designing integration solutions. These patterns were published as recommendations without implying a concrete implementation. This is where Apache Camel comes in. Camel was created to provide implementations for EIPs. With Apache Camel, integration solutions are developed by combining integration patterns using a domain-specific language (DSL). In addition to EIP implementations, Camel also provides more than 60 components for connecting to a great variety of transports and APIs. The four major concepts in Camel are components, endpoints, processors and the domain-specific language (DSL). Components provide connectivity to other systems. From components, endpoints are created for sending and receiving messages. Endpoints are uniquely identified by their URIs. Processors are used to route and transform messages between endpoints. To wire endpoints and processors together, Camel provides a DSL for Java. Consider a simple example: from("jms:queue:validated") .filter().xpath("/person[@name='Martin']") .to("http://www.example.com/camel"); In this route definition, messages are read from a JMS queue (identified by the jms:queue:validated endpoint URI) and sent through a filter. The filter criterion is an XPath predicate. Any message that passes the filter will be POSTed to the http://www.example.com/camel endpoint. Camel also supports a Spring-based XML configuration for creating message processing routes (not shown here). Riding IPF Any feature provided by Camel can be used in combination with any other features provided by IPF. IPF makes its features available via extensions to the Camel DSL. These extensions have been implemented via Groovy meta-programming. For these extensions to be used in an IPF application, route definitions must be written in Groovy. Here is an example of a route definition that uses IPF's DSL extensions: from('file:input') // read HL7 message from file .unmarshal().ghl7() // create HL7 message object .validate().ghl7() // validate HL7 message object .filter {exchange -> // filter message using criteria defined by closure def msg = exchange.in.body // use exchange.in.body to access HL7 message object msg.PID[8].value == 'F' // use HL7 DSL to access and compare PID-8 field value } .to('http://...') // send message to destination (via HTTP In this route, an HL7 message is read from a file, validated and then filtered based on the value of the 8th field in the PID segment. To obtain this field value, the filter closure uses IPF's HL7 DSL. This DSL is explained in detail in the next section. If the message passes the filter it is forwarded to its destination via HTTP. The route definition uses the DSL elements from, unmarshal, filter and to from Camel directly, all other DSL elements are extensions provided by IPF, including the use of closures for filter criteria. IPF DSL extensions can be used as if they are native Camel DSL elements. Furthermore, the DSL used in applications is not just limited to the DSL provided by Camel and IPF. Application-specific DSL extensions can also be written using IPF's DSL extension mechanism. This mechanism also supports modularization of DSL definitions. Any component can contribute its own DSL extensions. Consequently, the scope of the overall DSL depends on which components were deployed for the application. Inside an OSGi environment, IPF can even automatically detect and activate DSL extensions provided by different bundles. The following sections will explore the healthcare-specific features of IPF in greater detail. For a detailed description of all IPF features consult the IPF reference documentation. For a more hands-on guide on how to write IPF applications, the IPF tutorials are a good starting point. HL7 message processing HL7 (Health Level 7) is an ANSI-accredited standards developing organization (SDO) in the healthcare sector. Among other standards it focuses on developing messaging standards for the clinical and administrative domain. This standard is often referred to as the HL7 messaging standard. There are several versions of this standard. HL7 version 2.x is widely used, the most recent update was version 2.6 in 2007. It differs significantly from the XML-based HL7 version 3. The following subsections focus on IPF's support for HL7 version 2.x. Support for HL7 version 3 is currently under development. IPF uses the open source HAPI library as its basis for HL7 version 2 message processing. HL7 version 2 at a glance HL7 version 2 messages have a hierarchical structure and are organized into groups, segments, fields and datatypes which can also repeat. Message elements are referenced by their path within the hierarchy (see navigation syntax in the following figure). HL7 DSL The core of IPF's HL7 message processing capabilities is the HL7 DSL. This is a domain-specific language for accessing and manipulating HL7 version 2 messages. The IPF library that implements this DSL (modules-hl7dsl) can also be used standalone (i.e. independent from other IPF components) in any Groovy application. Seamless integration into the IPF DSL is provided as well. The following examples presume a certain degree of familiarity with HL7 version 2 message structures and terms. Constructing messages The entry point to the HL7 DSL is IPF's MessageAdapter. To create a MessageAdapter instance from an HL7 file we use the load method from the MessageAdapters utility class. import org.openehealth.ipf.modules.hl7dsl.MessageAdapter import org.openehealth.ipf.modules.hl7dsl.MessageAdapters MessageAdapter message = MessageAdapters.load('ADT-A01.hl7') This loads the HL7 file ADT-A01.hl7 from the classpath. Accessing message content The following example obtains the PID segment contained in the PATIENT group which itself is contained in the first repetition of the repeatable PATIENT_RESULT group. // repeating elements are indexed from 0 to n def segment = message.PATIENT_RESULT(0).PATIENT.PID The function call operator () is used to refer to an element in a repetition. The element index is passed as argument. Obtaining fields is similar to obtaining groups and segments except that fields are often referred to by index rather than by name. To obtain the MSH-3 field from a message we can write: // fields are indexed from 1 to n def composite = message.MSH[3] If the field is a composite we access the second component with: // components of a composite field are indexed from 1 to n def primitive = message.MSH[3][2] or, equivalently, def primitive = message.MSH.sendingApplication.universalIDType As shown above, navigation is also possible using field names instead of indices. Care must be taken, because along with the change of internal message structures, individual field names change between HL7 versions, even when they refer to the same position of the field in a segment. If the version of the HL7 message is not known in advance, it is better to use the more concise index notation. Fields may also repeat. To obtain a given element of a repeating field the function call operator () is used, just like with groups and segments. In the next example we obtain the first element of the repeating NK1-5 field. Because NK1 is a repeating segment, the function call operator is used on segment-level, too. def field = message.NK1(0)[5](0) def fieldList = message.NK1(0)[5]() Omitting the repetition index returns a list of repeating elements. Omitting the function call operator, the first repetition of a group, segment or field is assumed. This is called smart navigation: assert message.NK1(0)[5](0)[1].value == message.NK1[5](0)[1].value assert message.NK1(0)[5](0)[1].value == message.NK1[5][1].value assert message.PATIENT_RESULT(0).PATIENT.PID[5][1] == message.PATIENT_RESULT.PATIENT.PID[5][1] If a component is omitted, the first component or subcomponent of a composite is assumed assert message.NK1(0)[5](0)[1].value == message.NK1[5].value assert message.NK1(0)[5](1)[1].value == message.NK1[5](1).value assert message.NK1(0)[2][1][1].value == message.NK1[2].value Using smart navigation, the expressions are usually shorter and less error-prone. Moreover, in many cases the same expression can be used for different HL7 versions, making the DSL more portable. Modifying message content A segment of one message can be assigned the segment value of another message using the assigment operator (=). The following example copies the EVN segment from message2 to message1. message1.EVN = message2.EVN To change a field value we navigate to that field (either by name or index, as shown above) and assign it a string or another field value. def msh = message.MSH def nk1 = message.NK1(0) msh[5] = nk1[4][4] msh[5] = 'abc' Composite fields may also be changed by assigning other composite fields. In the following example we copy the composite NK1(0)[4] field from message2 to message1. message1.NK1(0)[4] = message2.NK1(0)[4] Externalizing messages The left-shift operator (<<) appends the string-represenation of a MessageAdapter object to a writer. In the following example, we write an HL7 message to System.out. MessageAdapter message = ... System.out << message To obtain the string-representation directly, we can use the MessageAdapter.toString() method. MessageAdapter message = ... def rendered = message.toString() Usage in route definitions This section shows a few examples how to combine the HL7 DSL with IPF's route definition DSL. The unmarshal().ghl7() extension should be used to create a MessageAdapter object from an external HL7 message representation. The created MessageAdapter object can then be used in subsequent processors. from('file:input') .unmarshal().ghl7() .process {exchange -> MessageAdapter message = exchange.in.body ... } ... The reverse operation marshal().ghl7() marshals a MessageAdapter object into a stream. This is often needed for transmitting HL7 messages over a variety of transports such as JMS, for example. from('file:input') .unmarshal().ghl7() ... .marshal().ghl7() .to(jms:queue:validated) Another usage example is content-based routing. In the following example a message is routed to different destinations depending on the content of the MSH[4] field. Here we use closures in combination with Camel's when DSL element for implementing routing rules. The it variable inside closures represents a message exchange. from(...) .unmarshal().ghl7() ... .choice() .when { it.in.body.MSH[4].value == 'ABC' } .to(...) .when { it.in.body.MSH[4].value == 'DEF' } .to(...) .otherwise() .to(...) HL7 validation IPF also adds support for specifying validation rules in a way that is easy to write and simple to understand. It facilitates the definition of custom validation rules by providing a dedicated validation DSL. Like the HL7 DSL, the validation DSL can also be used standalone but also integrates well into the IPF DSL for defining message processing routes. The IPF component that implements HL7 validation is modules-hl7. Validation rules are defined by extending the ValidationContextBuilder class of IPF. The validation rules DSL is provided by the RuleBuilder class. The following example defines a subset of segments from the HL7 version 2.2 specification. package example import ca.uhn.hl7v2.validation.ValidationContext import org.openehealth.ipf.modules.hl7.validation.builder.RuleBuilder import org.openehealth.ipf.modules.hl7.validation.builder.ValidationContextBuilder class SampleRulesBuilder extends ValidationContextBuilder { RuleBuilder forContext(ValidationContext context) { new RuleBuilder(context) .forVersion('2.2') .message('ADT', 'A01').abstractSyntax( 'MSH', 'EVN', 'PID', [ { 'NK1' } ], 'PV1', [ { INSURANCE( 'IN1', [ 'IN2' ] , [ 'IN3' ] )}] ) } } The sequence and cardinality of groups and segments is defined in a syntax that is very closely related to the HL7 Abstract Message Syntax. The message must contain the segments MSH, EVN, PID and PV1; it may contain zero or more NK1 segments and it may contain a repeatable INSURANCE group. In a next step we configure our SampleRulesBuilder in a Spring application context along with a ValidationContextFactoryBean. The ValidationContextFactoryBean auto-detects any beans of type ValidationContextBuilder and adds their validation rules to a ValidationContext that is used in route definitions. The validate().ghl7() DSL extension, which we have already seen, can be configured with a custom validation profile using the profile() DSL extension. The validation context is looked up from the Spring application context via bean(ValidationContext.class). import ca.uhn.hl7v2.validation.ValidationContext import org.apache.camel.spring.SpringRouteBuilder class SampleRouteBuilder extends SpringRouteBuilder { void configure() { from(...) .unmarshal().ghl7() .validate().ghl7().profile(bean(ValidationContext.class)) ... .to(...) } } Code mapping HL7 message processing often involves mapping between code systems i.e. from one set of codes into a corresponding different set of codes. For example, HL7 version 2 and HL7 version 3 use different code systems for most coded values such as message type, gender, clinical encounter type, marital status codes, address and telecommunication use codes, just to mention a few. IPF defines a mapping service that provides the mapping logic. This may be a simple map but it can also be a facade to a remote mapping or terminology service. IPF's default mapping service implementation, the BidiMappingService, supports bidirectional mappings and reads custom mapping definitions from mapping files. An instance of the BidiMappingService can be created with the following bean definition. The mapping service references a mapping file example.map on the classpath. If there is more than one mapping file, a list can be provided via the mappingScripts property. Here is the content of example.map: mappings = { encounterType(['2.16.840.1.113883.12.4','2.16.840.1.113883.5.4'], E : 'EMER', I : 'IMP', O : 'AMB' ) } The example mapping file is a Groovy script and contains a single mapping with three entries for encounter type codes. Also defined are the ISO Object Identifiers (OIDs) for the key and value code systems. The mapping service can now be accessed either directly or via methods on java.lang.String. The String.map() method maps the codes on the left side to the right side. The identifier for the mapping can either be passed as argument assert 'E'.map('encounterType') == 'EMER' assert 'X'.map('encounterType') == null assert 'X'.map('encounterType', 'DEFAULT') == 'DEFAULT' or as part of a method name. assert 'E'.mapEncounterType() == 'EMER' assert 'X'.mapEncounterType() == null assert 'X'.mapEncounterType('DEFAULT') == 'DEFAULT' A dynamic dispatch is used to select the mapping definition from the method name. The method names must therefore correspond to the registered mappings. Mapping in the reverse direction is equally possible. assert 'EMER'.mapReverse('encounterType') == 'E' assert 'EMER'.mapReverseEncounterType() == 'E' Code systems are often associated with a globally unique identifier, usually in form of an OID. The identifier of both sides of a mapping can be obtained as follows. assert 'encounterType'.keySystem() == '2.16.840.1.113883.12.4' assert 'encounterType'.valueSystem() == '2.16.840.1.113883.5.4' Code mapping methods may also be used in combination with the HL7 DSL. MessageAdapter message = ... assert message.PV1.patientClass.value == 'I' assert message.PV1.patientClass.map('encounterType') == 'IMP' assert message.PV1.patientClass.mapEncounterType() == 'IMP' Response messages HL7 messaging often requires the return of an HL7 response message to the sender. With IPF, positive (ACK) or negative (NAK) acknowledgments to messages can be generated. Acknowledgments are in the same HL7 version as the original message and are populated with arguments to the ack() method. MessageAdapter message = ... def ack = message.ack() def nak1 = message.nak('Reason for failure') def nak2 = message.nak(new HL7Exception('Reason for failure', 204)) Generating acknowledgments is, however, only one special case of generating a response to an original message. For responses other than acknowledgements, a response message prototype can be created via the respond(eventType, triggerEvent) method. The MSH and MSA segments of the response message are then populated as required by the HL7 specification. def rsp = msg.respond('RSP','K21') // generates a RSP_K21 message More features So far, the main focus has been on HL7 message processing. IPF has many more features and services to support the development and the operation of production-quality integration solutions. Some of them are briefly described in the following list. A detailed description would far exceed the scope of this paper. For a complete overview refer to the IPF reference documentation. Core features. Collection of domain-neutral message processors and DSL extensions usable for general-purpose message processing including support for Groovy XML processing and support for using closures with Camel DSL elements. OSGi support. Support for running IPF and its services inside an OSGi environment and for the development of OSGi-ready IPF applications. Flow management. A service for monitoring and managing message flows through IPF applications. The flow manager also supports a replay of messages for e.g. recovery from failures. Large message support. Allows for memory-efficient processing of large messages. Event infrastructure. An infrastructure for publishing and consuming system and application events. Can be used e.g. for separating logging, audit or statistics concerns from application-specific route definitions. Can also be used to integrate with complex event processing (CEP) engines. Outlook Upcoming IPF releases will provide support for CDA (Clinical Document Architecture) and IHE (Integrating the Healthcare Enterprise). CDA is an XML-based document markup standard that specifies the structure and semantics of a clinical document for the purpose of exchange. IHE is an initiative of healthcare professionals and industry to improve the way computer systems in the healthcare sector share information. The goal of IPF is to make it as easy as possible for developers to implement the CDA, IHE (and other clinical) standards in their applications. Here are a few examples of what to expect in the next IPF release. CDA support IPF's CDA support will focus on building CDA documents using a domain-specific language. This DSL supports the creation of structurally correct CDA documents by enforcing CDA-relevant schema definitions but without dealing with low-level XML details. The DSL is implemented by a custom Groovy builder, the CDABuilder. In the following code snippet we use the CDABuilder to create a CDA document using CDA-specific terms such as clinicalDocument, code, title, recordTarget and so on. For printing the created document to stdout we use the left-shift (<<) operator. // Create a CDA builder CDABuilder builder = new CDABuilder() // Create a new CDA document def document = builder.build { clinicalDocument { id(root:'2.16.840.1.113883.19.4', extension:'c266') code( code:'11488-4', codeSystem:'2.16.840.1.113883.6.1', codeSystemName:'LOINC', displayName:'Consultation note' ) title('Good Health Clinic Consultation Note') recordTarget { patientRole { id { extension="12345" root="2.16.840.1.113883.19.5" } patient { name { given('John') family('Doe') } birthTime('19320924') } //... } //... } //... } //... } // Write document XML to stdout System.out << document CDA support will also include support for selected CDA profiles from IHE, HL7/ASTM and HITSP specifications, for example XPHR and CCD. Profile-specific CDA DSL extensions will enforce the constraints imposed by the profile specifications. As an example, predefined CDA sections could then be added without knowing their templateID-OIDs or their exact nested XML structure. DSL support for parsing, validating, transforming and rendering CDA documents will complete the feature set. IHE support IPF's IHE support is a framework for creating actor interfaces as specified in IHE profiles. Most likely, support for the XDS profile will be the first to come. XDS stands for Cross-Enterprise Document Sharing and deals with registration and distribution of, and access to clinical documents across health enterprises. Central to this profile are the actors document registry and document repository. A number of document management systems could in principle act as registry and/or repository in the XDS profile. Most of these, however, do not support the XDS actor interface specifications right out of the box. This is were IPF comes in. It helps developers to build IHE actor interfaces for existing information systems. Consider this example: from('ihe:xds.b:iti-41?port=8080') .process { exchange -> def document = exchange.in.body // do further document processing here ... } // communicate with your document management system .to('http://...') // notify about availability of new document .to('ihe:nav:iti-25:[email protected]') This route starts a server to receive documents according to the ITI-41 transaction of the XDS.b IHE profile. ITI-41 is the Provide and Register Document Set transaction in XDS.b. XDS.b requires documents to be transported via SOAP and ebXML standards. To free developers from having to deal with low-level SOAP/ebXML handling, these communication details are hidden inside an ihe component (eventually there may be more than one). Subsequent processors can access the transported document without having to deal with ITI-41 details. After processing, the incoming document is uploaded to a document management system and, finally, [email protected] is notified about the availability of a new document. Notifications are sent according to the IHE NAV profile where NAV stands for Notification of Document Availability. This example is of course oversimplified (for instance it does not address responses, etc) but it still gives an idea of the abstraction level on which IHE interfaces can be implemented for existing systems. Conclusion Apache Camel is a good answer to many of today's integration problems. It provides a DSL for implementing Enterprise Integration Patterns and offers developers a simple and efficient way to deal with the diversity of applications and transports in distributed systems. IPF brings the power of Apache Camel to the healtcare domain and makes healthcare IT standards usable by means of a domain-specific language that closely resembles the language of domain experts. The DSL extension mechanism permits the evolution of even more specialized healthcare DSLs. IPF's support for DSL modularization makes these DSLs and their implementing components reusable in different integration scenarios. Author Martin Krasser is a software architect and engineer working for InterComponentWare AG. He focuses on distributed systems, application integration and application security. Martin is the founder and project lead of the open source IPF project.
May 11, 2009
by Martin Krasser
· 46,085 Views · 2 Likes
article thumbnail
Top 10 Open Source Projects for .NET Developers
There are many useful, practically essential, open source solutions available to .NET developers. This is a list of the ones that have been the most useful in my experience. Agree? Disagree? Leave a comment with your own suggestions. NHibernate - NHibernate is a mature, open source object-relational mapper for the .NET framework. It's actively developed, fully featured and used in thousands of successful projects. http://nhforge.org/Default.aspx NUnit - NUnit is a unit-testing framework for all .Net languages. Initially ported from JUnit, the current production release, version 2.4, is the fifth major release of this xUnit based unit testing tool for Microsoft .NET. It is written entirely in C# and has been completely redesigned to take advantage of many .NET language features, for example custom attributes and other reflection related capabilities. NUnit brings xUnit to all .NET languages. http://www.nunit.org/index.php jQuery - jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript. http://jquery.com/ Rhino.Mocks - A dynamic mock object framework for the .Net platform. It's purpose is to ease testing by allowing the developer to create mock implementations of custom objects and verify the interactions using unit testing. http://ayende.com/projects/rhino-mocks.aspx MVC Contrib - This is the contrib project for the ASP.NET MVC framework. This project adds additional functionality on top of the MVC Framework. These enhancements can increase your productivity using the MVC Framework. It is written in C#. Founded by Eric Hexter and Jeffrey Palermo. http://www.codeplex.com/MVCContrib CruiseControl.NET - CruiseControl.NET is an Automated Continuous Integration server, implemented using the Microsoft .NET Framework. http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET S#arp Architecture - Pronounced "Sharp Architecture," this is a solid architectural foundation for rapidly building maintainable web applications leveraging the ASP.NET MVC framework with NHibernate. The primary advantage to be sought in using any architectural framework is to decrease the code one has to write while increasing the quality of the end product. A framework should enable developers to spend little time on infrastructure details while allowing them to focus their attentions on the domain and user experience. http://code.google.com/p/sharp-architecture/ Spark View Engine - Spark is a view engine for Asp.Net Mvc and Castle Project MonoRail frameworks. The idea is to allow the html to dominate the flow and the code to fit seamlessly. http://sparkviewengine.com/ TortoiseSVN - A Subversion client, implemented as a windows shell extension. TortoiseSVN is a really easy to use Revision control / version control / source control software for Windows. Since it's not an integration for a specific IDE you can use it with whatever development tools you like. TortoiseSVN is free to use. You don't need to get a loan or pay a full years salary to use it. http://tortoisesvn.tigris.org/ Castle Windsor - Castle Project offers two Inversion of Control Containers. The MicroKernel and the Windsor Container. Castle Windsor aggregates the MicroKernel and exposes a powerful configuration support. It is suitable for common enterprise application needs. It is able to register facilities and components based on the configuration and adds support for interceptors. http://www.castleproject.org/container/index.html
May 4, 2009
by Alvin Ashcraft
· 88,221 Views
article thumbnail
Making Distinctions Between Different Kinds of JSF Managed-Beans
JSF has a simple Inversion-of-Control (IoC) container called the JSF Managed Bean Facility (MBF). Although it has a verbose XML syntax, and is not as robust as the Spring BeanFactory, PicoContainer, or the JBoss Microcontainer, the MBF does have the basics of an IoC container, and offers features like dependency injection. When a POJO is managed by the JSF MBF, it is typically referred to as a managed-bean. But if you're going to create a maintainable JSF webapp/portlet, it is necessary to distinguish between different kinds of managed-beans. This practice will also preserve the clean separation of concerns that JSF provides by implementing the Model-View-Controller (MVC) design pattern: Managed-Bean Type Nickname Typical Scope Model Managed-Bean model-bean session Description: This type of managed-bean participates in the "Model" concern of the MVC design pattern. When you see the word "model" -- think DATA. A JSF model-bean should be a POJO that follows the JavaBean design pattern with getters/setters encapsulating properties. The most common use case for a model bean is to be a database entity, or to simply represent a set of rows from the result set of a database query. Backing Managed-Bean backing-bean request Description: This type of managed-bean participates in the "View" concern of the MVC design pattern. The purpose of a backing-bean is to support UI logic, and has a 1::1 relationship with a JSF view, or a JSF form in a Facelet composition. Although it typically has JavaBean-style properties with associated getters/setters, these are properties of the View -- not of the underlying application data model. JSF backing-beans may also have JSF actionListener and valueChangeListener methods. Controller Managed-Bean controller-bean request Description: This type of managed-bean participates in the "Controller" concern of the MVC design pattern. The purpose of a controller bean is to execute some kind of business logic and return a navigation outcome to the JSF navigation-handler. JSF controller-beans typically have JSF action methods (and not actionListener methods). Support Managed-Bean support-bean session / application Description: This type of bean "supports" one or more views in the "View" concern of the MVC design pattern. The typical use case is supplying an ArrayList to JSF h:selectOneMenu drop-down lists that appear in more than one JSF view. If the data in the dropdown lists is particular to the user, then the bean would be kept in session scope. However, if the data applies to all users (such as a dropdown lists of provinces), then the bean would be kept in application scope, so that it can be cached for all users. Utility Managed-Bean utility-bean application Description: This type of bean provides some type of "utility" function to one or more JSF views. A good example of this might be a FileUpload bean that can be reused in multiple web applications. Now... One of the main benefits in making fine distinctions like this is loose coupling. What's that you ask? Well let's first take a look at an example of tight coupling, where MVC concerns can be smashed/confused into a single managed-bean: public class ModelAndBackingAndControllerBean { private String fullName; // model-bean property private boolean privacyRendered; // backing-bean property // model-bean getter public String getFullName() { return fullName; } // model-bean setter public void setFullName(String fullName) { this.fullName = fullName; } // backing-bean getter public boolean isPrivacyRendered() { return privacyRendered; } // backing-bean setter public void setPrivacyRendered(boolean privacyRendered) { this.privacyRendered = privacyRendered; } // backing-bean actionListener for UI support logic public void togglePrivacySection(ActionEvent actionEvent) { privacyRendered = !privacyRendered; } // controller-bean business logic public String submit() { System.out.println("fullName=" + fullName); return "success"; } } The problem here is that the bean would have to be kept in session scope because of the model-bean property. Additionally, what if we wanted to do some unit testing with mock model data? Can't do it. So in order to fix these problems, and to promote loose coupling, we would have three separate Java classes: public class ModelBean { private String fullName; public void setFullName(String fullName) { this.fullName = fullName; } public String getFullName() { return fullName; } } public class BackingBean { private boolean privacyRendered; public void setPrivacyRendered(boolean privacyRendered) { this.privacyRendered = privacyRendered; } public boolean isPrivacyRendered() { return privacyRendered; } public void togglePrivacySection(ActionEvent actionEvent) { privacyRendered = !privacyRendered; } } public class ControllerBean { private ModelBean modelBean; public ModelBean getModelBean() { return modelBean; } public void setModelBean(ModelBean modelBean) { // Dependency injected from the JSF managed-bean facility this.modelBean = modelBean; } public String submit() { System.out.println("fullName=" + getModelBean().getFullName()); return "success"; } } Now that the beans are found in different classes, they can all be kept in their appropriate scopes. The model-bean can be kept in session scope, and the backing-bean and controller-bean can be kept in request scope, thus saving memory resources on the server. Finally, we can use the dependency injection features of the JSF MBF in order to inject the model-bean into the controller-bean. This can be seen in the following WEB-INF/faces-config.xml example, where the #{modelBean} Expression Language (EL) binding is used: modelBean myproject.ModelBean session backingBean myproject.BackingBean request controllerBean myproject.ControllerBean request modelBean #{modelBean} From http://blog.icefaces.org/
April 24, 2009
by Neil Griffin
· 64,063 Views · 2 Likes
article thumbnail
Enterprise Integration Patterns with Apache Camel Refcard Now Available!
Apache Camel is a powerful open source integration platform based on Enterprise Integration Patterns with Bean Integration. This Refcard provides you with eleven of the most essential patterns that anyone working with integration must know. This Refcard is targeted for software developers and enterprise architects, but anyone in the integration space can benefit as well. Download Now! About the Author: Claus Ibsen is a passionate open-source enthusiast who specializes in the integration space. As an engineer in the FuseSource Open Source Division he works full time on Apache Camel, FUSE Mediation Router (Apache Camel Enterprise) and related projects. Claus is very active in the Apache Camel and Fuse communities, writing blogs, twittering, assisting on the forums, irc channels and is driving the Apache Camel roadmap.
March 30, 2009
by Wei Ling Chen
· 4,846 Views
article thumbnail
Apache Camel: Integration Nirvana
Take any integration project and you have multiple applications talking over multiple transports on multiple platforms. As you can imagine, in large enterprise applications this can get complex very fast. Much of the complexity stems from two issues: 1. dealing with the specifics of applications and transports, and 2. coming up with good solutions to integration problems. Making your applications speak transports and APIs is relatively easy on its own. I'm sure everyone knows how to send JMS messages to their broker of choice; though it still requires in depth knowledge of the JMS specification, which many developers may not have. On top of that, what happens when you want to route that JMS message to another application? You then have to take care of mapping the JMS message to the application plus handle any new concepts related to the application. Add a dozen other applications into the mix and you've got quite a headache on your hands. Ignoring the mechanics of how to connect with multiple transports and APIs, we can focus on the high level design of how applications interact. Fortunately, most solutions to enterprise integration problems have been formalized already. Gregor Hohpe and Bobby Woolfe's book, Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions, boils down years of experience from enterprise architects into a set of sixty five Enterprise Integration Patterns (EIPs). This is great but we still have to hand code all parts of these patterns; these are not packaged solutions, only recommendations. Apache Camel was created with the intention of addressing these two issues. In this article I'll show you how it actually does this. What is Camel? Apache Camel is an open source Java framework that focuses on making integration easier and more accessible to developers. It does this by providing: • concrete implementations of all the widely used EIPs • connectivity to a great variety of transports and APIs • easy to use Domain Specific Language (DSL) to wire EIPs and transports together Figure 1 shows how these three items actually map to Camel concepts. To give you a good understanding of how Camel is organized, we will discuss Components, Endpoints, Processors, and the Domain Specific Language (DSL). There is of course a lot more going on here under the hood but we'll leave that for another discussion. Figure 1: High level view of Camel's architecture. Components are the extension point in Camel to add connectivity to other systems. The core of Camel is very small to keep dependencies low, promote embeddability, etc. and as a result contains only 12 essential components. There are over 60 components outside the core. To expose these systems to the rest of Camel, Components provide an Endpoint interface. By using URIs, you can send or receive messages on Endpoints in a uniform way. For instance, to receive messages from a JMS queue aQueue and send them to a file system directory "c:/tmp", you could use URIs like "jms:aQueue" and "file:c:\tmp". Processors are used to manipulate and mediate messages in between Endpoints. All of the EIPs are defined as Processors or sets of Processors. As of writing, Camel supports 41 patterns from the EIP book, 6 other integration patterns, and many other useful Processors. To wire Processors and Endpoints together, Camel defines a Java DSL. The term DSL is used a bit loosely here as it usually implies the involvement of a compiler or interpreter that can process keywords specific to a particular domain. In Camel, DSL means a fluent Java API that contains methods named like terms from the EIP book. Its best explained with an example from("jms:aQueue") .filter().xpath("/person[@name='Jon']") .to("file:c:\tmp"); Here we define a routing rule in a single Java statement that will consume messages from the "jms:aQueue" Endpoint, send them through a Message Filter Processor, which will then send on messages passing the XPath condition to the "file:c:\tmp" endpoint. Messages failing the condition will be dropped. You can also configure your routes in a XML-based Spring configuration file. This configuration file is a lot more verbose and less auto complete friendly than the Java DSL; many prefer it though because of its direct access to Spring concepts and no requirement for compilation after changes. Here is what the earlier example would look like in Spring: /person[@name='Jon'] These are the concepts that Camel was built upon. Since then many other interesting features have been added. Details of these are left up to the reader to investigate. To get you started, some of these include: • Pluggable data formats and type converters for easy message transformation between Artix Data Services, CSV, EDI, Flatpack, HL7, JAXB, JSON, XmlBeans, XStream, Zip, Camel-bindy, etc. • Pluggable languages to create expressions or predicates for use in the DSL. Some of these languages include: EL, JXPath, Mvel, OGNL, BeanShell, JavaScript, Groovy, Python, PHP, Ruby, SQL, XPath, XQuery, etc. • Support for the integration of beans and POJOs in various places in Camel. • Excellent support for testing distributed and asynchronous systems using a messaging approach • and much more... Example A motorcycle parts business, Rider Auto Parts, supplies parts to motorcycle manufacturers. Over the years they've changed the way they receive orders several times. Initially, orders were placed by uploading CSV files to an FTP server. The message format was later changed to XML. Currently they provide a web site to submit orders as XML messages over HTTP. All of these messages are converted to an internal POJO format before processing. Rider Auto Parts states to any new customers to use the web interface to place orders. However, because of existing agreements with customers, they must keep all the old message formats and interfaces up and running. Solution using EIPs Rider Auto Parts faces a pretty common problem; over years of operation businesses acquire software baggage in the form of transports/data formats that are popular at the time. Using patterns from the EIP book we can envision the solution as something like Figure 2. Figure 2: This shows the solution to Rider Auto Parts integration problem using notation from the Enterprise Integration Patterns book. So we have several patterns in use here. 1. There are two Message Endpoints; one for FTP connectivity and another for HTTP. 2. Messages from these endpoints are fed into the incomingOrderQueue Message Channel 3. The messages are consumed from the incomingOrderQueue and routed by a Content-Based Router to one of two Message Translators. As the EIP name implies, the routing destination depends on the content of the message. In this case we need to route based on whether the content is a CSV or XML file. 4. Both Message Translators convert the message content into a POJO, which is fed into the orderQueue Message Channel. The whole section that uses a Content-Based Router and several Message Translators is referred to as a Normalizer. This composite pattern has a unique graphic to depict it but was left out here in favor of its sub-patterns to make things clearer. Implementation using Camel As mentioned before, Camel has a small core set of components included by default. The rest of the components exist as separate modules. In applications that require many types of connectivity it is useful to figure out what Camel modules to include. Listing 1 shows the dependencies using Apache Maven for the Camel implementation of the Rider Auto Parts example. Of course, you don't need to use Apache Maven for dependencies - it is just the easiest way to rapidly add new dependencies to your applications. The list of dependencies includes support for core Camel, ActiveMQ, JAXB marshaling, CSV marshaling, and HTTP. To make the example easier to try out, I've opted to use the File endpoint instead of the FTP. If we were using the FTP endpoint we would need to add a dependency on the camel-ftp module as well. Listing 1: Maven dependencies for the Camel implementation org.apache.camel camel-core ${camel-version} org.apache.camel camel-spring ${camel-version} org.apache.activemq activemq-camel ${activemq-version} org.apache.camel camel-jaxb ${camel-version} org.apache.camel camel-csv ${camel-version} org.apache.camel camel-jetty ${camel-version} org.apache.activemq activemq-core ${activemq-version} org.apache.xbean xbean-spring ${xbean-spring-version} While it is perfectly legitimate to use Camel as a standalone Java application, it is often useful to embed it in a container. In this case, we will be loading Camel from Spring. The Spring beans XML file is shown in Listing 2. First we start an embedded Apache ActiveMQ broker and connect Camel to it. We also load up some helper beans that we will reference from the DSL. Finally, the camelContext element tells Camel to look for routes in the org.fusesource.camel package. Routes are Java classes that extend the RouteBuilder class in Camel. Listing 2: Spring XML file that configures an embedded ActiveMQ broker, several beans used in the Camel route, and initializes the Camel Context to search for routes in the org.fusesource.camel package. org.fusesource.camel The real meat of the Camel implementation lies in the OrderRouter class (shown in Listing 3). This class extends RouteBuilder, so it will be automatically picked up and loaded by Camel's runtime. Looking back at Figure 2, we need to receive orders from an FTP (substituted with File) and HTTP endpoint, formatted as shown in Listing 4. In the DSL we can specify these incoming endpoints with two from elements. Both from elements are connected to a to("jms:incomingOrderQueue") element, which will send the messages to a queue on the ActiveMQ broker. Listing 3: Route definitions for the example. The routing rules are specified using a fluent API, referred to as Camel's DSL. public class OrderRouter extends RouteBuilder { @Override public void configure() throws Exception { JaxbDataFormat jaxb = new JaxbDataFormat("org.fusesource.camel"); // Receive orders from two endpoints from("file:src/data?noop=true").to("jms:incomingOrderQueue"); from("jetty:http://localhost:8888/placeorder") .inOnly().to("jms:incomingOrderQueue") .transform().constant("OK"); // Do the normalization from("jms:incomingOrderQueue") .convertBodyTo(String.class) .choice() .when().method("orderHelper", "isXml") .unmarshal(jaxb) .to("jms:orderQueue") .when().method("orderHelper", "isCsv") .unmarshal().csv() .to("bean:normalizer") .to("jms:orderQueue"); } } In the case of the HTTP endpoint, there are a couple of extra things to mention. First off the HTTP client will be expecting a response from the application so we have to handle that. In Camel, we have full control over what the client gets back from the HTTP endpoint. Each response is determined by the last method in our current route definition (each Java statement is a route definition). In our case we use the transform method to set the response to the constant string "OK". Since we handle the response ourselves, we don’t want any response to come from the JMS incomingOrderQueue. To send to this queue in a fire-and-forget fashion we add the inOnly modifier. It is important to note at this point that when writing Camel DSL in a modern Java IDE, selection of the next processing step is easy because of auto complete. The auto complete feature basically gives you a list of processors (i.e. EIPs) to choose from at any point in your route. Since fluent APIs chain methods together, the only method you need to remember is the from; all other methods are shown via auto complete. Listing 4: Incoming message formats; XML on top, CSV below. "name", "amount" "brake pad", "2" The next section of DSL in Listing 3 specifies the Normalizer, complete with Content-Based Router and two Message Translators. First we specify that we want to consume messages from the incomingOrderQueue on the ActiveMQ broker. The content based routing of the messages is done with the choice and when methods. In our case, we want to send CSV messages to one Message Translator and XML messages to another. To check what type of message we have we will be using a simple Java bean shown in Listing 5. Of course, this is demonstration code only; for production cases you would want to add more thorough checking of content types. Listing 5: Java bean that contains helper methods to be used in the DSL. public class OrderHelper { public boolean isCsv(String body) { return !body.contains("> body) { List orderHeaders = body.get(0); List orderValues = body.get(1); return new Order(orderValues.get(0), Integer.parseInt(orderValues.get(1))); } } At this point, successfully normalized messages are sent to the orderQueue for processing by some other application at the Rider Auto Parts business. Conclusion In this article I've shown two common problems that an integration developer may face: dealing with the specifics of applications and transports, and coming up with good solutions to integration problems. The Apache Camel project provides a nice answer to both of these problems. As the example has shown, solving integration problems with Camel is straight forward and results in relatively concise code. In my opinion it is the closest thing to integration nirvana that we have today. Links Apache Camel – http://camel.apache.org FUSE Mediation Router (based on Apache Camel) – http://fusesource.com/products/enterprise-camel Enterprise Integration Patterns – http://www.enterpriseintegrationpatterns.com Jon’s Blog – http://janstey.blogspot.com Camel in Action book - http://www.manning.com/ibsen Article source code - http://repo.fusesource.com/maven2/org/fusesource/examples/rider-auto-example/1.0/rider-auto-example-1.0.zip Author Jonathan Anstey is a senior engineer working for Progress Software Corporation specializing in the enterprise integration space. Jon focuses mostly on Apache Camel and its Progress endorsed likeness, FUSE Mediation Router. He also works on the Apache ActiveMQ and Apache ServiceMix projects
March 23, 2009
by Jonathan Anstey
· 223,817 Views · 8 Likes
article thumbnail
Wicket Tutorial Series: Setting Up the Project
Each day this week will feature a new article with an in-depth look at the creation process behind setting up a Java project and implementing the frontend with Apache Wicket. Wicket is a Java web application framework which allows “Designers” (people good with Dreamweaver) and “Developers” (people good with Java and Databases) to collaborate on a project with minimal chances of stepping on each other’s toes or wearing each other’s hats. The beauty of Wicket is that it uses plain xhtml pages as it’s templating markup. This means that html pages can be loaded into Dreamweaver (or whatever tool the Designer is comfortable with) and they will look very close to the same as they would when rendered on the deployment web server. Workflow The basic workflow involved in creating and maintaining html rendered by Wicket is as follows: The Designer creates the html for the website and fleshes it out with “mock” sections. For instance in the application we intend to create during our Five Days of Wicket will be a pastebin application called “Mystic Paste”. In our application we’ll have an “Add Code to Mystic Paste” page, mock data might include some user created content in the textarea of the page. All css/images, etc… are setup such that if they were to be put on a webserver, everything would work. The Developer needs to flesh out the dynamic areas of the webpage, that is, he needs to instruct Wicket where it will need to show information from the server. The developer does this by decorating the designer’s html page with special Wicket tags and attributes. Because these tags and attributes are just considered part of another namespace separate from xhtml’s, editors like Dreamweaver and browsers will simply ignore them - It is important to note: The developer will still keep the “mocked” sections of the page intact, this is so the page renders and looks fleshed out on its own. The mocked sections will be replaced by real data when rendered by Wicket. The Developer hands the file back to the Designer. The Designer is free to make further edits, so long as he/she does not remove or manipulate the Wicket tags and attributes present in the file. If the Designer does need to remove any Wicket tags or attributes, they need to consult the Developer as such an action will “break” the webpage when Wicket renders it. Example Wicket Page Here is an example of a Wicket page. This example was taken from Manning Publishing’s book “Wicket in Action”: ... Gouda Gouda is a Dutch... $1.99 add to cart Emmental Emmental is a Swiss che... $2.99 add to cart ... This looks almost 100% like a normal webpage would look, the only difference is the addition of the “wicket:XXX” attributes and tags sprinkled through the document. The parts of the document using the special Wicket namespace modifiers will be replaced/removed in the final markup when Wicket renders the page to the user’s browser. Notice the “” element? This is where your designer can put a “mocked” version of what that area of the page should look like. You as a developer can take that mocked html and divide it out into a template that is dynamically driven from the backend. Here is how the final page looks if you were to simply load the page into a web browser (or Dreamweaver) from your hard drive: Preparing for Setup Deviating a bit from the Standard Wicket Convention One of the first things a developer notices when starting out with Wicket is the convention where Wicket likes having its html template files live at the same level and in the same packages as it’s Java source files. Sure you can jump through hoops to get Wicket to load the html template files from elsewhere but a nice compromise is to simply keep your html template files within the same package directory structure but in a source folder separate from the Java classes. Why? Well quite simply to keep your designers (Dreamweaver folks!) from having to grab Java source files along with the html files they are working on. It will just confuse them and clutter their directories. You can of course stick with the typical “Java source files along side html” convention if you wish, but I find it much cleaner to separate them during design time, and have Maven combine them only at build time into the target war (which it will gladly do automagically). Project Folder Structure . |-- pom.xml |-- src | `-- main | |-- filters | |-- java | | `-- com | | `-- mysticcoders | | `-- mysticpaste | | |-- model | | |-- persistence | | | |-- exception | | | |-- hibernate | | |-- services | | `-- web | | |-- ajax | | |-- pages | | |-- panels | | `-- servlet | |-- resources | | |-- com | | | `-- mysticcoders | | | `-- mysticpaste | | | |-- spring | | | `-- web | | | |-- ajax | | | |-- pages | | | `-- panels | | `-- log4j.properties | |-- sql | `-- webapp | |-- WEB-INF | |-- images | |-- js | `-- css src/main: maven builds source and resources from this directory to the main deployable target (i.e. our war file) filters: we keep a set of “filters” files that maven can use to interpolate variables at build time. What does this mean? It means that inside your configuration files, the files you use to setup database connections or file paths, you can insert variable place holders like ${db.host}. When maven does a build, it looks up the correct filter file to use and looks for the key=value part corresponding to “db.host” and inserts it into the configuration file for you. This ensures that you are able to configure your application per environment you deploy to (i.e. DEV, QA, PROD, etc…) by having different filter files with the same keys but different values. For more information see Maven’s documentation on filtering resource. java/*: this folder will contain all of the application’s source code. Everything from the database access code, wicket code and services code for the mysticpaste application (see below). model: all “domain” classes, that is, classes that represent the objects in the application. For mysticpaste you’ll see classes like “PasteItem” which represents an item pasted to the mysticpaste. persistence: at this level of the persistence package a list of interfaces will be kept. The interfaces comprise the basic access layer the services layer will use to save, retrieve and update items to/from the paste bin. exception: the peristence layer needs to tell the services layer when things have gone wrong. It does this via delcaring and throwing exceptions. hibernate: such is our case, our persistence interfaces will be implemented via the ORM known as Hibernate. This package will store all of the custom hibernate implementations and hibernate specific classes services: The services layer will be stored here. Both the generic interfaces and their implementation classes. The persistence layer will be injected via spring. web: this folder is where our Wicket classes will reside and it’s split into several category packages which are as follows: ajax: mysticpaste uses Ajax to render portions of its UI. The wicket classes which render the xml/html to be injected dynamically into the page are stored here. pages: standard Wicket page classes which are used throughout the application are stored here panels: reusable panel classes are stored here. Panels may be included within Wicket pages for sake of templating servlet: any run of the mill servlet code we need is stored here. A good example might be an ImageUploadServlet resources/*: the resources folder will hold our non-java based files. Noteably html files and spring confguration files spring: Holds any spring configuration files needed to wire the services and persistence layer web: this folder and all subfolders mirror the packages under src/main/java/…/web and hold the .html files that the Wicket page/panel classes use as their templates. As described above, a “standard” wicket application simply stores the .html files along side their Wicket classes under src/main/java/…/web, however we want to keep these files separate from the Java source so as to keep the directory our designers checkout from version control contianing only the files they need to work on. sql: any sql scripts we need to keep handy for building the mysticpaste database. webapp: this folder will keep the files which live at the base directory of our war file WEB-INF: where you keep your web.xml file images: any image resource, .gif/.png/.jpg files your webapp will reference js: javascript files your webapp will reference css: style sheets your webapp uses src/test/*: All files which reside under this folder are test classes and resources needed to support the tests. Maven will build everything under src/main/java and add it to the class path of the JUnit or TestNG classes you create. java: JUnit or TestNG test classes which will be run during a build resources: resource files which are needed to support the tests Getting Started Since we are using Maven as our build tool we can take advantage of the fact that the fine folks at the Wicket project have created a specialized “archetype“ which creates a skeleton web application complete with a folder structure which mimics roughly what we have outlined above and Maven pom.xml file used to build a war. The Wicket contributors have even gone one step further and have created a little web page which will, based off a few drop down options, generate the maven command you need to execute in order to create the boiler plate Wicket project. You can find this web page over on the Apache Wicket site under the “Quick Start” link. Copying the above Maven command creates a Skeleton Wicket Project To be precise, the command I used was: mvn archetype:create -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.3.5 -DgroupId=com.mysticcoders -DartifactId=mysticpaste And I ended up with the following folder structure: . `-- mysticpaste |-- pom.xml `-- src |-- main | |-- java | | `-- com | | `-- mysticcoders | | |-- HomePage.html | | |-- HomePage.java | | `-- WicketApplication.java | |-- resources | | `-- log4j.properties | `-- webapp | `-- WEB-INF | `-- web.xml `-- test `-- java `-- com `-- mysticcoders |-- Start.java `-- TestHomePage.java Now obviously we’ll have to rearrange a few things, for instance I want my base package to be com.mysticcoders.mysticpaste, but that’s easy enough to do once we are in an IDE. For now, let’s test this example webapp out and see if it works. To do that switch into the mysticpaste directory (the directory that has pom.xml in it) and type the following: mvn jetty:run This will start up a Jetty webapp container running on port 8080 (if you have something running there already, use the -Djetty.port= option). Startup a webbrowser and navigate to http://localhost:8080/mysticpaste/ You should see: Your IDE Sooner or later you’re going to want to crack open your IDE and start hacking away. Maven makes this extremely easy by allowing you to create IDE specific project files based off of the Maven pom.xml file. Eclipse mvn eclipse:eclipse For eclipse you’ll also have to set the M2_REPO classpath variable for the workspace your project resides under. Do this by entering the following command: mvn -Declipse.workspace= eclipse:add-maven-repo IntelliJ IDEA mvn idea:idea -OR- in IDEA 7+ simply open the pom.xml file Netbeans Netbeans supports maven out of the box, just “Open Project” and choose the mysticpaste directory that contains the pom.xml file When generating the project files through Maven, the project is setup such that classpath entries point to your local Maven repository (i.e. ~/.m2/repository, or C:Documents and Settingsyourusername.M2repository on Windows). It also sets up src/main/java, src/main/resources as “source folders”. You may add other folders to the source folder list as per your IDE if needed, the only thing you have to remember is if you ever use mvn eclipse:clean followed by mvn eclipse:eclipse again, those other source folders will have to be readded through your IDE. Instead, you should add the source/resource folders directly to your pom.xml, this way they will be maintained. Spring The Mystic Paste application will use Spring, and really you should too. Unless you have been hiding under a rock or work in a corporate environment so lame as to which technologies newer than 2002 are forbidden you should learn to accept Spring as a defacto standard. Dependency injection for the win! We add the following to our pom.xml: org.apache.wicket wicket-spring-annot org.springframework spring org.springframework spring-test org.springframework spring-tx wicket-spring-annot: allows us to wire our Wicket application via handy dependency injection annotations (i.e. @SpringBean, see Wicket documentation for more detail) spring: is just the core spring libraries spring-test: is a set of Spring integration classes for Unit testing spring-tx: is the Spring Transaction Management api for declarative transactions web.xml additions for Spring In order for Spring to manage our Wicket application we need to setup the Wicket filter with a Spring-aware application factory. This allows us to wire our Wicket Application class in our applicationContext.xml file, which is really handy if you have a services and configuration settings you want to inject into the Wicket Application object so the rest of your application can access them. To do this, we change the original Wicket filter like so: wicket.mysticpaste org.apache.wicket.protocol.http.WicketFilter applicationFactoryClassName org.apache.wicket.spring.SpringWebApplicationFactory As well, we want our Spring context to be available to our webapp if ever there is a need for one of our pages to access the Spring managed beans directly: contextConfigLocation classpath:com/mysticcoders/mysticpaste/spring/applicationContext.xml org.springframework.web.context.ContextLoaderListener Hibernate Hibernate is our ORM of choice, it will allow us to persist and retrieve our model objects to and from the underlying database, whatever that database may be. We add the following to our pom.xml: org.hibernate hibernate-annotations c3p0 c3p0 commons-dbcp commons-dbcp javax.transaction jta 1.0.1B hibernate-annotations: used so we can annotate our model classes with mapping information, instead of having to create a separate mysticpaste.hbm.xml file. c3p0: provides a connection pooling library Hibernate can use commons-dbcp: another connection pooling library, we’ll add it as well and decide whether to use it or c3p0 later jta: this is the Java Transaction API which is needed by Hibernate (Hibernate provides an implementation of the API) web.xml additions for Hibernate To have a Hibernate Session open and ready for our webapplication during a Request Cycle we need to setup a Hibernate filter like so (otherwise, good luck getting lazy loading working!): open.hibernate.session.in.view org.springframework.orm.hibernate3.support.OpenSessionInViewFilter open.hibernate.session.in.view /* As the comment states above, make sure this filter-mapping exists *before* your wicket.mysticpaste filter or else it just plain won’t work. Database For the Mystic Paste we decided to use the freely available PostgreSQL. Adding support for PostgreSQL is very easy, unlike with some of the commercial DBMSes where you have to download and install their JDBC driver into your repository. To add support for Postgres, we simply add the following to our pom.xml: postgresql postgresql Servlets Regardless of which webapplication framework you choose there are just some times when a plain jane Servlet comes in really handy. If you have a need for Servlets and the Servlet must have access to the Wicket session add the following to your web.xml: wicket.session org.apache.wicket.protocol.http.servlet.WicketSessionFilter filterName wicket.mysticpaste And then, after your other filter-mappings add the following (assuming you mount your servlet-mappings under /servlet/): wicket.session /servlet/* Maven Filters and Profiles In order to build our Mystic Paste project for various environments (DEV/QA/PROD) we need to implement both Maven profiles and filters. Filters Filters allow you to place variables inside your configuration files and have those variables filled in durring build time. This is very handy for setting environment specific things such as database connection information. Enabling filters is quite easy, we open up the pom.xml file and find the section for and set the value for the element to true as follows: true src/main/resources . . . But for filtering to work, we need to specify a filters file. It’s not enough to specify only one filter file because we need to specify different filters per environment and we’ll do that by using Maven Profiles. Profiles To setup a profile, create a new set of elements following the section in your pom.xml file. Like so: DEV DEV DEV QA QA PROD PROD and just above your tag underneith your tag you would add the following elements: mysticpaste src/main/filters/filters-${env}.properties true src/main/resources src/main/filters will contain the following files. |-- pom.xml |-- src | `-- main | |-- filters | | `-- filters-DEV.properties | | `-- filters-QA.properties | | `-- filters-PROD.properties filters-DEV.properties jdbc.url=jdbc:postgresql://localhost:5432/mysticpaste jdbc.user=mysticpaste jdbc.password=password image.upload.path=/tmp/pasetbin/userimages image.upload.size.limit=4096K filters-PROD.properties jdbc.url=jdbc:postgresql://192.168.2.10:5432/mysticpaste jdbc.user=mysticpaste jdbc.password=CrYp71c image.upload.path=/mysticpaste/userimages image.upload.size.limit=4096K Now within any file under src/main/resources that has variables of the form ${variable.name} will have those variables replaced with the values specified in the proper filters file located under src/main/filters. For instance here is an example of a Spring applicationContext.xml file which will be interpolated with proper variables values at build time: applicationContext.xml To determine which filters file will be used depends on the profile chosen when building. For example, to build to production using the filters-PROD.properties we would execute the following: mvn clean deploy -P PROD The profile you use with the -P switch must match one of the values of the element for a profile. Conclusion Although it’s quite easy to get started with the Maven QuickStart project it is sometimes a bit frustrating putting some of the additonal pieces together. Building to several environments, setting up depenencies not included in the QuickStart project and strucuturing your project in an effort to make life easy for yourself as a developer and for your designer. I hope our Day 1 tutorial leaves you with a good sense of how a Wicket project is setup, now we can move onto coding the app! In the next four days we will be covering: Writing the Tests Designing the backend Designing the Wicket components Putting it all together Mystic Coders, LLC has been coding web magic since 2000. Mystic is a full-service Development Agency specializing in Enterprise development with Java. They are usually involved in developing enterprise-grade software for companies large and small, and have experience working in diverse industries, including b2b, b2c, and government-based projects. Mystic has done work with large companies such as LeapFrog, Nestlé, Harrah's Entertainment and the Los Angeles Conventions & Visitor's Bureau, among others. Andrew Lombardi, CTO of Mystic, is available for speaking engagements. For more about Mystic, check us out at http://www.mysticcoders.com
March 10, 2009
by Craig Tataryn
· 30,168 Views
article thumbnail
Camel Component For Amazon SQS
As its name implies Amazon Simple Queue Service (Amazon SQS) is a simplified version of a Messaging system. The great thing about it is its reliability and high scalability features. Amazon SQS makes it easy to build an automated workflow, working in close conjunction with the Amazon Elastic Compute Cloud (Amazon EC2) and the other AWS infrastructure web services. You can learn more about Amazon SQS here. The Problem My colleagues (Tom Purcell and Rod Biresch) and myself have been working on a demo application for Chariot Solutions' Emerging Technologies for the Enterprise conference and the need for a transport component to simplify the access of Amazon SQS arose. We have decided to use FUSE ESB(ServiceMix) 4 as the services integration platform for the demo application, and knowing that Apache Camel collaborates very well with ServiceMix, we decided to use it for the routing and transformation needs. Currently, neither ServiceMix, nor Camel provide a component to access Amazon SQS. Besides this limitation the remaining capabilities provided by these products still made it a great choice for the demo application. To learn more about the demo application, please visit Tom Purcell's blog. I also recommend attending to the Tom Purcell's presentation titled "Bus In the Cloulds" where he'll be speaking about Could Computing use cases and how Open Source Integration technologies can help resolve issues encountered while integrating with business partners. Another important part in production applications is management and monitoring. To learn more about how to monitor this application, please visit Rod Biresch's blog. A Solution Apache Camel makes it relatively easy to compose your own components, so the next logical step was to try to create one. Having seen Dave Kavanagh's Typica API in action and how easy it makes the communication with SQS, we decided to try and come up with such Camel component using this API as the back-bone. The Camel Amazon SQS Component The basic idea is to create a component that could be used in the following fashion: The above example shows a Camel route that sends data found in files placed in the data directory to a SQS queue named "dataQueue". In the to URI "sqs:sqsProducer?accessId=....", the protocol "sqs" will tell Camel what component to configure and attributes will be mapped the properties of either the Endpoint, or the Producer class. The documentation on writing Camel Components can be found here. Let's dive into the design of the Camel SQS component. The main steps for writing a Camel Component are: Write a POJO which implements the Component interface. The simplest approach is just to derive from DefaultComponent. In our case, the class SQSComponent was created. This class extends DefaultComponent. To support auto-discovery of your component add a file to META-INF/services/org/apache/camel/component/sqs where 'sqs' is the URI scheme for your component and any related endpoints created on the fly. The sqs file will contain the class attribute with the name of Class that implements the Component: class=com.chariotsolutions.soalab.camel.component.sqs.SQSComponent The Camel SQS Component is composed of the following artifacts: The SQSComponent Class This class serves as factory of Endpoints. When the component is being configured by Camel, the method of the createEndpoint is called. This method creates and configures the Endpoint (SQSEndpoint). The SQSEndpoint Class This class serves as a factory for Producers, Consumers, and Exchanges. After the SQSComponent.createEndpoint is execute, an instance of the class SQSEndoint is created. This class contains the properties used by the SQSConsumer class. These properties are: private String accessId; private String secretKey; private String queueName; This class extends ScheduledPollEndpoint and is used to create instances of the SQSProducer and SQSConsumer. The use of the ScheduledPollEndpoint is with the intention to use polling facilities it provides to query the SQS Queue at a specified time intervals. The SQSConsumer Class This class extends the ScheduledPollConsumer class to indicate that it will be excueted in poll intervals. The poll intervals are configured in the Component URI using the consumer.initialDelay and consumer.delay attributes like so: The poll() will be executed based on the configuration specified above.This method uses the Typica API to interact with the Amazon SQS Web services. If a message was found in the SQS Queue, it will e forward to the handleMessage. This method will set the message in a wrapper class called SQSObject, place it in the SQSExchange and send it flow of the route using the synchronous Processor by default. The attribute asyncProcess=true would cause it to use the AsyncProcess. The SQSProducer Class This class extends the DefaultProducer class. It processes the message coming from the Camel flow and sends it to the SQS queue, then it sets the assigned message id to the SQSObject, which is later added to the SQSExchange in case other components need it down the road. The SQSExchange Class This The base message exchange interface providing access to the request, response and fault instances. The SQSObject Class This is convenient POJO that wraps the payload and properties coming from the SQS Queue. Taking the Camel SQS Component For A Ride To see the Camel SQS Component in action, I created a small sample application. The sample application can be found in here. Here are the steps to build and run the application: If you haven't already done so, create an Amazon SQS account using the "Sign Up" button in this page. Extract the sample code to a directory of your choice. For example, /tmp/sqs-sample. You should see 2 directories in there, camel-sqs (camel sqs component) and camel-sqs-route (sample camel route). Navigate to the camel-sqs directory and build the code using: mvn clean install Navigate to the camel-sqs-route directory. Edit the file src/main/resources/aws.properties. Specify aws.accessId and aws.secretKey for your Amazon SQS account. Edit the file src/main/resources/META-INF/spring/camel-context.xml. Find the file endpoints and modify them to point to the directories of your choice. The File-In endpoint is where you would supply the data files to be sent to the SQS queue. The File-Out endpoint is the directory where the files containing the contents of the SQS queue will be placed on. Build the code using: mvn clean install Run the code using: mvn camel:run You should be able to place your sample text files directory pointed by the File-In endpoint. After a few seconds the output files will be placed in directory pointed by File-Out. Conclusion Amazon SQS combined with ServiceMix and Camel are a great platform for building your IaaS (Infrastructure as a Service) projects. Hopefully future versions of Apache Camel will include such component. The Camel CAMEL-1432 JIRA issue has been created for this reason.Happy Cloud Computing! Recommended Sites Tom Purcell's Blog Rod Biresch's Blog Amazon SQS FUSE ESB (ServiceMix) 4 Apache Camel Chariot Solutions
March 9, 2009
by Roberto Rojas
· 21,361 Views
article thumbnail
JBoss RichFaces with Spring
This article is going to show you how to build a RichFaces application with Spring.
February 16, 2009
by Max Katz
· 203,775 Views
article thumbnail
An Overview of Servlet 3.0
JSR 315 (Servlet 3.0) is an update to the existing Servlet 2.5 specification. Servlet 3.0 is focussed on extensibility and web framework pluggability, aligning with the goals of Java EE 6. Ease of Development (EoD) will be supported using newer language features. A reference implementation is available in the GlassFish v3 nightly build. The public review contains: Pluggability EoD Async Support Security Enhancements Miscellaneous Changes In this article we will bring you up to speed with what's happening with the Servlet 3.0 specification and give more detail on what is included. Note: this article corresponds to the public review of the specification. As it is not yet final some things may change. The Expert Group Rajiv Mordani from Sun Microsystems is the specification lead with an expert group comprised of many of the most recognisable names in the Java community: Adobe Systems Inc. Apache Software Foundation BEA Systems Ericsson AB Google Inc. Hunter, Jason IBM Icesoft Technologies Inc NCsoft Corporation Oracle Pramati Technologies Prasanna, Dhanji R. SAP AG Ship, Howard M. Lewis Suleiman, Hani Sun Microsystems, Inc. Tmax Soft, Inc. Walker, Joe Wilkins, Gregory John Pluggability Due to the popularity of so many various web frameworks, Servlet 3.0 will make it easier to use and configure the developer's framework of choice. So if you want to add in Struts, or Spring Web Flow it will be easy to do so. Methods to add Servlets and Filters If a ServletContextListener is registered and wants to add a Servlet or Filter, then at the time of context initialization the event that is fired to the Listener can add Servlets and Filters to the context. The methods are addServlet and addFilter. For more details look for the javadocs at the JCP site at http://jcp.org/aboutJava/communityprocess/pr/jsr315/index.html. Web fragments Instead of having just one monolithic web.xml that is used by the developer to declare servlets, filters and other configuration for using the framework, the framework can now include a web-fragment.xml with all it's configuration. A web-fragment is almost identical to the web.xml and can contain all the configuration needed by the framework in the META-INF directory of the framework's jar file. The container will use the information to assembe the descriptor for the application and the application needn't have to use any of the boilerplate configuration in their app for the framework. There are rules that are defined int the specification for conflict resolution, overriding and disabling fragment scanning. Along with the annotations which also can be in libraries the feature is very compelling not only for the developers that use frameworks but also for framework authors to be self sufficient in defining the configuration needed. The great benefit to this is that library providers can supply their own web.xml fragment for use in your webapp. Ease of Development Several new annotations have been defined for ease of development in Servlet 3.0, allowing you to write a Servlet without requiring a descriptor. These annotations reside in the javax.servlet.annotation package. Thanks to the addition of annotations, it is now possible to have Servlet, Filter and ServletContextListener in a war file without a web.xml. It's important to point out that this makes the web.xml optional, rather than redundant. The web.xml may be user to override metadata specified via annotations. Following discussions in the expert group and the community, it was decided that method level annotations were not to be added, so you keep the doGet, doPost methods and need to extend HttpServlet to use them. Let's take a closer look at the annotations present in the Servlet 3.0 specification: Servlet Annotation In Servlet 3.0, servlet metadata can be specified using @WebServlet @WebServlet(name="mytest", urlPatterns={"/myurl"}, initParams={ @InitParam(name="n1", value="v1"), @InitParam(name="n2", value="v2") }) public class TestServlet extends javax.servlet.http.HttpServlet { .... } TestServlet extends HttpServlet, while the meta data provided corresponds with the web.xml as follows: Parameter Annotation Parameter web.xml Servlet name name= URL Pattern urlPatterns={ } Initialization parameters InitParams={ @InitParam{name=””, value=””} .. .. Servlet Filter Annotation ServletFilter meta data is specified using the @ServletFilter annotation public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { .... } public void destroy() { .... } } Parameter Annotation Parameter web.xml URL Pattern urlPatterns={ } Initialization parameters InitParams={ @InitParam{name=””, value=””} .. .. Servlet Context Listener Annotation A ServletContextListener is simply marked with the @WebServletContextListener rather than needing to list it the web.xml file. @WebServletContextListener public class TestServletContextListener implements javax.servlet.ServletContextListener { .... public void contextInitialized(ServletContextEvent sce) { .... } public void contextDestroyed(ServletContextEvent sce) { .... } } Async Support The biggest change made in the specification is the addition of asynchronous processing. The main cases to cover were: Waiting for a resource to become available, such as JDBC or a call to a Web Service. Generating response asynchronously Using exisiting frameworks to generate responses after waiting the for asychronous operation to complete. While the early draft had suspend and resume, the latest specification has two variations of the startAsync() method on ServletRequest. One (startAsync() ) takes no parameters and initialises an AsyncContext with the original request and response. The ( startAsync() ) other takes a request and response as a parameter to initialise the AsyncContext with. Servlets (@WebServlet) and Filters (@ServletFilter) that support asynchronous processing need to be annotated with the supportAsync attribute set. It is illegal to call startAsync if you have a Servlet or Filter that doesn't support asynchronous processing anywhere in the request processing chain. The is also an AsyncListener that can be registered to get notification on timeout and completion of asynchronous processing of the request. This listener can be used to clean up resources if the wrapped request and response were used to create it's AsyncContext. You can forward requests back to the container using the AsyncContext.forward(path) and AsyncContext.forward() methods so frameworks like JSP can create a response. Security Enhancements HTTPServletRequest will be enhanced with methods allowing programmatic login and logout, while ServletRequest will be able to force a login.The logout method will allow an application to reset the authentication state of a request without requiring the authentication to be bound to a HTTPSession. Conclusion The draft is just beginning to be implemented within Glassfish v3. The specification will be a required piece of Java EE 6 and hence all the features described above will be available in all Java EE 6 compatible containers. The presence of the various features described above will make developing Java web appications much easier. Thanks to Rajiv Mordani for his input into this article, and to Shing Wai and Jan Luehe for the code snippets.
January 21, 2009
by James Sugrue
· 77,625 Views · 2 Likes
article thumbnail
Creating a REST WCF Service From an Existing XSD Schema
A reader of my blog sent me an email asking the following question: “I have an XSD that I am required to use to export my company's data. How can I use that XSD and return data to them in a web method? I should be able to return a data set with the information formatted the way the XSD defines but I have no idea how to do that. Any ideas would save me a ton of time and grief!” Turns out this is a really good question, and I think one a lot of developers struggle with primarily because the majority of developers are scared of XSD schemas. Hopefully I can change that. An XML Schema is really simple and it is your friend. What is an XSD or Xml Schema Definition? An XML Schema describes the structure of an XML document. That’s it, see, it isn’t that hard after all! As a developer think of an XSD the same way you would when creating business rules to validate objects before storing them into a database. Some items in objects cannot be null, some can. Some need to have their data formatted (email address for example) and others need to not exceed certain lengths, etc. When dealing with an XML document, we need to apply the same type of rules and this is where the XSD comes in. Once we have an XSD to describe an XML document we can guarantee any XML data we receive conforms to these rules. Ok, enough intro, let’s get coding. The Schema In the case of the reader’s question, an XSD schema already existed. To save time, I’ve taken then general idea of the schema I was sent and slimmed it down for simplicity sakes. The schema represents an XML document that will contain job listings. Here is a view of the schema from the schema explorer in Visual Studio as well as the schema itself (again slimmed down). Once we have a schema defined like this we can generate code to be used for a service. We have a tool at our disposal that is available within the Visual Studio Command Prompt called XSD.exe. This executable does a lot of things but one thing it can do is generate code from an XML Schema Definition. When generating from the XSD file I was sent there was a problem with it. Here is the walk through of that story so you can follow along. When I first tried this on the reader’s original XSD I got an error: Warning: cannot generate classes because no top-level elements with complex type were found. What does this mean? Well, look at the screen shot of the XML Schema Explorer above. Do you see the <> green icons? Well those represent an XML Element. An element is a fancy name for an XML tag like: Bramar Let me roll this up and take another screen shot so you can start to see the problem (i have to hit my magic number of 12 screen shots anyway :) ). See the problem? There isn’t an element in this schema (no green <> thingy). What this means is we have a schema which just lists complex types of elements and enumerations. There isn’t any “xml” in this schema. The fix is simple though. Add an element to the schema. Now we have a green thingy icon which means this XSD contains at least one element. Basically think of the JobListing element as the root element. Now that we have an element we can generate a C# class file from this XSD: The code generated is about 350 lines so I’m not going to include it in the article. There are some nice things happening for us when the C# classes are generated using xsd.exe. For starters the enumerations in the XSD are turned into C# enumerations. The classes are marked serializable and they have the appropriate XML attributes on the properties to serialize these objects into XML. This is a good thing since it means we didn’t have to create it. Code generation is your friend. Now that we have C# objects we can serialize these to XML easily. The Service The first thing we need to do is create the WCF service. For this example I chose to create a WCF Service Application in Visual Studio 2008. After the project is initialized, the first thing we need to do is define the contract for the service. In other words, what is coming in and going back out. Since we have generated our code using the XSD utility we are going to use the XmlSerializer with our service. The reason is this will make sure our XML formatted the way we intended. While we are at it, I’ve made the service a RESTful type of service. Here is the contract. [ServiceContract] public interface IJobService { [OperationContract] [XmlSerializerFormat] [System.ServiceModel.Web.WebGet(UriTemplate="/jobs/{type}", RequestFormat=WebMessageFormat.Xml)] List GetJobListings(string type); } The contract above has one method GetJobListings(). This method has two additional attributes. One, the attribute to mark the method to serialize using the XmlSerializer and two the attribute to turn the method into a RESTful service. In other words our service can be accessed like this: http://localhost/service.svc/jobs/full-time Now that the contract is setup, we just need a class to implement this contract on. Here’s a quick and dirty implementation. public class Service1 : IJobService { #region IJobService Members public List GetJobListings(string type) { return GetJobs(); } private static List GetJobs() { var jobs = new List(); jobs.Add(new Job { JobType= JobType.parttime, Category = JobCategory.Banking, Benefits= "You are on your own.", Description="I did something" }); jobs.Add(new Job { JobType= JobType.fulltime, Category = JobCategory.Banking, Benefits= "You get something." }); jobs.Add(new Job { JobType= JobType.contractor, Category = JobCategory.Banking, Benefits= "Times are tuff, deal with it." }); jobs.Add(new Job { JobType= JobType.fulltime, Category = JobCategory.Banking, Benefits= "How does $700 billion sound?" }); return jobs; } #endregion } Now all we have left is to get this working is to configure WCF to support our RESTful implementation. In order to do this we are going to use the webHttpBinding. Here is the WCF configuration to implement our RESTful service. That’s it, we are all setup. Now all we have to do is launch the service and browse to the URL we outlined earlier to get our results. This may seem like a lot of steps but it really isn’t. I encourage you to take this example and play with it. You can download the solution below. Download Solution WcfService.zip
December 18, 2008
by Keith Elder
· 33,327 Views
article thumbnail
Eclipse Tip: Incremental Find or Find as You Type
Eclipse has many ways of doing things. Finding the way that suits you can be tricky. :-) The standard find dialog triggered by Crtl+F is, well, standard. But if you are a keyboard junkie then it kind of gets in the way. The other way of searching with in the current editor is Incremental Search. This is triggered by Crtl+J and has no GUI! Just press Ctrl+J and type the search text. Eclipse finds and highlights the next match as you type. You can use the Up or Down arrow key to jump to the next or previous match. I like this way... From http://www.vasanth.in/
November 25, 2008
by Vasanth Dharmaraj
· 20,104 Views · 1 Like
article thumbnail
Enabling the Hover-Over-Help Feature Using JSP Custom Tags
This article introduces a presentation-tier JEE framework designed to enable the hover-over-help feature without hard coding JavaScript modules in the JSPs in your web or portal applications. The framework is packaged as a jar file for distribution and includes a server-side RESTful web service component and a set of JSP tag handlers which inserts JavaScript and Cascading Style Sheet (CSS) code into HTML files at the page rendering phrase. The targeted users are java developers who only have preliminary experience on writing JavaScript code. 1. Introduction Mouseover is a standard JavaScript event that is raised when the user hovers the cursor over a particular HTML element on a web page. This event has been widely used in web applications for navigation or causing an image or text to change. Hover-over-help, also called hover-over bubble, refers to the process of showing a small popup window when a mouseover event occurs in the browser. The window contains a message to either help the user to use the application or provide additional explanation and data. It is a useful feature which can make your web pages more intuitive and user-friendly and can carry more information on a single page in rich internet applications (RIAs). There are some tips and samples to enable the feature on the internet. However, they are not effective in developing large-scale web applications. Some of caveats include the following: The message contents are directly hard-coded in JavaScript. They are tied-coupled with graphic user interface components, such as text labels in web pages. The re-usability is low. If the same message needs to appear on several pages, the message and the pertaining JavaScript code have to be copied and pasted to each of these pages. It is hard to maintain these duplications in multiple places. The messages are designed to be static and are typically created when the page is designed. It is difficult to insert runtime data into messages on the fly. Portal applications are not completely supported. The framework introduced in this article is designed to address these issues and provides a comprehensive but easy-to-use solution to java developers who don’t have extensive JavaScript experiences. It leverages the JSP taglibary technology, the Dojo framework, and RESTful web services. Reusability in both web and portal environments, performance, and reliability are the factors that have been taken into consideration. 2. Message bubbles and messages 2.1 Message bubbles A message bubble is a rectangle information window containing a message. Each bubble has one color-coded title compartment and one content compartment. The window is decorated by CSS definitions. The image below illustrates a sample message bubble. Figure 1 – a hover-over-help message bubble Bubbles are not viewable in the webpage until the user moves his/her mouse over action labels or images. In this case, the mouse cursor will turn into a finger-pointing hand and the pertaining bubble window will pop up near the hand. 2.2 Data structure The message contents vary from static to dynamic considerably. However, all messages can share a common data structure, which typically consists of four parts: • Message ID: This is the primary key in each message, which is represented as a unique number. Given any single message ID, the framework is able to identify one and only one message. • Message title: This is a character string displayed in the title compartment in a bubble window. • Message content: This is character string that refers to the detail of a help message. The message content can contain HTML elements. • Color code: This is a character string representing the background color scheme of a bubble window. The value must be one of the following strings: “infor”, “data”, “warning”, or “link”. 2.3 Message types Based on the dynamicity of the contents, we categorized all messages into three types. Each of the types is described in this section, with samples provided. 2.3.1 Static Messages This type of message is considered static because its contents always retain the same. A static message can be the definition of a concept, the explanation of a field, or the instruction of a user action. The same messages will appear to any user on the same page when the page is visited. Valid examples include: • This is a example of a static message. • Click on the button below to submit your request. 2.3.2 Variable Messages These messages contain replaceable variables which are represented by tokens. A token is a non-whitespace character string surrounded by “${” and “}”. The token will be completely replaced by its actual value at the page rendering time on the server. The value is based on user data, and normally will not change for a longer-than-user-session period. From users’ perspectives, the same user will see the same message with his customized values when browsing the same page, but different users may see different messages. The following are examples of valid messages in this category: • Your first name ${firstname}. • Your annual goal is to sell ${yourgoalnumber} cars. 2.3.3 Dynamic Messages The messages in this category are the most dynamic ones and contain variables represented by tokens, as well. However, the actual values are populated based on the data associated to the user session. If it happens that a user session is shared by multiple applications, these values may be changed even without a page refresh. This situation typically occurs in portal applications where multiple portlets can access the same user session. It is possible that the same user will read different messages at a different time on the same page. The examples are – • You have talked to ${anumber} clients today. • It is ${servertimestamp} now. 3. Design and implementation In the design, messages are cached at server-side to gain the maximum performance. Two strategies have been implemented to support the hover-over-help feature for each of the message types described in the previous section. 3.1 Message caching Messages can be persisted in a database or flat text file, but regardless of where they are physically stored, they will be loaded and cached at the web container when it starts. The framework includes a class – CacheIntializer which implements the ServerContextListener interface to perform the job. All you need to develop is your own message loader class to retrieve your messages from storage. Your class must implement the com.myuan.tags.bubblemsg.serverside.MessageLoader interface in the framework, and its name must be added as a ContextParameter in the web descriptor. Please refer to the installation section for more details. 3.2 Dojo and CSS Strategy This strategy is designed to support static and variable messages. It can be referred as the push strategy, since help messages are embedded as html elements and pushed to users’ browsers along with the whole web page. No client-server communication is needed once the page download is done. The values will be kept the same until the page is re-loaded again. This strategy relies on a Dojo module to recognize particular “span” elements (listed in list 1) in html files. For each individual message bubble, two span elements are required. The first one represents a visible graphical component in a page, while the second one is the message bubble which isn’t visible for most of the time. When you move the mouse over the first “span” area, an action will be triggered by the browser, and a Dojo method will make the message bubble popped up (illustrated in Figure 1). The “id” attribute in the first “span” element and the “connectid” attribute in the second one are the keys to tie the pair together. These two attributes must have the same value. The value is randomly generated by the custom tags in the framework, which guarantees that the strategy can support both web and portal applications. Households Household A household includes all the persons who occupy a housing unit. Four tag handlers have been developed to support static message and variable message scenarios, respectively. At page-rendering time, the handlers can retrieve help messages from the cache, replace variable tokens in the messages if any, and create and insert value-matched “span” html elements into the web pages. The complete process is detailed in the sequence diagram in figure 2. Figure 2 – sequence diagram for the Dojo and CSS strategy 3.2.1 hohcsstag This tag inserts CSS definitions in JSP pages at the rendering time. It should be placed in the page head element. In the WebSphere Portal environment, this tag should be added in the Default.jsp file. 3.2.2 hohstatictag hohstatictag is a custom tag built for the static message scenario. It has five attributes: msgid: This is the primary key used to identify a message from the cache. This attribute is mandatory. label: This is the text which will be associated with a mouse-over action to display the message. style: This is the style definition that will be used to decorate the label above. This is the place where the user could overwrite CSS arributes for the label. bubblestyle: This is the place where the user could overwrite CSS attributes for the message bubble. img: If you need to enable the hover-over on an image instead of a text label, you can use this attribute and pass the path to your image. If this attribute appears in the tag, the value in the “label” and the “style” attributes will be ignored. A static message example -- Msg_id Msg_title Msg_content Color_cd 1 Household A household includes all the persons who occupy a housing unit. Infor JSP Fragment where the hohstatictag is used – //text //image 3.2.3 hohvariabletag and hohparamtag hohvariabletag and hohparamtag work together to support variable messages. The “hohvariabletag” has the same four attributes as the “hohstatictag” tag. One “hohparamtag” tag holds one name-value pair. The tokens in the message will be replaced with the values passed in from the hohparamtag when html elements are generated. The following is an example of how to use the custom tag. A variable message example-- Msg_id Msg_title Msg_content Color_cd 2 Recognition My retention rate is ${rate} and my goal is ${goal}. data JSP Fragment where the hohvariabletag and hohparamtag are used together – 3.2.4 hohgenerictag This tag has been created to provide a unified API for both static and variable messages. This tag can replace the “hohstatictag” or “hohvariabletag” without any syntax change. But there will be a minor performance cost if you use this tag on the static-message scenario instead of the hohstatictag. 3.3 AJAX strategy AJAX (Asynchronous JavaScript and XML) is a powerful web development technique in creating interactive web applications. The AJAX strategy was developed for the dynamic message scenario. It is a pull-based model, since messages are retrieved by an AJAX module at runtime from the server. This approach can guarantee that the message contains the latest data. When a mouseover event is triggered from a web page, the AJAX module invokes the server-side RESTful web service endpoint. The server-side component picks up the correct message from the message cache, replaces all variable tokens in it with the most current user-session data, and sends the final message back to your browser in the XML format. Upon receiving the response, the AJAX module populates the pertaining information window and pops it up. The complete process is illustrated in the sequence diagram in figure 3. Figure 3 – Sequence diagram for the AJAX strategy One servlet class and three custom tags have been created to support this strategy, and they must be used together in the same page. 3.3.1 HelpMessagesServiceServlet This is an extension of the HTTPSerlvet class. It serves as the RESTful web service endpoint at the server-side. It processes the HTTP request from the client-side AJAX module, constructs the message with the latest data in user’s session, and sends the response in XML format back to the browser. A sample response is listed below. Household infor Household A household includes all the persons who occupy a housing unit. 3.3.2 hohajaxtag This tag inserts AJAX methods in a JSP which will be invoked by the hohdynatag below. It has two attributes. The namespace can be used to pass a portlet’s namespace into the tag in the portal environment. In a web application the value of the attribute can be left blank. The serviceurl attribute must be the valid URL for the HelpMessagesServiceServlet. In the WebSphere Portal environment, this tag should be added in the Default.jsp file. // Portal environment // Web environment 3.3.3 hohdynatag and hohdynaparamtag The hohdynatag has four attributes as same as the “hohstatictag” tag, and it will generate a “span” element. Each hohdynaparamtag establishes a mapping between one token in the message and one key used in user’s session to refer to the actual value. These mappings will be sent to the RESTful endpoint as HTTP parameters. When a user’s mouse moves over the area in a page represented by the span tag, the following events will occur sequentially at the client’s browser: • OnMouseOver events will be fired by the browser. • The Ajax method generated by the hohajaxtag will be invoked. The method will make an HTTP request to the RESTful service endpoint and will be waiting for the response. • Upon receiving the response, the AJAX method will parse it to get the actual help message. • The AJAX method will display the message bubble in the browser. Below is a valid utilization of these tags. 4. Installation The installation procedure is fairly straight forward. After adding the jar file – MYTagLib.jar -- into the /WEB-INF/lib directory in your web project, you can use the deployment descriptor editor in RAD/RSA to complete the installation: Develop your own message loader class and add a context parameter with the name “BubbleMsgLoaderClass” and the value as the fully qualified name of your class. Figure 4 – adding your class name as a Server Context Parameter Create a listener. The class name is: com.myuan.tags.bubblemsg.serverside.CacheInitializer, and the class is shipped in the TagLib.jar file. Figure 5 – creating the listener with the shipped class Add the servlet class in the framework into the deployment descriptor in your web project. The servlet class is also shipped in the MYTagLib.jar. Figure 6 – creating a servlet with the shipped class Define the taglib element in the /WEB-INF/web.xml file. Figure 7 – adding the tag lib references Define the tag extension in your JSP pages. The and the uri directive must match. The prefix identifies the tags in the tag library within the jsp page. For example: 5 Conclusion The framework packaged in the MYTagLib.jar can enable the hover-over-help feature in a web or portal application without adding any JavaScript/CSS code into JSP pages during the development phrase. This approach can make it simpler to create and maintain these pages. The framework has been tested in web applications running on WebSphere Application Server (WAS) 6.0 and 6.1, as well as in portal applications running on WebSphere Portal 5.1 and 6.0.
October 21, 2008
by Ming Yuan
· 39,564 Views · 1 Like
article thumbnail
Adding Color and Font preferences
You had that nice looking editors and views. You loved the button color and the geeky font. But your boss didn't. Solution? Put a preference so that the user can choose which ever he likes ;-) Ok. That may not be the real rationale, but for a valid reason, you wanted to have Color and Font preferences in the PreferencePage. The obvious answer for us (the plugin develoepers) would be to add ColorFieldEditor & FontFieldEditor in our existing PreferencePage. But its not obvious for the user to look into your plugins Preference Page for changing them. Eclipse already provides a PreferencePage for these customizations: Colors and Fonts page ( General->Appearance->Colors and Fonts ) Users might be looking into this place to change the colors & fonts. As you can see in the above image it categorizes the available preferences; gives a filter to search; provides space for description and preview; and a tool tip for the current value of the preference. This is much more than the *FieldEditor right? In this tip let us see how to add our preferences into that and access them. You need to extend the org.eclipse.ui.themes extension point for adding your content into this page. I would like to provide one category with one color preference and one font preference. The extension is: An example theme category Your description goes here Description for this font Guess all the elements are self explanatory - except for the value element. For colorDefinition the value element will be the COLOR_* constants defined in the SWT class. You can specify your custom colors thru comma separated RGB values like 125,245,96. For fontDefinition it would be fontname-style-height. Now our UI will look like: To get the values stored in the preferences, you need to use the IThemeManager: IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager(); ITheme currentTheme = themeManager.getCurrentTheme(); ColorRegistry colorRegistry = currentTheme.getColorRegistry(); Color color = colorRegistry.get("com.eclipse-tips.blog.preferences.colorDefinition"); FontRegistry fontRegistry = currentTheme.getFontRegistry(); Font font = fontRegistry.get("com.eclipse-tips.blog.preferences.fontDefinition"); Once you get the current theme, you can get the preferences stored by giving the appropriate ids defined in the plugin.xml What you have seen is just the tip of the iceberg. The themes extension point has much more functionalities (The Preview is one such example). I'll explain them later, but you can see the Extension Point description here. This is an extract from http://blog.eclipse-tips.com/2008/08/adding-color-and-font-preferences.html
October 15, 2008
by Prakash
· 13,845 Views
article thumbnail
A Look Inside the JBoss Microcontainer, Part I -- Component Models
Looking at the current state of Java, we can see that POJOs (Plain Old Java Objects) rule the land yet again. Their dominance stretches from enterprise applications to middleware services. At JBoss we were known for our modular JMX-based kernel. The application server was nothing more than a bunch of flexible MBeans and a powerful MicroKernel in the middle. But, as you could feel the change is coming, we still wanted to be ahead of the pack. We could see different POJO based component models popping up all over the place (EJB3, JPA, Spring, Guice, … to name a few), yet nothing was out there that would bind them all, flattening out the differences on a single component model. Hence the Microcontainer project was born. The JBoss Microcontainer project is about many things. The Microcontainer's features range from reflection abstraction, a virtual file system, a simple state machine to transparent AOP integration, a new classloading layer, a deployment framework and an OSGi framework implementation. I'll try to address them all over a short series of articles that will be published here on DZone. This article will examine the Microcontainer's component models. Read the other parts in DZone's exclusive JBoss Microcontainer Series: Part 1 -- Component Models Part 2 –- Advanced Dependency Injection and IoC Part 3 -- the Virtual File System Part 4 -- ClassLoading Layer Part 5 - the Virtual Deployment Framework Part 6 - The Scanning Library What is a component model? What do we consider a component model? First of all, what do we consider being a component? One abstract way to express this would be that “components are reusable software programs that you can develop and assemble easily to create sophisticated applications.” To consider a bunch of components as an actual model, we also need to declare what kind of interactions we allow. JMX MBeans are one example of a component model. Their interactions include executing MBean operations, referencing attributes, setting attributes and declaring explicit dependencies between named MBeans. As mentioned, we had advanced JMX handling already with the MicroKernel. And as expected, the Microcontainer brought extensive POJO support. The default behavior and interactions in the Microcontainer are what you also normally get from any other IoC container and are similar to the functionality that MBeans provided: plain method invocations for operations, setters/getters for attributes and explicit dependencies. However, having only this functionality would mean we didn't get much further than just relieving the pain of declaring MBeans, hence it was only logical for us to do something more. I'll leave the discussion of these new IoC features for the next article in the series. There are many existing POJO component models out there, Guice and Spring being amongst the most popular. Effective integration with these frameworks was an important goal for us. Demo environment setup Before we begin, I'd like to first describe the various parts that constitute the demo. All the source code can be found at this location of our Subversion repository: • http://anonsvn.jboss.org/repos/jbossas/projects/demos/microcontainer/branches/DZone_1_0/ The project is fully mavenized, so it should be easy to adjust it to your IDE. I will first go over the sub-projects within the demo and describe their usage. At the end of my article series, I will provide a more detailed look at what certain sub-projects do. Below are the JBoss Microcontainer demos and sub-projects that are relevant for this article: • bootstrap (as the name suggests, it bootstraps the Microcontainer with demo code) • jmx (adds the JMX notion to demo's bootstrap) • models (source code of our components / services) The demo has only one variable you need to set - demos home - but even this one can be optional if you checked-out your project into the \projects\demos directory. Otherwise, you need to set the system property demos.home (e.g. -Ddemos.home=). You should now be able to run JMXMain as a main class. Make sure you include the models sub-project in the classpath, since some of the services require additional classes in the classpath, several more then what the jmx sub-project expects. Once the Microcontainer is booted it starts to scan the ${demos.home}/sandbox directory for any changes. Now all we need to do is provide a deployable unit and drop it in there. Models Let’s now turn our attention to the models sub-project. This is where the previously mentioned deployable unit should come from. You can see if everything is in place by building the models sub-project (mvn package) and dropping it into the sandbox. You should get a bunch of debug and info messages on the console log, showing how the Microcontainer got booted. Any error message indicates some problems. Let’s go over exactly what the models sub-project does, its integration code and try to redeploy it. If we look at the models src/main/resources/META-INF directory, we'll see plenty of -beans.xml resource files and one -service.xml. You’ll notice that each has a meaningful name that matches the source code package from models's src/main/java/org/jboss/demos/models directory. Let's dissect them one by one, starting with the ones that have no dependencies. org.jboss.demos.models.plain.PojoFactory This is a simple Micrcocontainer beans descriptor file. Anyone who crossed paths with some other IoC’s configuration file should be familiar with it. And, as I already mentioned, I'll follow up on more advanced usage in the next article. The next file shows what we have done to support Spring integration: Note that this file's namespace is different from the previous Microcontainer bean’s plain-beans.xml file. The urn:jboss:spring-beans:2.0 namespace points to our version of the Spring schema port, meaning you can describe your beans Spring style, but it's the Microcontainer that's going deploy then, not Spring's bean factory notion. public class Pojo extends AbstractPojo implements BeanNameAware { private String beanName; public void setBeanName(String name) { beanName = name; } public String getBeanName() { return beanName; } public void start() { if ("SpringPojo".equals(getBeanName()) == false) throw new IllegalArgumentException("Name doesn't match: " + getBeanName()); } } Although the SpringPojo bean has a dependency on Spring lib via implementing BeanNameAware interface, this dependency is only there to expose and mock some of the Spring's callback behavior (see SpringBeanAnnotationPlugin for more details). Since we introduced Spring integration, let's have a look at Guice integration. As Guice users know, Guice is all about type matching. Configuration of Guice beans is done via Modules which means that in order to generate beans, one must implement a Module. Two important parts to watch from this file are PojoModule and GuiceKernelRegistryEntryPlugin. The first one is where we configure our beans: public class PojoModule extends AbstractModule { private Controller controller; @Constructor public PojoModule(@Inject(bean = KernelConstants.KERNEL_CONTROLLER_NAME) Controller controller) { this.controller = controller; } protected void configure() { bind(Controller.class).toInstance(controller); bind(IPojo.class).to(Pojo.class).in(Scopes.SINGLETON); bind(IPojo.class).annotatedWith(FromMC.class).toProvider(GuiceIntegration.fromMicrocontainer(IPojo.class, "PlainPojo")); } } The second class provides integration with the Microcontainer: public class GuiceKernelRegistryEntryPlugin implements KernelRegistryPlugin { private Injector injector; public GuiceKernelRegistryEntryPlugin(Module... modules) { injector = Guice.createInjector(modules); } public void destroy() { injector = null; } public KernelRegistryEntry getEntry(Object name) { KernelRegistryEntry entry = null; try { if (name instanceof Class) { Class clazz = (Class)name; entry = new AbstractKernelRegistryEntry(name, injector.getInstance(clazz)); } else if (name instanceof Key) { Key key = (Key)name; entry = new AbstractKernelRegistryEntry(name, injector.getInstance(key)); } } catch (Exception ignored) { } return entry; } } Notice how we created an Injector from the Modules and then did a lookup on it for matching beans. In mbeans-service.xml we declare our legacy usage of MBeans: What’s interesting to note here is how we injected a POJO into an MBean. The preceding demonstrated our first interactions between different component models. In order to allow for MBean deployment via the Microcontainer, we had to write entirely new component model handling code. See the system-jmx-beans.xml for more details. The code from this file lives in the JBossAS source code: system-jmx sub-project. One note here, this is currently only possible with JBoss's JMX implementation, since the system-jmx code uses some implementation details. Now what if we wanted to expose our existing POJOs as MBeans, registering them into an Mbean server? @org.jboss.aop.microcontainer.aspects.jmx.JMX(exposedInterface=org.jboss.demos.models.mbeans.PojoMBean.class, registerDirectly=true) As you can see from looking at any of the beans in this file, in order to expose your POJOs as MBeans, it’s simply a matter of annotating them with an @JMX annotation. You can either expose the bean directly or its property: Here we see how you can use any of the injection lookup types by either looking up a plain POJO or getting a handle to an MBean from the MBean server. One of the injection options is to use type injection, which is also sometimes called autowiring: The FromGuice bean injects the Guice bean via type matching, where PlainPojo is injected with a common name injection. We then test if Guice binding works as expected: public class FromGuice { private IPojo plainPojo; private org.jboss.demos.models.guice.Pojo guicePojo; public FromGuice(IPojo plainPojo) { this.plainPojo = plainPojo; } public void setGuicePojo(org.jboss.demos.models.guice.Pojo guicePojo) { this.guicePojo = guicePojo; } public void start() { f (plainPojo != guicePojo.getMcPojo()) throw new IllegalArgumentException("Pojos are not the same: " + plainPojo + "!=" + guicePojo.getMcPojo()); } } This only leaves us with an alias component model. Even though the alias is quite a trivial feature, in order to implement it as a true dependency, it has to be introduced as a new component model inside the Microcontainer. The implementation details for this is part of the AbstractController source code: springPojo Here we’ve mapped the SpringPojo name to the springPojo alias. The beauty of having aliases as true component models is that it doesn't matter when the real bean gets deployed. This means that the alias will wait in a non-installed state until the real bean triggers it. Conclusion We've seen how we can deploy simple Microcontainer beans, legacy MBeans, Guice POJOs, Spring beans and aliases. And since all of this is controlled by the Microcontainer, we saw how easily we can mix and match the different component models. I can easily say, with the level of abstraction we put in our component model design, the sky is the limit on what we can handle. An example of this is the upcoming OSGi services, but that's another story, another article. Stayed tuned for my next article which will provide a detailed look at the Microcontainer's IoC functionality. About the Author Ales Justin was born in Ljubljana, Slovenia and graduated with a degree in mathematics from the University of Ljubljana. He fell in love with Java seven years ago and has spent most of his time developing information systems, ranging from customer service to energy management. He joined JBoss in 2006 to work full time on the Microcontainer project, currently serving as its lead. He also contributes to JBoss AS and is Seam and Spring integration specialist. He represent JBoss on 'JSR-291 Dynamic Component Support for Java SE' and 'OSGi' expert groups.
October 1, 2008
by Ales Justin
· 57,239 Views
article thumbnail
Using JSF and Flex Components Together
Exadel Fiji extends JavaServer Faces (JSF) by allowing the use of Flex components within a JSF page. Fiji stands for “Flex and JSF Integration.” When using Fiji components, developers use Flex with the same component-based approach to building user interfaces that they are familiar with from JSF. This means that Flex components are bound to standard JSF managed beans. Fiji is a framework that provides the following: A library of ready-to-use Flex charting components for JSF A universal wrapper that allows the use of any Flex component within a JSF page Most importantly, with Fiji, you can bind Flex components to the same JSF-managed beans properties or methods (or Seam components or Spring beans) used by the rest of your JSF application. The current version ships with the following ready-to-use charts: Column chart Stacked column chart Bar chart Stacked bar chart Line chart For example, here is a screenshot of a Flex component inside a JSF page [img_assist|nid=5013|title=|desc=|link=none|align=undefined|width=341|height=398] You can see all Fiji components in action at http://livedemo.exadel.com/fiji-demo Now that I have given you a short introduction to Fiji, you are probably wondering what problem Fiji is trying to solve. Let's see. Why Fiji? Let's start with the basics. JavaServer Faces (JSF) is a standard (Java EE) framework for building Web user interfaces out of components. Today, we are interested in building Rich Internet Applications, so RichFaces was created takes JSF a step further by allowing the easier building of AJAX-based applications in JSF. (In case you don't know, RichFaces offers a large number of ready-to-use AJAX components.) While JSF has been constantly growing, one area where it's still lacking is in displaying rich and interactive charts, graphs, and other similar visuals. Even with AJAX, any serious charting is extremely difficult, not to mention the testing that would be required for different browsers. It really comes down to two things. First, the technologies used behind JSF such as HTML, JavaScript, and CSS are not meant for displaying rich and interactive visual data (possible, but very difficult). Second, people have much higher expectations from a browser. The browser alone was never meant to display such visual data. It was primarily meant to display text and static images. So, in the end, it's not really JSF’s fault, we are simply asking the underlying technologies (HTML, JavaScript, CSS, the browser) to do too much. Of course, there is hope. We can use a Flash player to display rich and interactive charts. Adobe Flash With Flex, complex rich applications can be compiled and then run inside a Flash player. A Flash player is a virtual machine that installs as a plug-in into any browser. Because the application (built with Flex) is running inside a virtual machine, it provides a far more superior environment for rich and interactive charts and graphs than the browser alone (which just interprets HTML, JavaScript, etc.). The obvious next question is: So, why not use Flex and JSF components together right now? While it's possible to use Flex and JSF components inside the same page, the two technologies are not aware of each other. This means that JSF components are bound to JSF managed beans (or Seam components or Spring beans) while Flex is bound to completely different objects. This kind of integration is equivalent to inserting an image into a JSF page – in other words, not much integration. Back to Fiji This is a good place to revisit Fiji. Fiji is the perfect fit for helping with the above problem. Not only does Fiji provide ready-to-use chart components and a universal wrapper to use any Flex component, but, with Fiji, you can bind Flex components to standard JSF managed beans. As a JSF developer, you just use the standard and the familiar JSF component-centric approach, while now also being able to use Flex components. So, where does it make sense to use Fiji. One scenario is if you have an existing JSF application and you would like to insert richer content based on Flash while still using your existing model (JSF managed beans, Seam components or Spring beans). This content can be charts, graphs or any other rich content. Another situation where Fiji would make sense is where you have an existing JSF application, but want to use a Flash-based user interface (instead of HTML/JavaScript). By using Fiji, you can still use the existing model part of your application. However, to be honest, it wouldn't make sense to use Fiji if you have an existing Flash-only application and are using a service like GraniteDS, BlazeDS, or Exadel Flamingo. Now, I think we are ready for examples. Using Fiji There are three basic steps to get started. Download project Download JAR file and add them to project template Open the project in your favorite IDE Download Project template Download and unzip the project template. Download Fiji JAR files Go to http://exadel.com/web/portal/fiji and click on Download to download Fiji distribution Unzip the downloaded file In the next step you are going to copy JAR files from lib folder to fiji/web/WEB-INF/lib directory 1. If running Tomcat 5.5, copy all files 2. If you are running Tomcat 6, copy all files except: ¦ el-api.1.0.jar ¦ el-impl-1.0.jar Import Project Import the project into your favorite IDE. Here is how to do it in JBoss Tools (same steps for JBoss Developer Studio). Select File/Import Select Other Select JSF Project Point to the web.xml file location in the project Click Next Keep all setting as they are (I'm assuming you have a server defined) Click Finish To tell you the truth, installing Fiji is very simple. It's basically a RichFaces project (has to be RichFaces version 3.2.2 or higher) plus the JAR files for Fiji: fiji-api-1.x.x.jar fiji-ui-1.x.x.jar flamingo-service-jsf-1.6.x.jar - to use HttpService via component. Covered later in article. Besides using HttpService, if you would like to use DataServices (AMF format), you need two additional JAR files: amf-serializer-1.6.x.jar That's it. Nothing else is needed, not even changes to web.xml. Using Bar Chart Let's start with a simple example using bar chart. The first step is to create the data for the chart. Because we can easily bind charts to JSF managed beans, that's where we are going to create our data. The Java bean looks like this: public class BarChartBean { public BarChartBean() { } private Integer[] data; public Integer[] getData() { return data; } @PostConstruct public void init () { data = new Integer[5]; data[0] = 5; data[1] = 2; data[2] = -3; data[3] = 10; data[4] = 9; } } To make it a JSF managed bean we need to register it in a JSF configuration file: barChartBean fiji.BarChartBean session So far this is just basic JSF. Let's now create the page. Open start.xhtml. Look at the top, the page already contains a namespace for the Fiji tag library. Insert the following between tags: is just like a standard JSF component. The value attribute is bound to chart data inside the managed bean. sets the chart name. Save everything and run the page. You should get the following: [img_assist|nid=5014|title=|desc=|link=none|align=undefined|width=672|height=394] Let's try another example, this time using column chart. I'm sure most of you still remember the Summer Olympics, so we'll take the medal count and display it in the chart. Using the column chart You can reuse the same page or create a new page if you would like. If you create a new page, make sure to include the namespace for Fiji. We are going to take the top three countries (USA, China, and Russia) and display their gold, silver and bronze medal count. As before, let's start with data for the chart. The Java bean looks like this: public class MedalsBean { private Map medalsData = new LinkedHashMap(); private ArrayList colors = new ArrayList(); private ArrayList names = new ArrayList(); private Integer[] medalsChina = new Integer[]{51, 21, 28}; private Integer[] medalsUSA = new Integer[]{36, 38, 36}; private Integer[] medalsRussia = new Integer[]{23, 21, 28}; @PostConstruct private void init() { medalsData.put("China", medalsChina); medalsData.put("USA", medalsUSA); medalsData.put("Russia", medalsRussia); names.add("Gold"); names.add("Silver"); names.add("Bronze"); colors.add("#DAA520"); colors.add("#C0C0C0"); colors.add("#B87333"); } public Map getMedalsData() { return medalsData; } public ArrayList getColors() { return colors; } public ArrayList getNames() { return names; } public Integer[] getMedalsChina() { return medalsChina; } public Integer[] getMedalsUSA() { return medalsUSA; } public Integer[] getMedalsRussia() { return medalsRussia; } } Because we now display three bars per country (one for each medal), we use a Map object and inside it put an array of integers representing the medal count. To make it a JSF managed bean, we need to register is in a JSF configuration file: medalsBean fiji.MedalsBean request Now we are ready to build the page. The page is not much different than in the first example: Running the page will produce the following: [img_assist|nid=5015|title=fiji3|desc=|link=none|align=undefined|width=339|height=404] While the integration with JSF is neat (we can easily use JSF managed beans as a data model for Flex components), we can even take it a step further. It's possible to click on a Flex chart, send an AJAX request and do a partial page update. Let's see how it's done. Event handlers Fiji components have event handlers such as onitemclick which are very similar to the standard DHTML event handlers such as onkeyup. Going back to our example, let's say we want to click on any bar and display the medal information outside the chart. When a bar is clicked, an AJAX request will be sent to the server, properties will be set, and then rerendered. The changes to the managed bean are minimal. All we do is add three properties: private String countrySelected; private String medalTypeSelected; private String medalCountSelected; // getter and setters methods Don't forget to generate getters and setters. This is how our page now looks. We use the most popular tag from RichFaces, to attach an event (onitemclick) to the parent component, . When a bar is clicked on a chart, an Ajax request is sent to the server passing three arguments defined by the tag. The tag automatically takes the value from value attribute and assigns it to property defined in the assignTo attribute. The following three arguments are passed: event.x – is the x-axis data. In our case, it is the country name event.y – is the y-axis data. In our case, it is the medal count event.name – is the the active bar. In our case, it will be the medal type selected I have also set noEscape=”true” for each . This is necessary in order for the value to be treated as JavaScript code instead of being enclosed in single quotes and just passed to the server as a parameter. Finally, we rerender the information inside the panel grid. As you can see, we are using standard RichFaces techniques to send and rerender information even though we are mixing in Flex components. Using the universal wrapper So far I have shown you how to use charting components that ship with Fiji. Obviously you might want to use other, existing Flex components or maybe even build your own. To use any other Flex components, we use the universal wrapper or component. We will use one of the charts provided by amCharts.com. Note: We can use their charts for free. The only limitation is that a small URL will appear pointing to their Web site. I don't think it's such a limitation for such nice charts. The SWF file for the chart as well as chart data are included in the template under web/ampie directory. You can also download them from here: SWF file – ampie.swf Settings file – ampie_settings.xml Data file – ampie_data.xml The page looks like this: Using the src attribute of , we point to a Flash component. The Flash component can also be loaded as a resource by using src=“resource:///file.swf”. This particular Flash component (ampie.swf) requires some data. The data is being passed using the standard JSF attribute, . When a Flash object is rendered on a page, it has a special flashVars attribute that provides arguments to the Flash module. In our case, the tags with their information are rendered as flashVar arguments to the Flash component. This is how the charts gets its data. Running the page will produce the following: [img_assist|nid=5016|title=|desc=|link=none|align=undefined|width=539|height=384] In case you need to update the data for the chart, one possible way is to rerender the Flash component using the standard RichFaces approach. Using As a final example, I'm going to show you how to use together with . This will allow us to send a parameter from a Flash component to a JSF managed bean. Let's start with the Flash part. This is the Flex application we want to use in our JSF page: hello.mxml: It's a pretty simple MXML file which you can compile either in Flex Builder or just from the command line after installing Flex SDK >mxmlc hello.mxml I have also provided the SWF file inside the template (and here hello.swf ) in case you want to skip the compilation step. The MXML file will produce the following: [img_assist|nid=5017|title=|desc=|link=none|align=undefined|width=267|height=110] Now, let's look at the JSF page: is used to include the Flash component as we did before. The service attribute points to a JSF managed bean with a method called greeting: public Object greeting(Object value){ if(value != null){ return "What's up, "+value+"?"; } else { return "What's up, unknown?"; } } It also has to be registered in a JSF configuration file: serviceBean fiji.ServiceBean request I will cover HelloDecoder and HelloEncoder later. When running this page, we will get something very similar to the previous image; however, now it's inside a JSF page and, if we enter a value for Username and click Submit, we will get the following. [img_assist|nid=5018|title=|desc=|link=none|align=undefined|width=271|height=118] The question is, how are we able to send a request to the JSF managed bean from the Flash component? It's done via the component: We define an endpoint with the name of fiji. If you look back at the MXML file, we have the following: private function send():void { userRequest = new HTTPService(); userRequest.url = Application.application.parameters.fiji; userRequest.addEventListener("result", httpResult); var param:Object = {}; param["hello"] = username.text; userRequest.send(param); } Inside the Flex component, the HTTP URL points to Application.application.parameters.fiji which in turn points to the Fiji endpoint defined in the JSF page by tag. When the Submit button inside the Flash is clicked, the URL is resolved. This is a standard JSF request and that's how we invoke the serviceBean.greeting method inside a JSF managed bean. The URL is again passed via the flashVars attribute when the page is rendered. Finally, the initial label value is set via {Application.application.parameters.text} Its value is set via this tag: Decoders and Encoders First, why do we even need these decoders and encoders? Well, when using the Flex HttpService, the data is being sent to the server and returned in XML format. The JSF managed bean that we are using doesn't know anything about XML. It simply returns a string value. So, in order to convert the request into a format that the managed bean understands, we use a decoder. When we invoke a method, the value returned has to be encoded in order for the Flash module to understand it. I know, it sounds complicated, but it's really not. The decoder shown below will be called by Fiji and the value returned will be passed to the greeting(Object) method inside a JSF managed bean. The decoder will just pull the value from the XML sent by the request. public class HelloDecoder implements FlexDecoder , Serializable { private static final String ENDPOINT_PARAM = "hello"; public Object decodeRequest(FacesContext context, UIComponent component) { return context.getExternalContext().getRequestParameterMap().get(ENDPOINT_PARAM); } } When the greeting(Object) method inside the JSF managed bean returns a value, this encoder will be called to convert the response back to XML format. public class HelloEncoder implements FlexEncoder { private static final String VALUE = "value"; public void encodeObject(FacesContext context, UIComponent component, Object object) throws IOException { ResponseWriter responseWriter = context.getResponseWriter(); responseWriter.startElement(VALUE, component); responseWriter.writeText(object, null); responseWriter.endElement(VALUE); } } You can implement different encode and decode methods in case your Flash module requires the XML request/response to be in a specific format. Summary This article showed how you can use JSF and Flex component together while using standard JSF managed beans to provide data for the Flash components. That's what makes this framework unique. As a developer, you can continue using the standard component-centric JSF approach, but now you are able to inject even richer content using Flash. To learn more, please visit the Fiji home page: http://exadel.com/web/portal/fiji About the Author Max Katz is a Senior Systems Engineer at Exadel. He has been helping customers jump-start their RIA development as well as providing mentoring, consulting, and training. Max is a recognized subject matter expert in the JSF developer community. He has provided JSF/RichFaces training for the past three years, presented at many conferences, and written several published articles on JSF-related topics. Max also leads Exadel's RIA strategy and writes about RIA technologies in his blog, https://exadel.com/newsroom/blog/. He is an author of Practical RichFaces book (Apress). Max holds a BS in computer science from the University of California, Davis.
September 16, 2008
by Max Katz
· 114,102 Views · 1 Like
  • Previous
  • ...
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • Next
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook
×