Featured FREE Whitepapers

What's New Here?

mongodb-logo

Sorting Spring Data MongoDB collections using @OrderBy

This is already third post about tuning and enhancing Spring Data MongoDB capabilities. This time I found that I miss one JPA feature – @OrderBy annotation. @OrderBy specifies the ordering of the elements of a collection valued association at the point when the association is retrieved. In this article I will show how to implement sorting with @OrderBy annotation with Spring Data MongoDB.   Use case Just a short example of what is it all about for those who did not use JPA @OrderBy before. We’ve got here two classes and one to many relation: package pl.maciejwalkowiak.springdata.mongodb.domain;import org.bson.types.ObjectId; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document;@Document public class Backpack { @Id private ObjectId id;private List<Item> items;... }public class Item { private String name; private int price;... }Backpack is here a main class and contains list of embedded items. When Backpack is loaded from database its items are loaded in order close to insertion order. What if we want to change that and order items by one of its fields? We need to implement sorting by our own and again we will extend AbstractMongoEventListener. Sorting details: introducing @OrderBy In opposite to JPA – sorting in this case sorting cannot be done on database level. We need to take care about it on application side – that can be done in two places:before object is converted into MongoDB data structure – if we want to make sure that objects are sorted properly inside MongoDB collection after object is converted from MongoDB data structure into Java object – if we just want to make sure that inside our application List is sorted properlyIn order to specify in which place sorting should take place I have created SortPhase enumeration: public enum SortPhase { AFTER_CONVERT, BEFORE_CONVERT; }Finally – @OrderBy annotation will contain three almost self describing properties: package pl.maciejwalkowiak.springdata.mongodb;import org.springframework.data.mongodb.core.query.Order;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD }) public @interface OrderBy { /** * Field name */ String value(); Order order() default Order.ASCENDING; SortPhase[] phase() default SortPhase.AFTER_CONVERT; }Implementing SortingMongoEventListener Declarative sorting has to use reflection. To keep code readable I used commons-beanutils but it could have been done manually without using it. Add following dependencies to your project: <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.3</version> </dependency><dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency>The final part is SortingMongoEventListener implementation: package pl.maciejwalkowiak.springdata.mongodb;import com.mongodb.DBObject; import org.apache.commons.beanutils.BeanComparator; import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener; import org.springframework.data.mongodb.core.query.Order; import org.springframework.util.ClassUtils; import org.springframework.util.ReflectionUtils;import java.lang.reflect.Field; import java.util.Arrays; import java.util.Collections; import java.util.List;/** * MongoEventListener that intercepts object before its converted to BasicDBObject (before it is saved into MongoDB) * and after its loaded from MongoDB. * * @author Maciej Walkowiak */ public class SortingMongoEventListener extends AbstractMongoEventListener { @Override public void onAfterConvert(DBObject dbo, final Object source) { ReflectionUtils.doWithFields(source.getClass(), new SortingFieldCallback(source, SortPhase.AFTER_CONVERT)); }@Override public void onBeforeConvert(Object source) { ReflectionUtils.doWithFields(source.getClass(), new SortingFieldCallback(source, SortPhase.BEFORE_CONVERT)); }/** * Performs sorting with field if: * <ul> * <li>field is an instance of list</li> * <li>is annotated with OrderBy annotation</li> * <li>OrderBy annotation is set to run in same phase as SortingFieldCallback</li> * </ul> */ private static class SortingFieldCallback implements ReflectionUtils.FieldCallback { private Object source; private SortPhase phase;private SortingFieldCallback(Object source, SortPhase phase) { this.source = source; this.phase = phase; }public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException { if (field.isAnnotationPresent(OrderBy.class)) { OrderBy orderBy = field.getAnnotation(OrderBy.class);if (Arrays.asList(orderBy.phase()).contains(phase)) { ReflectionUtils.makeAccessible(field); Object fieldValue = field.get(source);sort(fieldValue, orderBy); } } }private void sort(Object fieldValue, OrderBy orderBy) { if (ClassUtils.isAssignable(List.class, fieldValue.getClass())) { final List list = (List) fieldValue;if (orderBy.order() == Order.ASCENDING) { Collections.sort(list, new BeanComparator(orderBy.value())); } else { Collections.sort(list, new BeanComparator(orderBy.value(), Collections.reverseOrder())); } }} } }In order to use it you just need to declare this class as a Spring bean in application context: <bean class="pl.maciejwalkowiak.springdata.mongodb.SortingMongoEventListener" />Example Now its time to add created OrderBy annotation to Backpack class from beginning of this post. Lets say we want to order items by price in descending order: @Document public class Backpack { @Id private ObjectId id;@OrderBy(value = "price", order = Order.DESCENDING) private List<Item> items;... }Thats it. Now every time you load Backpack objects – does not matter if its findAll, findOne or your custom method – items in backpack will be ordered.   Summary SortingMongoEventListener is another example how Spring Data MongoDB event system is powerful. You are welcome to comment and let me know if you think this feature could be a part of Spring Data MongoDB. Reference: Sorting Spring Data MongoDB collections using @OrderBy from our JCG partner Maciej Walkowiak at the Software Development Journey blog....
jaspersoft-jasperreports-logo

JasperReports JSF Plugin Use Cases – Simple List Report

This is the first “use case article” of the JasperReports JSF Plugin Series and I will focus on a simple requirement and I will get deeper in further ones. The starting point is the project setup that we have already done for our book store and I will add to it a list with the different books registered in our database and that list will be available as a report as well. Our application will offer with following features when showing reports to the user:User will be able to select the output format of the report. The report view will be localizable and will be output in the same locale that the user of the application has.Initial Setup To avoid creating all the CRUD functionally I will initialize the table that will contain the values to be shown using a SQL script for the sake of simplicity. Just a few records should be enough to the purpose of this article and thus, I will use following script to feed the book table: insert into book(title, author, published_year, genre, price) values('The Futurogical Congress', 'Stanislaw Lem', '1978', 'SciFi', 2.5); insert into book(title, author, published_year, genre, price) values('Brave New World', 'H. G. Wells', '1975', 'SciFi', 3.99); insert into book(title, author, published_year, genre, price) values('Treasure Island', 'Robert Lewis Stevenson', '1948', 'Adventures', 4.45); insert into book(title, author, published_year, genre, price) values('The Lord of the Rings', 'J. R. Tolkien', '1945', 'Fantasy', 12.23); insert into book(title, author, published_year, genre, price) values('In Cold Blood', 'Truman Capote', '1966', 'Nonfiction', 9.50);I will create a resource bundle that will hold the localised texts for the view and the report. The name of the file will be Messages.properties and I will add it to the package net.sf.jasperreports.jsf.sample.usecases under the resources root folder. File contents will be as follows: report.format.select=Select report formatbookList.pageTitle=Browsing Books bookList.id=Reference ID bookList.title=Title bookList.author=Author bookList.genre=Genre bookList.year=Year bookList.price=PriceI added another file like the previous one but named Messages_es.properties and holding the Spanish translation, you can add your additional preferred languages if interested in support more than one. Previous resource file must be configured in our faces-config.xml file: <faces-config ...> <application> <locale-config> <default-locale>en</default-locale> <supported-locale>es</supported-locale> </locale-config> <resource-bundle> <var>Messages</var> <base-name>net.sf.jasperreports.jsf.sample.usecases.Messages</base-name> </resource-bundle> </application> </faces-config>Since I’m using Maven I will configure a folder inside my project structure to hold the reports’ .jrxml files and configure my POM to run the JasperReports compiler against that folder. The folder name I chose is src/main/jasperreports and the POM configuration for the JasperReports Maven Plugin is as follows: <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jasperreports-maven-plugin</artifactId> <version>1.0-beta-2</version> <executions> <execution> <goals> <goal>compile-reports</goal> </goals> </execution> </executions> <configuration> <outputDirectory>target/jasperreports/jasper</outputDirectory> </configuration> <dependencies> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>4.5.1</version> </dependency> </dependencies> </plugin>I will also add some extra configuration to the Maven WAR Plugin so it can collect all the .jasper files generated by the JasperReports compiler and pack them inside the application WAR file: <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <webResources> <resource> <directory>src/main/jasperreports</directory> <includes> <include>**/*.jrxml</include> </includes> <targetPath>resources/reports/sources</targetPath> </resource> <resource> <directory>target/jasperreports/jasper</directory> <includes> <include>**/*.jasper</include> </includes> <targetPath>resources/reports/jasper</targetPath> </resource> </webResources> </configuration> </plugin>As you may notice, I’m packaging the JasperReports’ .jrxml files inside the web application archive. When using the plugin we can reference either as the report template resource, the plugin engine is smart enough to recognise the type of file referenced and when using a reference to a report source file the plugin will compile the report on the fly. However, the preferred approach should be always to use a .jasper file as it has better performance than the other one.   Design the Report Template As stated in the intro to this series, the visual design tool for JasperReports I will be using is iReport, there are a lot of tutorials out there about how to use iReport so I will skip that part. However, since I want to design a locale-aware report I must pay attention to the I18n Sample provided at JasperReports’ web site. So, we start iReport and select a blank report template. Since our report will use a SQL based data source, once the visual designer has finished loading we must configure the SQL sentence that will grab the data from the database. To do that we must click on the button at the left of the zoom options in the designer view and select the “Report query” tab:The SQL query I will use to grab the data is the most simple one we can do. After inputting that SQL sentence iReport will show us all the available fields in the lower part of the window. If it could load all the fields without any errors then click the OK button to save them to report: select * from book;All the text that will be outputted in my final report will come from either a resource bundle or the database itself. So, as the JasperReports i18n sample points out, we should use text fields wherever we want to output some text. The report design view will look something like following picture:The XML view of the report template file will be something like the following: <?xml version="1.0" encoding="UTF-8"?> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="booklist" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20"> <property name="ireport.zoom" value="1.5"/> <property name="ireport.x" value="0"/> <property name="ireport.y" value="0"/> <queryString> <![CDATA[select * from book]]> </queryString> <field name="BOOK_ID" class="java.lang.Integer"/> <field name="TITLE" class="java.lang.String"/> <field name="AUTHOR" class="java.lang.String"/> <field name="PUBLISHED_YEAR" class="java.lang.String"/> <field name="GENRE" class="java.lang.String"/> <field name="PRICE" class="java.math.BigDecimal"/> <background> <band splitType="Stretch"/> </background> <title> <band height="38" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="227" height="29"/> <textElement> <font size="18" isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.pageTitle}]]></textFieldExpression> </textField> </band> </title> <columnHeader> <band height="27" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="100" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.id}]]></textFieldExpression> </textField> <textField> <reportElement x="113" y="2" width="155" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.title}]]></textFieldExpression> </textField> <textField> <reportElement x="285" y="2" width="100" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.author}]]></textFieldExpression> </textField> <textField> <reportElement x="398" y="2" width="100" height="20"/> <textElement> <font isBold="true"/> </textElement> <textFieldExpression><![CDATA[$R{bookList.year}]]></textFieldExpression> </textField> </band> </columnHeader> <detail> <band height="21" splitType="Stretch"> <textField> <reportElement x="0" y="0" width="100" height="20"/> <textElement/> <textFieldExpression class="java.lang.Integer"><![CDATA[$F{BOOK_ID}]]></textFieldExpression> </textField> <textField> <reportElement x="113" y="0" width="155" height="20"/> <textElement/> <textFieldExpression><![CDATA[$F{TITLE}]]></textFieldExpression> </textField> <textField> <reportElement x="285" y="0" width="100" height="20"/> <textElement/> <textFieldExpression><![CDATA[$F{AUTHOR}]]></textFieldExpression> </textField> <textField> <reportElement x="398" y="0" width="112" height="20"/> <textElement/> <textFieldExpression><![CDATA[$F{PUBLISHED_YEAR}]]></textFieldExpression> </textField> </band> </detail> <columnFooter> <band height="45" splitType="Stretch"/> </columnFooter> <pageFooter> <band height="25" splitType="Stretch"> <textField> <reportElement x="227" y="0" width="100" height="20"/> <textElement textAlignment="Center"/> <textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression> </textField> </band> </pageFooter> <summary> <band height="42" splitType="Stretch"/> </summary> </jasperReport>Save this file inside the src/main/jasperreports folder created earlier and you are ready for the next section. Design the JSF View Our JSF View will based in Facelets, so it will be written as a XHTML file in which we need to declare the different library namespaces that we will be using. For instructions how to setup Facelets go straight to its documentation (JSF 2.x applications support Facelets out-of-the-box without additional configuration). The following snippet shows the contents of the Facelets’ template I will use to render the user interface for the book list. Copy it and save it in a file inside your web application content files. The file name I will use is /book/bookList.xhtml: <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:jr="http://jasperreportjsf.sf.net/tld/jasperreports-jsf-1_3.tld"> <head> <title>Book List - JasperReports JSF Use Cases</title> </head> <body> <h1><h:outputText value="#{Messages['bookList.pageTitle']}"/></h1><div> <h:form id="bookListForm"> <jr:source id="bookSource" type="jndi" value="java:comp/env/jdbc/BookStoreDB"/><h:panelGrid columns="3"> <h:outputLabel for="reportFormat" value="#{Messages['report.format.select']}" /> <h:selectOneMenu id="reportFormat" value="#{bookList.reportFormat}" onchange="document.bookListForm.submit();"> <f:selectItems value="#{bookList.reportFormats}" /> </h:selectOneMenu> <jr:reportLink id="reportLink" format="#{bookList.reportFormat}" target="blank" source="bookSource" value="/resources/reports/jasper/booklist.jasper" resourceBundle="#{Messages}"> <h:outputText value="#{Messages['bookList.action.show']}"/> </jr:reportLink> </h:panelGrid><h:dataTable value="#{bookList.allBooks}" var="book"> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.title']}"/> </f:facet> <h:outputText value="#{book.title}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.author']}"/> </f:facet> <h:outputText value="#{book.author}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.year']}"/> </f:facet> <h:outputText value="#{book.publishedYear}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="#{Messages['bookList.genre']}"/> </f:facet> <h:outputText value="#{book.genre}"/> </h:column> </h:dataTable> </h:form> </div> </body> </html>The highlighted lines are where we are adding the JasperReports JSF Plugin components:First of all, at line 14, we are defining a Report Source Component by means of the <jr:source> tag. This component will not output any data to the rendered HTML but can be referenced by the visual components of the library as way of telling them how to obtain the data they need to render the report contents. From line 21 to 26 we are defining a Report Link Component by means of the <jr:reportLink> tag. This component will output a standard a HTML element pointing to a special URL generated by the plugin’s engine. When clicked on it the plugin’s engine will intercept that URL and replace some of the JSF life-cycle phases to process the report data and generate a result. Notice that the report component has an attribute resourceBundle pointing to the messages bundle we have created in the first section.Note: The resourceBundle attribute has made available in the trunk version (at the moment of writing this lines) of JasperReports JSF Plugin, which uses the 1.3 version of the tag library. For users that are still using the 1.2 version of the tag library they can get a similar result adding a parameter to the report link: <jr:reportLink id="reportLink" format="#{bookList.reportFormat}" target="blank" source="bookSource" value="/resources/reports/jasper/booklist.jasper"> <f:param name="RESOURCE_BUNDLE" value="#{Messages}" /> <h:outputText value="#{Messages['bookList.action.show']}"/> </jr:reportLink>Apart from the highlighted lines, I added code to render a combo box with all the export options supported by JasperReports JSF Plugin and a data table that will layout the different records for the table books. Note: The combo box contains an onchange attribute intended to submit the form with the new value for the report export option. I must done it that way to get the report link properly working in JSF prior to version 2.x as that versions do not have any AJAX support. The JSF view shown above needs a managed bean to work, that managed bean will be providing the values to the user interface: public class BookListView {private BookManager bookManager;private List allBooks;private String reportFormat = &quot;pdf&quot;;public void setBookManager(BookManager bookManager) { this.bookManager = bookManager; }public List getAllBooks() { if (allBooks == null) { allBooks = bookManager.getAllBooks(); } return allBooks; }public String getReportFormat() { return reportFormat; }public void setReportFormat(String reportFormat) { this.reportFormat = reportFormat; }public List getReportFormats() { FacesContext context = FacesContext.getCurrentInstance(); JRFacesContext jrContext = JRFacesContext.getInstance(context); List list = new ArrayList(); for (String format : jrContext.getAvailableExportFormats()) { list.add(new SelectItem(format, format)); } return list; }}The bookManager field is a reference to an interface that will provide with the logic to fetch all the books from the database: public interface BookManager { public List getAllBooks(); }As said in the introduction article to this series, I will not get into the details of additional classes or interfaces needed to implement the use case as it’s up each specific user to decide what framework will be providing the skeleton of the application.   Testing All Together It’s time to check that everything works as it should. So, let’s package our web application, deploy it on our Tomcat server and enter the following URL into your preferred browser: http://localhost:8080/jrjsf-usecases/book/bookList.jsf. Note: The Derby (database) and Tomcat (app server) must be running before performing the deploy operation. So, this is how it should look when our browser outputs the contents of the previous mentioned URL:Now, click on the “Show Report” link to see the outputs of the report filled with the strings from our resource bundle and the data from the database:That is a sample screenshot taken from the PDF view of the report. Use the combo box in the user interface to change the report export format. Conclusion So, all done, this is the simplest way of adding a report to our JavaServer Faces application. I started with a simple sample and I will be adding more complex features to it from time to time. Hope you enjoyed this article and come back for the future publications, the good stuff is yet to come! Reference: JasperReports JSF Plugin Use Cases – Simple List Report from our JCG partner Alonso Dominguez at the Code Nibbles blog....
zk-logo

ZK in Action: MVVM – Form Binding

This is the second episode in our efforts to build a ZK application from the ground up. The previous post dealt with loading and rendering of data into a table using MVVM. In this post, we’ll be introduced to ZK MVVM’s form binding. Objective We’ll build an “Add” function that would enable us to save new entries to the inventory.A Form Appears When “Add” is ClickedNew Entry is Added When “Save” is ClickedZK Features in Action  MVVM : Save, Form Binding, Conditional BindingAdd New Entries with MVVM Form Binding we’ll need to implement these parts:Enhance our ViewModel POJO Add UI markup to present a form and decorate the markup with the appropriate annotationsThe ViewModel Class public class InventoryVM {private List<item> items; private Item newItem; @NotifyChange("newItem") @Command public void createNewItem(){ newItem = new Item("", "",0, 0,new Date()); } @NotifyChange({"newItem","items"}) @Command public void saveItem() throws Exception{ DataService.getInstance().saveItem(newItem); newItem = null; items = getItems(); } @NotifyChange("newItem") @Command public void cancelSave() throws Exception{ newItem = null; } public List<item> getItems() throws Exception{ items = DataService.getInstance().getAllItems(); return items; } }Line 4, we declare an Item object named newItem which will reference the Item instance to be saved to the database. Line 6, @NotifyChange informs the binder to update the UI on the state of the associated ViewModel’s property. In our UI markup shown below, at line 8, we have a Groupbox annotated with visible=”@load(not empty vm.newItem), hence the Groupbox will become visible once createNewItem assigns an instance of Item to newItem. Simply put, @NotifyChange refreshes the UI with respect to the updates on ViewModel’s properties. Line 7, we annotate the createNewItem method with @Command and in our UI markup shown below, at line 4, we have a Toolbarbutton with onClick=”@commnad(createNewItem)”. So when the Toolbarbutton is clicked, the createNewItem method will be invoked. Similarly, from line 12 to 18, we have a saveItem method which is called when its corresponding onClick event is triggered. Once the new Item object is saved to the database cache, we reset the newItem to null and retrieve the new list of items. The changes made to the ViewModel properties newItem (now null again) and items (now with an extra entry) are reflected to the UI using @NotifyChange as before. The Markup <window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('lab.sphota.zk.ctrl.InventoryVM')"> <toolbar> <toolbarbutton label="Add" onClick="@command('createNewItem')" /> </toolbar> <groupbox form="@id('itm') @load(vm.newItem) @save(vm.newItem, before='saveItem')" visible="@load(not empty vm.newItem)"> <caption label="New Item"></caption> <grid width="50%"> <rows> <row> <label value="Item Name" width="100px"></label> <textbox id="name" value="@bind(itm.name)" /> </row> <row> <label value="Model" width="100px"></label> <textbox value="@bind(itm.model)" /> </row> <row> <label value="Unit Price" width="100px"></label> <decimalbox value="@bind(itm.price)" format="#,###.00" constraint="no empty, no negative" /> </row> <row> <label value="Quantity" width="100px"></label> <spinner value="@bind(itm.qty)" constraint="no empty,min 0 max 999: Quantity Must be Greater Than Zero" /> </row> <row> <cell colspan="2" align="center"> <button width="80px" label="Save" onClick="@command('saveItem')" mold="trendy" /> <button width="80px" label="Cancel" onClick="@command('cancelSave')" mold="trendy" /> </cell> </row> </rows> </grid> </groupbox> <listbox> ... </listbox> </window>Line 1, we apply ZK’s default implementation of its BindComposer. It is responsible for instantiating our ViewModel and Binder instances. Line 2, we supply the full class name of the ViewModel we wish to instantiate and give it an ID for future reference Line 4, we assign our ViewModel’s “command method” createNewItem as the onClick event handler for the toolbar button. Line 6, the property newItem in ViewModel is made referenceable throughout the Groupbox using the ID “itm”. Line 6,7, by using form binding, to avoid invalid or incomplete data saved to the ViewModel property, entries in the form are saved to a temporary object until the command method saveItem is called. Line 8, we show the Groupbox to enter a new Item entry only user has clicked the “Add” button; which in turn invokes createNewItem method and assigns the VM property newItem an instance of Item with default value(empty strings and 0s). Line 14, 18, 22, 27, we bind the Item properties with the input elements. @bind is effectively equivalent to @load plus @save.In a Nuteshell To sum up in point form:Using form binding avoids directly modifying data in ViewModel properties by saving form entries to a temporary object. Data is written to the ViewModel properties only if the condition specified is satisfied; in our example, only if the saveItem method is invoked. @Command annotation allows the binder to map UI event handlers to ViewModel command methods. @NotifyChange informs the binder which ViewModel properties had been modified after the command method is executed so changes in data can then be reflected on the UI. We can assign values to any of UI components’ attributes at run-time via MVVM binding to manipulate parameters such as visibility, style, disable/enable, etc.In this post, we’ve not seen how data entries are validated. Before that, we’ll implement the delete and edit functionalities in the next post. Reference ZK Developer Reference Reference: ZK in Action [1] : MVVM – Form Binding from our JCG partner Lance Lu at the Tech Dojo blog....
enterprise-java-logo

Three steps to follow MVC while building Java Web application

Step #1 DO Always process URL(POST forms, link clicking etc) by servlet / action bean and never by JSPWHY ActionBeans (whatever certain framework call those classes) and rarely servlets are controllers intended for processing user input. JSPs are view engine dedicated to rendering representation of software to client. Separating user input processing and HTML rendering prevents you from temptation of creating huge, multi-purpose, untestable JSPs that are mixing business and representation logic and violating MVC pattern.Step #2 DO Render views by forwarding to JSP located only under /WEB-INF/{JSP folder}WHY Views should be accessible only by design of software and never directly. Putting JSPs within root directory of project brings security issues regarding unwanted access to them from clients.Also practice of hiding all JSPs under /WEB-INF reduces possibility of URL being processed by JSP and not controller and help us to follow step #1.Step #3 DO Pass model from controller to view only by using request attributes or flash scopeWHY All other ways of view being able to access some data are too limited or insecure. Using request parameters directly within view can be the option for malicious user to pass invalid data. Using session for storing information is causing memory consumption and requires mechanisms to clear unused data after expiration. Cookies depends on browser, limited in size and not very friendly to use. From the other hand – request attributes lacks all those drawback and propose clean decoupling of controller responsibility (update model) and view responsibility (read model). Flash scope becomes very handy when it comes to Redirect After Post pattern where request attributes can’t be used.PS: all modern action-based frameworks are using steps described below to achieve their goals. But if you using some old fashioned code or don’t use any framework at all – you still can achieve good clean and easy to use MVC.Reference: Three steps to follow MVC while building Java Web application from our JCG partner Evgeny Shepelyuk at the jk’s blog blog....
zk-logo

ZK in Action: MVVM – Update View Programmatically

In the previous 2 posts we’ve used ZK’s MVVM functionalities to:load data into a table save data with form bindingWe’ve seen when a method is decorated with the annotation @NotifyChange( ) , upon its execution completes, the Binder would be informed of the VM property’s changes so that Binder can update the corresponding UI accordingly. In this post, whilst we implement the functionality of item deletion in our inventory, we’ll see how we can update UI components programmatically at runtime. Objective Build a delete function to our simple inventory CRUD feature.ZK Feature in ActionMVVM : BindUtilsImplement Deletion with MVVM BindUtilsWe will:Add markup for the delete button and assign it an onClick event handler Implement command method ‘deleteItem()‘ in VMThe Markup <window apply='org.zkoss.bind.BindComposer' viewModel='@id('vm') @init('...InventoryVM')'> <toolbar width='100%'> <toolbarbutton label='Add' onClick='@command('createNewItem')' /> <toolbarbutton label='Delete' onClick='@command('deleteItem')' disabled='@load(empty vm.selected)'/> </toolbar>line 5, assign a command method ‘deleteItem‘ to the delete button’s onClick handler line 5, ‘disabled=’@(empty vm.selected)’‘ ensures that the delete button is functional only if an entry in the table has been selectedThe ViewModel Class public class InventoryVM {private Item selected; private List<Item> items; ...@Command public void deleteItem() throws Exception{ if (selected != null){ String str = 'The item with name \'' +selected.getName() +'\' and model \'' +selected.getModel() +'\' will be deleted.';Messagebox.show(str,'Confirm Deletion', Messagebox.OK|Messagebox.CANCEL, Messagebox.QUESTION, new EventListener<event>(){ @Override public void onEvent(Event event) throws Exception { if (event.getName().equals('onOK')){ DataService.getInstance().deleteItem(selected); items = getItems(); BindUtils.postNotifyChange(null, null, InventoryVM.this, 'items'); }); } ... } ... }line 7, we decorate our deleteItem method with @Command so it can be wired as the onClick event handler in our added markup: <toolbarbutton label=’Delete’ onClick=’@command(‘deleteItem’)’ />; line 9, we go ahead with the deletion process only if an item is selected. line 16, we show a Messagebox which prompts the user to confirm the deletion of the selected item. line 20, if user clicks ‘OK’, our program proceeds to delete the selected item. line 23, we call BindUtils.postNotifyChange(String queueName, String queueScope, Object bean, String property) to update our inventory table. By giving the parameter queueScope a null value, the default desktop queue scope is used. The third and forth argument are given as such since we want to notify the Binder that property ‘items’ in our InventoryVM instance has changed. The Binder would then update the UI (remove the item entry in the inventory table).Wrap Up The @NotifyChange annotation lets us update the UI through ZK MVVM’s Binder to reflect changes made to the ViewModel properties. The notification is fired when the annotated method finishes executing. In our implementation, we attached an anonymous event listener class to a Messagebox. In this case, after deleteItem is executed, the annotation @NotifyChange(‘items’) would falsely alert the Binder before the event handling is completed. A programmatic way to reflect state changes in ViewModel to the UI resolves this particular problem conveniently. Next up, editing the entries with MVVM. Reference: ZK in Action [2] : MVVM – Update View Programmatically from our JCG partner Lance Lu at the Tech Dojo blog....
java-logo

java.lang.NoClassDefFoundError: How to resolve – Part 3

This article is part 3 of our NoClassDefFoundError troubleshooting series. As I mentioned in my first article, there are many possible issues that can lead to a NoClassDefFoundError. This article will focus and describe one of the most common causes of this problem: failure of a Java class static initializer block or variable. A sample Java program will be provided and I encourage you to compile and run this example from your workstation in order to properly replicate and understand this type of NoClassDefFoundError problem. Java static initializer revisited The Java programming language provides you with the capability to “statically” initialize variables or a block of code. This is achieved via the “static” variable identifier or the usage of a static {} block at the header of a Java class. Static initializers are guaranteed to be executed only once in the JVM life cycle and are Thread safe by design which make their usage quite appealing for static data initialization such as internal object caches, loggers etc. What is the problem? I will repeat again, static initializers are guaranteed to be executed only once in the JVM life cycle…This means that such code is executed at the Class loading time and never executed again until you restart your JVM. Now what happens if the code executed at that time (@Class loading time) terminates with an unhandled Exception? Welcome to the java.lang.NoClassDefFoundError problem case #2! NoClassDefFoundError problem case 2 – static initializer failure This type of problem is occurring following the failure of static initializer code combined with successive attempts to create a new instance of the affected (non-loaded) class. Sample Java program The following simple Java program is split as per below: – The main Java program NoClassDefFoundErrorSimulator – The affected Java class ClassA – ClassA provides you with a ON/OFF switch allowing you the replicate the type of problem that you want to study This program is simply attempting to create a new instance of ClassA 3 times (one after each other) . It will demonstrate that an initial failure of either a static variable or static block initializer combined with successive attempt to create a new instance of the affected class triggers java.lang.NoClassDefFoundError. #### NoClassDefFoundErrorSimulator.java package org.ph.javaee.tools.jdk7.training2;/** * NoClassDefFoundErrorSimulator * @author Pierre-Hugues Charbonneau * */ public class NoClassDefFoundErrorSimulator { /** * @param args */ public static void main(String[] args) { System.out.println("java.lang.NoClassDefFoundError Simulator - Training 2"); System.out.println("Author: Pierre-Hugues Charbonneau"); System.out.println("http://javaeesupportpatterns.blogspot.com\n\n"); try { // Create a new instance of ClassA (attempt #1) System.out.println("FIRST attempt to create a new instance of ClassA...\n"); ClassA classA = new ClassA(); } catch (Throwable any) { any.printStackTrace(); } try { // Create a new instance of ClassA (attempt #2) System.out.println("\nSECOND attempt to create a new instance of ClassA...\n"); ClassA classA = new ClassA(); } catch (Throwable any) { any.printStackTrace(); } try { // Create a new instance of ClassA (attempt #3) System.out.println("\nTHIRD attempt to create a new instance of ClassA...\n"); ClassA classA = new ClassA(); } catch (Throwable any) { any.printStackTrace(); } System.out.println("\n\ndone!"); } }#### ClassA.java package org.ph.javaee.tools.jdk7.training2;/** * ClassA * @author Pierre-Hugues Charbonneau * */ public class ClassA { private final static String CLAZZ = ClassA.class.getName(); // Problem replication switch ON/OFF private final static boolean REPLICATE_PROBLEM1 = true; // static variable initializer private final static boolean REPLICATE_PROBLEM2 = false; // static block{} initializer // Static variable executed at Class loading time private static String staticVariable = initStaticVariable(); // Static initializer block executed at Class loading time static { // Static block code execution... if (REPLICATE_PROBLEM2) throw new IllegalStateException("ClassA.static{}: Internal Error!"); } public ClassA() { System.out.println("Creating a new instance of "+ClassA.class.getName()+"..."); } /** * * @return */ private static String initStaticVariable() { String stringData = ""; if (REPLICATE_PROBLEM1) throw new IllegalStateException("ClassA.initStaticVariable(): Internal Error!"); return stringData; } }Problem reproduction In order to replicate the problem, we will simply “voluntary” trigger a failure of the static initializer code . Please simply enable the problem type that you want to study e.g. either static variable or static block initializer failure: // Problem replication switch ON (true) / OFF (false) private final static boolean REPLICATE_PROBLEM1 = true; // static variable initializer private final static boolean REPLICATE_PROBLEM2 = false; // static block{} initializerNow, let’s run the program with both switch at OFF (both boolean values at false) ## Baseline (normal execution) java.lang.NoClassDefFoundError Simulator - Training 2 Author: Pierre-Hugues Charbonneauhttp://javaeesupportpatterns.blogspot.comFIRST attempt to create a new instance of ClassA... Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA... SECOND attempt to create a new instance of ClassA... Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA... THIRD attempt to create a new instance of ClassA... Creating a new instance of org.ph.javaee.tools.jdk7.training2.ClassA... done! For the initial run (baseline), the main program was able to create 3 instances of ClassA successfully with no problem. ## Problem reproduction run (static variable initializer failure) java.lang.NoClassDefFoundError Simulator - Training 2 Author: Pierre-Hugues Charbonneauhttp://javaeesupportpatterns.blogspot.comFIRST attempt to create a new instance of ClassA... java.lang.ExceptionInInitializerError at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:21 ) Caused by: java.lang.IllegalStateException : ClassA.initStaticVariable(): Internal Error! at org.ph.javaee.tools.jdk7.training2.ClassA.initStaticVariable( ClassA.java:37 ) at org.ph.javaee.tools.jdk7.training2.ClassA.<clinit>( ClassA.java:16 ) ... 1 more SECOND attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:30 ) THIRD attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:39> ) done! ## Problem reproduction run (static block initializer failure) java.lang.NoClassDefFoundError Simulator - Training 2 Author: Pierre-Hugues Charbonneauhttp://javaeesupportpatterns.blogspot.comFIRST attempt to create a new instance of ClassA... java.lang.ExceptionInInitializerError at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:21 ) Caused by: java.lang.IllegalStateException> : ClassA.static{}: Internal Error! at org.ph.javaee.tools.jdk7.training2.ClassA.<clinit>( ClassA.java:22 ) ... 1 more SECOND attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:30 ) THIRD attempt to create a new instance of ClassA... java.lang.NoClassDefFoundError: Could not initialize class org.ph.javaee.tools.jdk7.training2.ClassA at org.ph.javaee.tools.jdk7.training2.NoClassDefFoundErrorSimulator.main( NoClassDefFoundErrorSimulator.java:39 ) done! What happened? As you can see, the first attempt to create a new instance of ClassA did trigger a java.lang.ExceptionInInitializerError . This exception indicates the failure of our static initializer for our static variable & bloc which is exactly what we wanted to achieve. The key point to understand at this point is that this failure did prevent the whole class loading of ClassA . As you can see, attempt #2 and attempt #3 both generated a java.lang.NoClassDefFoundError, why? Well since the first attempt failed, class loading of ClassA was prevented. Successive attempts to create a new instance of ClassA within the current ClassLoader did generate java.lang.NoClassDefFoundError over and over since ClassA was not found within current ClassLoader. As you can see, in this problem context, the NoClassDefFoundError is just a symptom or consequence of another problem. The original problem is the ExceptionInInitializerError triggered following the failure of the static initializer code. This clearly demonstrates the importance of proper error handling and logging when using Java static initializers. Recommendations and resolution strategies Now find below my recommendations and resolution strategies for NoClassDefFoundError problem case 2: – Review the java.lang.NoClassDefFoundError error and identify the missing Java class – Perform a code walkthrough of the affected class and determine if it contains static initializer code (variables & static block) – Review your server and application logs and determine if any error (e.g. ExceptionInInitializerError) originates from the static initializer code – Once confirmed, analyze the code further and determine the root cause of the initializer code failure. You may need to add some extra logging along with proper error handling to prevent and better handle future failures of your static initializer code going forward Please feel free to post any question or comment. The part 4 will start coverage of NoClassDefFoundError problems related to class loader problems. Reference: java.lang.NoClassDefFoundError: How to resolve – Part 3 from our JCG partner Pierre-Hugues Charbonneau at the Java EE Support Patterns & Java Tutorial blog....
apache-activemq-logo

JMS with ActiveMQ

JMS with ActiveMQ  JMS short for Java Message Service provides a mechanism for integrating applications in a loosely coupled, flexible manner. JMS delivers data asynchronously across applications on a store and forward basis. Applications communicate through MOM(Message Oriented Middleware) which acts as an intermediary without communicating directly. JMS Architecture Main components of JMS are:JMS Provider: A messaging system that implements the JMS interfaces and provides administrative and control features Clients: Java applications that send or receive JMS messages. A message sender is called the Producer, and the recipient is called a Consumer Messages: Objects that communicate information between JMS clients Administered objects: Preconfigured JMS objects created by an administrator for the use of clients.There are several JMS providers available like Apache ActiveMQ and OpenMQ. Here I have used Apache ActiveMQ. Installing and starting Apache ActiveMQ on windowsDownload ActiveMQ windows binary distribution Extract the it to a desired location Using the command prompt change the directory to the bin folder inside ActiveMQ installation folder and run the following command to start ActiveMQ activemqAfter starting ActiveMQ you can visit the admin console using http://localhost:8161/admin/ and do the administrative tasks JMS Messaging Models JMS has two messaging models, point to point messaging model and publisher subscriber messaging model. Point to point messaging model Producer sends the message to a specified queue within JMS provider and the only one of the consumers who listening to that queue receives that message.Example 1 and example 2 are almost similar the only difference is example 1 creates queues within the program and the example 2 uses jndi.properties file for naming look ups and creating queues. Example 1 package com.eviac.blog.jms;import javax.jms.*; import javax.naming.InitialContext; import javax.naming.NamingException;import org.apache.log4j.BasicConfigurator;public class Producer {public Producer() throws JMSException, NamingException {// Obtain a JNDI connection InitialContext jndi = new InitialContext();// Look up a JMS connection factory ConnectionFactory conFactory = (ConnectionFactory) jndi .lookup('connectionFactory'); Connection connection;// Getting JMS connection from the server and starting it connection = conFactory.createConnection(); try { connection.start();// JMS messages are sent and received using a Session. We will // create here a non-transactional session object. If you want // to use transactions you should set the first parameter to 'true' Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);Destination destination = (Destination) jndi.lookup('MyQueue');// MessageProducer is used for sending messages (as opposed // to MessageConsumer which is used for receiving them) MessageProducer producer = session.createProducer(destination);// We will send a small text message saying 'Hello World!' TextMessage message = session.createTextMessage('Hello World!');// Here we are sending the message! producer.send(message); System.out.println('Sent message '' + message.getText() + '''); } finally { connection.close(); } }public static void main(String[] args) throws JMSException { try { BasicConfigurator.configure(); new Producer(); } catch (NamingException e) { e.printStackTrace(); }} }package com.eviac.blog.jms;import javax.jms.*;import org.apache.activemq.ActiveMQConnection; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.log4j.BasicConfigurator;public class Consumer { // URL of the JMS server private static String url = ActiveMQConnection.DEFAULT_BROKER_URL;// Name of the queue we will receive messages from private static String subject = 'MYQUEUE';public static void main(String[] args) throws JMSException { BasicConfigurator.configure(); // Getting JMS connection from the server ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url); Connection connection = connectionFactory.createConnection(); connection.start();// Creating session for seding messages Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// Getting the queue Destination destination = session.createQueue(subject);// MessageConsumer is used for receiving (consuming) messages MessageConsumer consumer = session.createConsumer(destination);// Here we receive the message. // By default this call is blocking, which means it will wait // for a message to arrive on the queue. Message message = consumer.receive();// There are many types of Message and TextMessage // is just one of them. Producer sent us a TextMessage // so we must cast to it to get access to its .getText() // method. if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; System.out.println('Received message '' + textMessage.getText() + '''); } connection.close(); } }jndi.properties # START SNIPPET: jndijava.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory# use the following property to configure the default connector java.naming.provider.url = vm://localhost# use the following property to specify the JNDI name the connection factory # should appear as. #connectionFactoryNames = connectionFactory, queueConnectionFactory, topicConnectionFactry# register some queues in JNDI using the form # queue.[jndiName] = [physicalName] queue.MyQueue = example.MyQueue# register some topics in JNDI using the form # topic.[jndiName] = [physicalName] topic.MyTopic = example.MyTopic# END SNIPPET: jndipackage com.eviac.blog.jms;import javax.jms.*; import javax.naming.InitialContext; import javax.naming.NamingException;import org.apache.log4j.BasicConfigurator;public class Producer {public Producer() throws JMSException, NamingException {// Obtain a JNDI connection InitialContext jndi = new InitialContext();// Look up a JMS connection factory ConnectionFactory conFactory = (ConnectionFactory) jndi .lookup('connectionFactory'); Connection connection;// Getting JMS connection from the server and starting it connection = conFactory.createConnection(); try { connection.start();// JMS messages are sent and received using a Session. We will // create here a non-transactional session object. If you want // to use transactions you should set the first parameter to 'true' Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);Destination destination = (Destination) jndi.lookup('MyQueue');// MessageProducer is used for sending messages (as opposed // to MessageConsumer which is used for receiving them) MessageProducer producer = session.createProducer(destination);// We will send a small text message saying 'Hello World!' TextMessage message = session.createTextMessage('Hello World!');// Here we are sending the message! producer.send(message); System.out.println('Sent message '' + message.getText() + '''); } finally { connection.close(); } }public static void main(String[] args) throws JMSException { try { BasicConfigurator.configure(); new Producer(); } catch (NamingException e) { e.printStackTrace(); }} }package com.eviac.blog.jms;import javax.jms.*; import javax.naming.InitialContext; import javax.naming.NamingException;import org.apache.log4j.BasicConfigurator;public class Consumer { public Consumer() throws NamingException, JMSException { Connection connection; // Obtain a JNDI connection InitialContext jndi = new InitialContext();// Look up a JMS connection factory ConnectionFactory conFactory = (ConnectionFactory) jndi .lookup('connectionFactory'); // Getting JMS connection from the server and starting it // ConnectionFactory connectionFactory = new // ActiveMQConnectionFactory(url); connection = conFactory.createConnection();// // Getting JMS connection from the server // ConnectionFactory connectionFactory = new // ActiveMQConnectionFactory(url); // Connection connection = connectionFactory.createConnection(); try { connection.start();// Creating session for seding messages Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// Getting the queue Destination destination = (Destination) jndi.lookup('MyQueue');// MessageConsumer is used for receiving (consuming) messages MessageConsumer consumer = session.createConsumer(destination);// Here we receive the message. // By default this call is blocking, which means it will wait // for a message to arrive on the queue. Message message = consumer.receive();// There are many types of Message and TextMessage // is just one of them. Producer sent us a TextMessage // so we must cast to it to get access to its .getText() // method. if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; System.out.println('Received message '' + textMessage.getText() + '''); } } finally { connection.close(); } }public static void main(String[] args) throws JMSException { BasicConfigurator.configure(); try { new Consumer(); } catch (NamingException e) { // TODO Auto-generated catch block e.printStackTrace(); }} }Publisher Subscriber Model Publisher publishes the message to a specified topic within JMS provider and all the subscribers who subscribed for that topic receive the message. Note that only the active subscribers receive the message.Point to Point Model Example package com.eviac.blog.jms;import javax.jms.*; import javax.naming.*;import org.apache.log4j.BasicConfigurator;import java.io.BufferedReader; import java.io.InputStreamReader;public class DemoPublisherSubscriberModel implements javax.jms.MessageListener { private TopicSession pubSession; private TopicPublisher publisher; private TopicConnection connection;/* Establish JMS publisher and subscriber */ public DemoPublisherSubscriberModel(String topicName, String username, String password) throws Exception { // Obtain a JNDI connection InitialContext jndi = new InitialContext();// Look up a JMS connection factory TopicConnectionFactory conFactory = (TopicConnectionFactory) jndi .lookup('topicConnectionFactry');// Create a JMS connection connection = conFactory.createTopicConnection(username, password);// Create JMS session objects for publisher and subscriber pubSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); TopicSession subSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);// Look up a JMS topic Topic chatTopic = (Topic) jndi.lookup(topicName);// Create a JMS publisher and subscriber publisher = pubSession.createPublisher(chatTopic); TopicSubscriber subscriber = subSession.createSubscriber(chatTopic);// Set a JMS message listener subscriber.setMessageListener(this);// Start the JMS connection; allows messages to be delivered connection.start();// Create and send message using topic publisher TextMessage message = pubSession.createTextMessage(); message.setText(username + ': Howdy Friends!'); publisher.publish(message);}/* * A client can register a message listener with a consumer. A message * listener is similar to an event listener. Whenever a message arrives at * the destination, the JMS provider delivers the message by calling the * listener's onMessage method, which acts on the contents of the message. */ public void onMessage(Message message) { try { TextMessage textMessage = (TextMessage) message; String text = textMessage.getText(); System.out.println(text); } catch (JMSException jmse) { jmse.printStackTrace(); } }public static void main(String[] args) { BasicConfigurator.configure(); try { if (args.length != 3) System.out .println('Please Provide the topic name,username,password!');DemoPublisherSubscriberModel demo = new DemoPublisherSubscriberModel( args[0], args[1], args[2]);BufferedReader commandLine = new java.io.BufferedReader( new InputStreamReader(System.in));// closes the connection and exit the system when 'exit' enters in // the command line while (true) { String s = commandLine.readLine(); if (s.equalsIgnoreCase('exit')) { demo.connection.close(); System.exit(0);} } } catch (Exception e) { e.printStackTrace(); } } }Reference: JMS with ActiveMQ from our JCG partner Pavithra Siriwardena at the EVIAC blog....
scala-logo

Custom Ordering Scala TreeMap

How do you get custom ordering in a Scala TreeMap? Well this puzzled me for a while. The answer lies in the world of implicits and receiver type converters. In a nut shell, a scala.collection.immutable.TreeMap is a SortedMap. If you look at the documentation for TreeMap, you will see it takes an Ordering[T] as an implicit argument. Normally when you declare a TreeMap, say inline, it will use the default Ordering object like so:- scala> val dtm = TreeMap( "a" -> 1, "bc" -> 2, "def" -> 3 ) dtm: scala.collection.immutable.TreeMap1 = Map(a -> 1, bc -> 2, def -> 3) If you want to change the ordering of the keys, for example, instead of the ascending order by String content, into, say, a descending order of strings length then you need an Ordering type. scala> object VarNameOrdering extends Ordering[String] { def compare(a:String, b:String) = b.length compare a.length } defined module VarNameOrdering Now you can use the second argument list in an explicit fashion like this: scala> val tm1 = TreeMap( "a" -> 1, "bc" -> 2, "def" -> 3 )( VarNameOrdering ) tm: scala.collection.immutable.TreeMap1 = Map(def -> 3, bc -> 2, a -> 1) We pass the object to the TreeMap, which is rather similiar to a Java Collection Comparator object without the boilerplate instantiation. The keys of the TreeMap are now ordered by String lengths. We add more elements and the map will stay ordered. val tm2 = tm1 + ( "food" -> 4 ) cala.collection.immutable.TreeMap1 = Map(food -> 4, def -> 3, bc -> 2, a -> 1) However, a word of caution, one needs to be careful and remember that maps are usually implemented as hashes. scala> val tm3 = tm2 + ( "z" -> 5 ) tm3: scala.collection.immutable.TreeMap1 = Map(food -> 4, def -> 3, bc -> 2, z -> 5) Surprised? You should be. Another way to sort a map is just to get access to the keys and sort. scala> dtm.keys.toList.sortWith ( _.length > _.length ) res3: List1 = List(salad, def, bc, a)scala> dtm.keys.toList.sortWith ( _.length > _.length ).map( k => ( dtm.get(k).get )) res4: List[Int] = List(10, 3, 2, 1)scala> dtm.keys.toList.sortWith ( _.length > _.length ).map( k => ( k, dtm.get(k).get )) res5: List[(java.lang.String, Int)] = List((salad,10), (def,3), (bc,2), (a,1)) This may well be a better solution, as you have not lost a key in flight! Considering how data is going to be stored is a major decision that needs to be taken early. You can always decide how to write projection of that data much later. Finally, it is interesting to see the parallels between Java and Scala scala> dtm.keys res6: Iterable1 = Set(a, bc, def, salad)scala> dtm.keys.toList res7: List1 = List(a, bc, def, salad)Reference: Custom Ordering Scala TreeMap from our JCG partner Peter Pilgrim at the Peter Pilgrim’s blog blog....
zk-logo

ZK in Action: MVVM – Load and Render Data

A previous post had briefly introduced the RIA framework ZK and how its CSS Selector inspired controller mechanism alleviates some of the burdens that comes with UI changes by making the task of referencing UI components in the controller class a relatively flexible affair. We then explored how the MVVM patterns in ZK allows a single ViewModel to serve different views in the last post. This post marks the beginning of a series of posts that will go through steps in building a simple application from the ground up using ZK. Objective For now, we’ll build a simple inventory management feature which is limited only to the loading and rendering of a data collection from a database into a table. ZK Features in ActionMVVM : Load Template TagLoad and Render Data into a Table with MVVM Assume there’s a collection of objects named “Item” and there’s a DataService class which takes care of caching and communication with the database (MongoDB and Morphia). @Entity("items") public class Item { @Id private ObjectId id; private String name; private String model; private int qty; private float price; private Date datemod; // getters & setters To render data into a table as shown below in ZK, we’ll need to implement these parts:A POJO that will serve as our ViewModel A ZK markup file as our presentationThe ViewModel Class public class InventoryVM {private List<item> items; public List<item> getItems() throws Exception{ items = DataService.getInstance().getAllItems(); return items; } }Line 3, the list of items needs to be declared as a property of the VM class Line 5, we need to provide a getter method so the Binder can retrieve the list of items. To recap, the Binder holds reference to the UI components and the ViewModel so it can keep data on both sides in sync as well as call command methods in ViewModel as events are triggered in View.The Markup <window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('lab.sphota.zk.ctrl.InventoryVM')"> <listbox model="@load(vm.items) "> <listhead> <listheader label="Name" /> <listheader label="Model" /> <listheader label="Quantity" /> <listheader label="Unit Price"/> <listheader label="Last Modified" /> </listhead> <template name="model" var="item" > <listitem> <listcell> <textbox value="@load(item.name)" inplace="true" /> </listcell> <listcell> <textbox value="@load(item.model)" inplace="true" /> </listcell> <listcell> <spinner value="@load(item.qty)" inplace="true" /> </listcell> <listcell> <decimalbox value="@load(item.price)" inplace="true" format="#,###.00"/> </listcell> <listcell label="@load(item.datemod)" /> </listitem> </template> </listbox> </window>Line 1, we apply ZK’s default implementation of its BindComposer. It is responsible for instantiating our VM instance as well as the Binder instance. Line 2, we supply the full class name of the ViewModel we wish to instantiate and give it an ID (in this case, ‘vm’) for future reference Line 3, we assign a data model, which we made as a property of our ViewModel instance, to the Listbox. Line 11, we instruct the Template component to iterate through the given collection. We also declare a variable called “item” which will iteratively take on each Item object inside our collection. Alternatively, we can omit the variable declaration and use the keyword “each” to reference the data object (Item). Line 14, 17, 20, 23, 26, we retrieve the Item properties which we’d like to be displayed in the Listbox. Here we use input elements (Textbox, Spinner, Decimalbox) inside the Listcells in anticipation of our future implementation of an editable table. The attribute “inplace=true” will render these input elements as regular labels while they’re not selected.Wrap Up ZK Binder is central to the workings of ZK MVVM. It holds references to both the UI components and the ViewModel. The ViewModel class is just a POJO where we declare and assign our data models. It exposes getter methods so Binder can retrieve and bind data to their respective annotated UI components. The template tag then allows us to iteratively render UI components with respect to the data model. In our case, a row of 5 Listcells with each cell holding a bean property is rendered iteratively through the bean collection using the template tag. In the next post, we’ll implement an “Add” feature so we can save new entries to our existing inventory using MVVM’s form binding. Reference ZK Developer Reference Reference: ZK in Action [0] : MVVM – Load and Render Data from our JCG partner Lance Lu at the Tech Dojo blog....
java-logo

How changing Java package names transformed my system architecture

Changing your perspective even a small amount can have profound effects on how you approach your system.Let’s say you’re writing a web application in Java. In the system you deal with orders, customers and products. As a web application, your classes include staples like PersonController, PersonRepository, CustomerController and OrderService. How do you organize your classes into packages?There are two fundamental ways to structure your packages. Either you can focus on the logical tiers, like com.brodwall.myapp.controllers, com.brodwall.myapp.domain or perhaps com.brodwall.myapp.services.customer. Or you can focus on the domain contexts, like com.brodwall.myapp.customer, com.brodwall.myapp.orders and com.brodwall.myapp.products. The first approach is by far the most prevalent. In my view, it’s also the least helpful.Here are some ways your thinking changes if you structure your packages around domain concepts, rather than technological tiers:First, and most fundamentally, your mental model will now be aligned with that of the users of your system. If you’re asked to implement a typical feature, it is now more likely to be focused around a strict subset of the packages of your system. For example, adding a new field to a form will at least affect the presentation logic, entity and persistence layer for the corresponding domain concept. If your packages are organized around tiers, this change will hit all over your system. In a word: A system organized around features, rather than technologies, have higher coherence. This technical term means that a large percentage of a the dependencies of a class are located close to that class.Secondly, organizing around domain concepts will give you more options when your software grows. When a package contains tens of classes, you may want to split it up in several packages. The discussion can itself be enlightening. “Maybe we should separate out the customer address classes into a com.brodwall.myapp.customer.address package. It seems to have a bit of a life on its own.” “Yeah, and maybe we can use the same classes for other places we need addresses, such as suppliers?” “Cool, so com.brodwall.myapp.address, then?” Or maybe you decide that order status codes and payment status codes deserve to be in the “com.brodwall.myapp.order.codes” package.On the other hand, what options do you have for splitting up com.brodwall.myapp.controllers? You could create subpackages for customer, orders and products, but these subpackages may only have one or possibly two classes each.Finally, and perhaps most intriguingly, using domain concepts for packages allows you to vary the design according on a case by case basis. Maybe you really need a OrderService which coordinates the payment and shipping of an order, while ProductController only needs basic create-retrieve-update-delete functionality with a repository. A ProductService would just get in the way. If ProductService is missing from the com.brodwall.myapp.services package, this may be confusing or at the very least give you a nagging feeling that something is wrong. On the other hand, if there’s no Controller in the com.brodwall.myapp.product package, it doesn’t matter much.Also, most systems have some good parts and some not-so-good parts. If your Services package is not working for you, there’s not much you can do. But if the Products package is rotten, you can throw it out and reimplement it without the whole system being thrown into a state of chaos.By putting the classes needed to implement a feature together with each other and apart from the classes needed to implement other features, developers can be pragmatic and innovative when developing one feature without negatively affecting other features.The flip side of this is that most developers are more comfortable with some technologies in the application and less comfortable with other technologies. Organizing around features instead of technologies force each developer to consider a larger set of technological challenges. Some programmers take this as a motivating challenge to learn, while others, it seems, would rather not have to learn something new.If it were my money being spend to create features, I know what kind of developer I would want.Trivial changes can have large effects. By organizing your software around features, you get a more coherent system that allows for growth. It may challenge your developers, but it drives down the number of hand-offs needed to implement a feature and it challenges the developers to improve the parts of the application they are working on.Reference: How changing Java package names transformed my system architecture from our JCG partner Johannes Brodwall at the Thinking Inside a Bigger Box blog....
Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close