Featured FREE Whitepapers

What's New Here?

spring-logo

Spring 3 Internationalization and Localization

I wanted to add internationalization and localization feature provided by spring 3 to one of my current project recently. I went through the spring documentation and then searched on internet to find some resources.But I could not find a resource which was able to satisfy my client requirement. Most of the tutorials are like hello world application which gives basic understanding. Even spring documentation does not give in detailed explanation on integrating this feature to our own project. Expert developers can pick the stuff from spring documentation. But for others, have to put extra effort to make things up and running. With this tutorial, I am going to explain very practical scenario that most of the clients are expecting.The requirementI am using spring security with my application. User should be able to select the language from the log-in page which was specified as ‘ login-page’ of spring security XML file. I have provided links as “English”,”Chinese”,”German” and “Spanish” on top right corner of my log-in page to select the language. User can select the language and log in to the system by providing username and password. Then the whole application should be from the selected language. And also when selecting the language from the log-in page, the contents of the log-in page should also be changed.Spring configurationsAs the first step, I had to configure LocaleChangeInterceptor interceptor with in the dispatcher-servlet.xml file. This XML file name will change according to the name given to DispatcherServlet in web.xml file. I have given ‘ dispatcher’ as the name for DispatcherServlet. So I should create ‘ dispatcher-servlet.xml‘ file under /WEB-INF folder. My application is running on Tomcat 7.I could not make it working by following the way of declaring this interceptor as in the spring documentation. The request for changing the locale before log in(ie: from the login page) was not intercepted by the locale change interceptor. Therefore, I had to declare it as fallows. <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/doChangeLocale*"/> <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" > <property name="paramName" value="locale" /> </bean> </mvc:interceptor> </mvc:interceptors> The ‘ LocaleChangeInterceptor‘ will intercept the request asking for locale change and the corresponding locale code will be stored in the session with the help of ‘ SessionLocaleResolver‘.Next we will look at how to declare the ‘SessionLocaleResolver’ in the ‘dispatcher-servlet.xml’ file. <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"> <property name="defaultLocale" value="en" /> </bean> The SessionLocaleResolver will store the locale in the current session and resolve it for every subsequent user requests for the current session.Next, we have to declare the message resource bean. <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="useCodeAsDefaultMessage" value="true" /> <property name="basenames"> <list> <value>classpath:messages</value> </list> </property> <property name="cacheSeconds" value="0" /> <property name="defaultEncoding" value="UTF-8"></property> </bean> My application should support for 4 languages. So I added 4 property files into the ‘ resources’ folder (ultimately all those property files should be in ‘classes’ folder) as follows.messages_de.properties – German messages_en.properties – English messages_zh.properties – Chinese messages_es.properties – SpanishNote that, all the file names should start with the text which you specified as ‘basenames’ property of message resource bean.The spring 3 security configurations were very important in this implementation. Keep in mind that, when you click any locale change link from the log-in page, you are not authenticated yet. But still that request should be intercepted by ‘LocaleChangeInterceptor’. Otherwise, the language will not be changed as expected. There fore, any anonymous user should be allowed to make locale change request and that request should go through the ‘LocaleChangeInterceptor’.Carefully look into my spring security configuration. <http auto-config="false"> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=true" default-target-url="/mainMenu.htm"/> <logout logout-success-url="/login.jsp"/> <intercept-url pattern="/doChangeLocale**" access="ROLE_ANONYMOUS,ROLE_ADMIN,ROLE_USER"/> <intercept-url pattern="/**" access="ROLE_ADMIN,ROLE_USER" /> </http> The login.jsp file is where user can log into the system by providing username and password and also that page has the corresponding links to change the locale. When user makes any request to a protected resource without authenticating, the user will be redirected to the login.jsp page. The above configuration says all the requests that are coming to the application should be from a authenticated user and also the user should be authorized except for the ‘ /doChangeLocale**’ request.The intercept URL ‘ /doChangeLocale**’ is very important. Without that, the requests for changing locales are not intercepted by the locale change interceptor and finally locale will not change. The followings are the locale change links that are placed in the login.jsp file. <a href="<%=request.getContextPath()%>/doChangeLocale?locale=en">English</a> <a href="<%=request.getContextPath()%>/doChangeLocale?locale=de">German</a> <a href="<%=request.getContextPath()%>/doChangeLocale?locale=es">Spanish</a> <a href="<%=request.getContextPath()%>/doChangeLocale?locale=zh">Chinese</a>Hope this will be helpful for you. Reference: Spring 3 Internationalization and Localization – Not ‘Hello World’, But ‘Practical’ from our JCG partner Semika loku kaluge at the Code Box blog....
agile-logo

Hours, Velocity, Silo’d Teams, & Gantts

I’ve been having some email conversations with some project and program managers turned Scrum Masters. In general here’s how things have proceeded:Their organizations decided agile was a great idea Their organizations decided Scrum was a great idea to implement agile (because they don’t know the difference between Scrum and agile) The teams started working in two-week iterations, sort-of getting close to done at the end of the iterationBut, if you peel back the covers, what you see is not really Scrum. The person with the Scrum Master title is doing funky things, such as:preparing Gantt charts for the iteration, so you can see who will do what when predicting velocity based on hours (!!) predicting the number of story points per person per day telling the team what they can commit to for stories and all kinds of other strangeness I don’t associate with agileAnd, the teams are still silo’d teams. That is, there are developer teams, tester teams, architects leading component teams. There are 2- and 3-person teams here and maybe a 4-person teams there. These Scrum Master/project manager/program manager people have their hearts in the right places. But they have not had training, and they don’t know what agile can do for them. So while their iterations are helping them and their projects, they look around and say, “Why is agile not helping me?” If you are one of those people, you have options. Here is my list of recommendations:Stop trying to predict anything for the teams. Make the teams work as teams, and that brings us to #2. Move to cross-functional teams. Make them a reasonable size, such as 5-7 people. Make sure you have at least one tester on each team. If you don’t have enough testers to go around, that’s an impediment, and your team is going to have to develop tests for your code. But teams of 2 people are too small. And much of the time, teams of 3 people are too small. Tester-teams are wrong, just plain wrong. Testers go with developers. You need a cross-functional team to deliver features. Integrate all your architects into the feature teams. If you have more architects than you have teams, you have too many architects. (Yes, one of my correspondents has that problem.)Now, you have teams that might be able to work together. You, as the agile project manager/erstwhile Scrum Master, you, stay out of the middle!Now, when you have an iteration planning meeting, here is what you do. You ask the Product Owner to present the stories, and ask the team if the team can commit to the story for this iteration. That’s it. You don’t commit, the team commits. The team can estimate, but the team commits. If you start predicting velocity and you start predicting which stories a team can commit to, you are not doing agile. You are doing command-and-control in iterations. Oh, and if anyone starts to tell people, “Jim, that’s your story, Sue, that’s your story,” gag that person. Okay, maybe that’s a little extreme. But only a little. Remember, the idea is that the team commits to stories, not a person. What you can say is this, “Is it in our best interests as a team to commit to stories as a person? Remember, we want to make sure all of our stories are done at the end of the iteration. That means the testing has to be done. And, all of the user experience has to be done. (And any of the other special for-your-product stuff has to be done.) If someone who is an expert commits, what happens to the all the other pieces? Does that help us get all the stories done?” Then you hush. You can always facilitate the retrospective and help people learn from what happened. During an iteration, if anyone wants to know what a given team member is doing, you can say, “Look at the board.” If that person wants to know more by seeing a Gantt, you can say, “No, we don’t have Gantts in agile.” If that person signs your paycheck, you can remind that person that you have a demo every two weeks. If that person is insistent, you can ask what the real issue is. Because if that person looks at the people working, can’t that person see that everyone on the team is heads-down working? Look for the information that person wants and find another way to deliver it. If you have trouble seeing what’s really happening, consider adding kanban to your iterations, so you see if you have bottlenecks. Many organizations are understaffed in some area or other, and until you add a kanban board, you can’t see it. Kanban allows you to visualize the flow. Make sure you do a retrospective at the end of each iteration. Every single time. The retros can help you more than you know. Choose one thing to work on after each retro (okay, maybe up to three things), and see how fast you improve.What’s key is for the teams to turn into self-directed teams, not manager-led teams. The teams have to take responsibility for their own work, and fast. They have to recognize their own impediments. For many of these teams, one of the major impediments is that the stories are too large. They don’t realize it, so they try to take on too many stories at the start of the iteration. They can’t finish them all, so they don’t get credit, and they are left with unfinished work at the end of the iteration. Well, that frustrates everyone. Who is a “bad” estimator? Maybe no one. If the stories were smaller, or if a sufficiently large team swarmed around the stories, maybe the teams could complete the stories in the iteration. But asking a 2-person team to complete something that takes a 6-person team 1 week is crazy. Of course, I think a story that takes a 6-person team 1 week is too big. So, if you are on one of these not-quite-agile teams, take heart. First, you are not alone. There are people all over the world, just like you. If your management won’t allow you to take training, start reading. I’m sure there will be comments about what else to read. Here are my suggestions for reading: Join the scrumdevelopment group which is a yahoo group. There is plenty of free advice there. Much of it is good. Listen to everything Ron Jeffries says. Manage It! Your Guide to Modern, Pragmatic Project Management. I offer you tons of ideas about facilitative project management. (Yes, you can buy my book on Amazon. But you can only buy the electronic version on the Prag site, because that way you can get the updates for free.) Exploring Scrum: The Fundamentals. Rawsthorne and Shimp take you through the nuts and bolts of Scrum. Reference: Hours, Velocity, Silo’d Teams, & Gantts from our JCG partner Johanna Rothman at the Managing Product Development blog....
play-framework-logo

Play Framework posted values revisited

Working with posted values with Play Framework 2.0, without defining a form mapping, might not be so obvious as it was with Play 1.x, that’s why I’m writing this quick cheatsheet. For this quick sample, let’s define the following view: app/views/index.scala.html @(message: String)message: @message <br /><h2>Scala form</h2><form action="@routes.ScalaPoster.save()" method="POST"> scala name: <input name="scala_name"> <br /> scala surname: <input name="scala_surname"> <br /> <input type="submit" value="save"> </form><h2>Java form</h2><form action="@routes.JavaPoster.save()" method="POST"> java name: <input name="java_name"> <br /> java surname: <input name="java_surname"> <br /> <input type="submit" value="save"> </form> And the following routes file: conf/routes # Home page GET / controllers.Application.indexPOST /scala controllers.ScalaPoster.save POST /java controllers.JavaPoster.save With java, accesing directly the request body: app/controllers/JavaPoster.java package controllers;import play.mvc.*;import views.html.*;import java.util.Map;public class JavaPoster extends Controller { public static Result save() {final Map<String, String[]> values = request().body().asFormUrlEncoded(); final String name = values.get("java_name")[0]; final String surname = values.get("java_surname")[0]; return ok(index.render(String.format("You are %s, %s",surname, name))); } } Or using a DynamicForm: package controllers;import play.mvc.*;import views.html.*;import play.data.DynamicForm;public class JavaPoster extends Controller { public static Result save() {final DynamicForm form = form().bindFromRequest(); final String name = form.get("java_name"); final String surname = form.get("java_surname"); return ok(index.render(String.format("You are %s, %s",surname, name))); } } Now the scala version, accessing the body: app/controllers/ScalaPoster.java package controllersimport play.api.mvc._object ScalaPoster extends Controller {def save = Action { request =>def name = request.body.asFormUrlEncoded.get("scala_name")(0) def surname = request.body.asFormUrlEncoded.get("scala_surname")(0)Ok(views.html.index("You are %s, %s".format(surname, name))) }} And defining a form package controllersimport play.api.mvc._import play.api.data.Form import play.api.data.Forms.tuple import play.api.data.Forms.textobject ScalaPoster extends Controller {val form = Form( tuple( "scala_name" -> text, "scala_surname" -> text ) )def save = Action { implicit request => def values = form.bindFromRequest.data def name = values("scala_name") def surname = values("scala_surname")Ok(views.html.index("You are %s, %s".format(surname, name))) }} Notice the implict request in the above sample. You could explicitly pass it to bindFromRequest with def values = form.bindFromRequest()(request).data You can also play with the tuples and issue something like val data = form.bindFromRequest.get Ok(views.html.index("You are %s, %s".format(data._2, data._1))) or val (name, surname) = form.bindFromRequest.get Ok(views.html.index("You are %s, %s".format(surname, name))) And of course, if you just want to read a single posted value you could issue: def name = Form("scala_name" -> text).bindFromRequest.getThere are several ways to achieve it. I hope this serves as a useful reminder. Reference: Play Framework posted values revisited from our JCG partner Sebastian Scarano at the Having fun with Play framework! blog....
jsf-logo

JSF Simple Ajax Samples

Today we will see some Simple Samples of Ajax with JSF. If you want to see other posts about JSF/Web Applications click on the next links: JSF Persisting Objects and Messages after a Redirect ,User Login Validation with JAAS and JSF, JSF: Converter and Bean AutoComplete, JSF – Hello World, Auto Complete, Handling Exceptions on a WebApp, User Authentication (Filter/Servlet), Creating a WebServer. In the end of this post you will find the link to download the source code of the samples. In this post (User Login Validation with JAAS and JSF) I show how to install the JBoss 6 in case you want to run the project from today. You will need to install the JBoss tools plugin in your Eclipse. Take a look at the page bellow and its code:<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:f='http://java.sun.com/jsf/core'> <h:head> </h:head> <h:body> <h:form> Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/> <br /> <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'/> <br /> </h:form> </h:body> </html> How could we display the typed name in the same screen using Ajax? Piece of cake, just add the “f:ajax” component. Check the code update and the result:<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:f='http://java.sun.com/jsf/core'> <h:head> </h:head> <h:body> <h:form> Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/> <br /> <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'> <f:ajax render='myName' execute='inputname' /> </h:commandButton> <br /> <br /> <h:outputText id='myName' value='#{user.name}' /> </h:form> </h:body> </html> It is very easy right? We just need to pass the value that will be carried to the ManagedBean by the “execute” parameter; with the “render” parameter we will tell to the JSF which component will be “refreshed”. Notice also that the typed name appears in the Console. With this code we can “refresh” all kind of components. Let us see another sample? Let us display an error message if the user types a name with less than 4 characters. Check our new message and the new code:<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:f='http://java.sun.com/jsf/core'> <h:head> </h:head> <h:body> <h:form> <h:messages id='myMessage' globalOnly='true' showDetail='true'/> Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}'/> <br /> <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'> <f:ajax render='myName myMessage' execute='inputname' /> </h:commandButton> <br /> <br /> <h:outputText id='myName' value='#{user.name}' /> </h:form> </h:body> </html> package demo;import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.context.FacesContext;/** * Created by JBoss Tools */ @ManagedBean(name = 'user') @RequestScoped public class User {private String name;public String sayHello() { if (isNameIncorrect()) { FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?')); }System.out.println(name); return null; }private boolean isNameIncorrect() { return ''.equals(name.trim()) || name.length() < 3; }public String getName() { return name; }public void setName(String name) { this.name = name; } } Notice that we have the component “h:messages” and its ID is used in the “f:ajax” component. This code also works when you use the “h:message for=“YYY”” component. What if we work now with comboboxes? Let us display a combobox that will contain 4 items when we have a name with less than 6 characters, and a list with more than 4 items if the typed name has more than 6 characters. package demo;import java.util.ArrayList; import java.util.List;import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.component.UISelectItems; import javax.faces.component.html.HtmlSelectOneMenu; import javax.faces.context.FacesContext; import javax.faces.event.AjaxBehaviorEvent;/** * Created by JBoss Tools */ @ManagedBean(name = 'user') @RequestScoped public class User {private String name;private List<String> cars;private String selectedCar; private HtmlSelectOneMenu htmlSelectCars;private static final String SELECT_A_CAR = 'Select One Car';public User() { cars = new ArrayList<String>(); }public String sayHello() { if (isNameInCorrect()) { FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?')); }System.out.println(name); return null; }private boolean isNameInCorrect() { return name == null || ''.equals(name.trim()) || name.length() < 3; }public String getName() { return name; }public void setName(String name) { this.name = name; }public void editMyCarsList(AjaxBehaviorEvent event) { if (htmlSelectCars == null) { htmlSelectCars = new HtmlSelectOneMenu(); }htmlSelectCars.getChildren().clear();UISelectItems items = new UISelectItems(); items.setValue(getCars()); htmlSelectCars.getChildren().add(items); }public List<String> getCars() { cars.clear();cars.add(SELECT_A_CAR);if (!isNameInCorrect() && name.length() >= 6) { cars.add('Ferrari'); cars.add('Porch'); cars.add('Beetle'); cars.add('Opala'); cars.add('Passat'); cars.add('Vectra'); cars.add('Chevet'); cars.add('Corvet'); } else { cars.add('Ferrari'); cars.add('Porch'); cars.add('Beetle'); cars.add('Opala'); }return cars; }public void setCars(List<String> cars) { this.cars = cars; }public String getSelectedCar() { return selectedCar; }public void setSelectedCar(String selectedCar) { this.selectedCar = selectedCar; }public HtmlSelectOneMenu getHtmlSelectCars() { editMyCarsList(null);return htmlSelectCars; }public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) { this.htmlSelectCars = htmlSelectCars; } } Take a look now at our page:<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:f='http://java.sun.com/jsf/core'> <h:head> </h:head> <h:body> <h:form> <h:messages id='myMessage' globalOnly='true' showDetail='true' /> Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}' /> <br /> <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'> <f:ajax render='myName myCars myMessage' execute='inputname' listener='#{user.editMyCarsList}' /> </h:commandButton> <br /> <br /> <h:outputText id='myName' value='#{user.name}' /> <br /> <br /> Choose your car: <h:selectOneMenu id='myCars' binding='#{user.htmlSelectCars}' value='#{user.selectedCar}' /> <br /> <br /> </h:form> </h:body> </html> Notice that our combobox items size is updated according to the typed name. At the end of this post I will talk more about why I used the binding attribute to the HtmlSelectOneMenu instead returning the List<String>. As our last sample, let us create a combobox that will appear and disappear according to the selected value in the Car combobox. Take a look at our ManagedBean: package demo;import java.util.ArrayList; import java.util.List;import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.component.UISelectItems; import javax.faces.component.html.HtmlSelectOneMenu; import javax.faces.context.FacesContext; import javax.faces.event.AjaxBehaviorEvent;/** * Created by JBoss Tools */ @ManagedBean(name = 'user') @RequestScoped public class User {private String name;private List<String> cars; private List<String> colors;private String selectedCar; private String selectedColor; private HtmlSelectOneMenu htmlSelectCars;private static final String SELECT_A_CAR = 'Select One Car';public User() { cars = new ArrayList<String>(); colors = new ArrayList<String>();colors.add('Red'); colors.add('Blue'); colors.add('Orange'); colors.add('Pink --> O.o'); }public String sayHello() { if (isNameInCorrect()) { FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, 'Too small', 'Can you write it a little bigger?')); }System.out.println(name); return null; }private boolean isNameInCorrect() { return name == null || ''.equals(name.trim()) || name.length() < 3; }public String getName() { return name; }public void setName(String name) { this.name = name; }public void editMyCarsList(AjaxBehaviorEvent event) { if (htmlSelectCars == null) { htmlSelectCars = new HtmlSelectOneMenu(); }htmlSelectCars.getChildren().clear();UISelectItems items = new UISelectItems(); items.setValue(getCars()); htmlSelectCars.getChildren().add(items); }public List<String> getCars() { cars.clear();cars.add(SELECT_A_CAR);if (!isNameInCorrect() && name.length() >= 6) { cars.add('Ferrari'); cars.add('Porch'); cars.add('Beetle'); cars.add('Opala'); cars.add('Passat'); cars.add('Vectra'); cars.add('Chevet'); cars.add('Corvet'); } else { cars.add('Ferrari'); cars.add('Porch'); cars.add('Beetle'); cars.add('Opala'); }return cars; }public void setCars(List<String> cars) { this.cars = cars; }public String getSelectedCar() { return selectedCar; }public void setSelectedCar(String selectedCar) { this.selectedCar = selectedCar; }public List<String> getColors() { return colors; }public void setColors(List<String> colors) { this.colors = colors; }public boolean isColorsAlloweToDisplay() { if (isNameInCorrect()) { return false; }if (selectedCar == null || selectedCar.trim().equals('') || selectedCar.equals(SELECT_A_CAR)) { return false; }return true; }public String getSelectedColor() { return selectedColor; }public void setSelectedColor(String selectedColor) { this.selectedColor = selectedColor; }public HtmlSelectOneMenu getHtmlSelectCars() { editMyCarsList(null);return htmlSelectCars; }public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) { this.htmlSelectCars = htmlSelectCars; } } Our ManagedBean were lightly updated, we just added a List with a method that return a list of colors that will populate our combobox; we added also a method that will return a Boolean – true if the combobox is allowed to be displayed. Check our new page:<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'> <html xmlns='http://www.w3.org/1999/xhtml' xmlns:ui='http://java.sun.com/jsf/facelets' xmlns:h='http://java.sun.com/jsf/html' xmlns:f='http://java.sun.com/jsf/core'> <h:head> </h:head> <h:body> <h:form> <h:messages id='myMessage' globalOnly='true' showDetail='true' /> Your Name: <h:inputText id='inputname' label='${msgs.prompt}' value='#{user.name}' /> <br /> <h:commandButton action='#{user.sayHello}' value='Display my name here, now!'> <f:ajax render='myName myCars myMessage myColors' execute='inputname' listener='#{user.editMyCarsList}' /> </h:commandButton> <br /> <br /> <h:outputText id='myName' value='#{user.name}' /> <br /> <br /> Choose your car: <h:selectOneMenu id='myCars' binding='#{user.htmlSelectCars}' value='#{user.selectedCar}'> <f:ajax render='myColors' execute='inputname myCars'/> </h:selectOneMenu> <br /> <br /> <h:panelGroup id='myColors'> <h:selectOneMenu value='#{user.selectedColor}' rendered='#{user.colorsAlloweToDisplay}'> <f:selectItems value='#{user.colors}' /> </h:selectOneMenu> </h:panelGroup> </h:form> </h:body> </html> I will talk about the code used in the post:HtmlSelectOneMenu – I used the component instead a List because the JSF is not so good in render the components in the user screen (DOM Tree). If your combobox has 4 lines and by using ajax you add more lines to the List, the JSF/Ajax will not recognize the new added lines; you will be able to use only the older values. You can try to use the code with a List<String> instead using the HtmlSelectOneMenu and see the result; I spend like 3~4 hours to understand this by a lot of searches on the internet. HtmlSelectOneMenu inside the “h:panelGroup” component – I did this because every time you want to render a non rendered component you need to update its container. If our selectOne were inside the same form of the car selectOne you would need to render all form.Click here to download the code from this post. I hope this post might help you. If you have any question/doubt/suggestion just post it. Reference: JSF Simple Ajax Samples from our JCG partner Hebert Coelho at the uaiHebert blog....
java-logo

Java Sequential IO Performance

Many applications record a series of events to file-based storage for later use. This can be anything from logging and auditing, through to keeping a transaction redo log in an event sourced design or its close relative CQRS.Java has a number of means by which a file can be sequentially written to, or read back again. This article explores some of these mechanisms to understand their performance characteristics. For the scope of this article I will be using pre-allocated files because I want to focus on performance. Constantly extending a file imposes a significant performance overhead and adds jitter to an application resulting in highly variable latency. “Why is a pre-allocated file better performance?”, I hear you ask. Well, on disk a file is made up from a series of blocks/pages containing the data. Firstly, it is important that these blocks are contiguous to provide fast sequential access. Secondly, meta-data must be allocated to describe this file on disk and saved within the file-system. A typical large file will have a number of “indirect” blocks allocated to describe the chain of data-blocks containing the file contents that make up part of this meta-data. I’ll leave it as an exercise for the reader, or maybe a later article, to explore the performance impact of not preallocating the data files. If you have used a database you may have noticed that it preallocates the files it will require.The TestI want to experiment with 2 file sizes. One that is sufficiently large to test sequential access, but can easily fit in the file-system cache, and another that is much larger so that the cache subsystem is forced to retire pages so that new ones can be loaded. For these two cases I’ll use 400MB and 8GB respectively. I’ll also loop over the files a number of times to show the pre and post warm-up characteristics.I’ll test 4 means of writing and reading back files sequentially:RandomAccessFile using a vanilla byte[] of page size. Buffered FileInputStream and FileOutputStream. NIO FileChannel with ByteBuffer of page size. Memory mapping a file using NIO and direct MappedByteBuffer.The tests are run on a 2.0Ghz Sandybridge CPU with 8GB RAM, an Intel 320 SSD on Fedora Core 15 64-bit Linux with an ext4 file system, and Oracle JDK 1.6.0_30. The Code import java.io.*; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel;import static java.lang.Integer.MAX_VALUE; import static java.lang.System.out; import static java.nio.channels.FileChannel.MapMode.READ_ONLY; import static java.nio.channels.FileChannel.MapMode.READ_WRITE;public final class TestSequentialIoPerf { public static final int PAGE_SIZE = 1024 * 4; public static final long FILE_SIZE = PAGE_SIZE * 2000L * 1000L; public static final String FILE_NAME = "test.dat"; public static final byte[] BLANK_PAGE = new byte[PAGE_SIZE];public static void main(final String[] arg) throws Exception { preallocateTestFile(FILE_NAME);for (final PerfTestCase testCase : testCases) { for (int i = 0; i < 5; i++) { System.gc(); long writeDurationMs = testCase.test(PerfTestCase.Type.WRITE, FILE_NAME);System.gc(); long readDurationMs = testCase.test(PerfTestCase.Type.READ, FILE_NAME);long bytesReadPerSec = (FILE_SIZE * 1000L) / readDurationMs; long bytesWrittenPerSec = (FILE_SIZE * 1000L) / writeDurationMs;out.format("%s\twrite=%,d\tread=%,d bytes/sec\n", testCase.getName(), bytesWrittenPerSec, bytesReadPerSec); } }deleteFile(FILE_NAME); }private static void preallocateTestFile(final String fileName) throws Exception { RandomAccessFile file = new RandomAccessFile(fileName, "rw");for (long i = 0; i < FILE_SIZE; i += PAGE_SIZE) { file.write(BLANK_PAGE, 0, PAGE_SIZE); }file.close(); }private static void deleteFile(final String testFileName) throws Exception { File file = new File(testFileName); if (!file.delete()) { out.println("Failed to delete test file=" + testFileName); out.println("Windows does not allow mapped files to be deleted."); } }public abstract static class PerfTestCase { public enum Type { READ, WRITE }private final String name; private int checkSum;public PerfTestCase(final String name) { this.name = name; }public String getName() { return name; }public long test(final Type type, final String fileName) { long start = System.currentTimeMillis();try { switch (type) { case WRITE: { checkSum = testWrite(fileName); break; }case READ: { final int checkSum = testRead(fileName); if (checkSum != this.checkSum) { final String msg = getName() + " expected=" + this.checkSum + " got=" + checkSum; throw new IllegalStateException(msg); } break; } } } catch (Exception ex) { ex.printStackTrace(); }return System.currentTimeMillis() - start; }public abstract int testWrite(final String fileName) throws Exception; public abstract int testRead(final String fileName) throws Exception; }private static PerfTestCase[] testCases = { new PerfTestCase("RandomAccessFile") { public int testWrite(final String fileName) throws Exception { RandomAccessFile file = new RandomAccessFile(fileName, "rw"); final byte[] buffer = new byte[PAGE_SIZE]; int pos = 0; int checkSum = 0;for (long i = 0; i < FILE_SIZE; i++) { byte b = (byte)i; checkSum += b;buffer[pos++] = b; if (PAGE_SIZE == pos) { file.write(buffer, 0, PAGE_SIZE); pos = 0; } }file.close();return checkSum; }public int testRead(final String fileName) throws Exception { RandomAccessFile file = new RandomAccessFile(fileName, "r"); final byte[] buffer = new byte[PAGE_SIZE]; int checkSum = 0; int bytesRead;while (-1 != (bytesRead = file.read(buffer))) { for (int i = 0; i < bytesRead; i++) { checkSum += buffer[i]; } }file.close();return checkSum; } },new PerfTestCase("BufferedStreamFile") { public int testWrite(final String fileName) throws Exception { int checkSum = 0; OutputStream out = new BufferedOutputStream(new FileOutputStream(fileName));for (long i = 0; i < FILE_SIZE; i++) { byte b = (byte)i; checkSum += b; out.write(b); }out.close();return checkSum; }public int testRead(final String fileName) throws Exception { int checkSum = 0; InputStream in = new BufferedInputStream(new FileInputStream(fileName));int b; while (-1 != (b = in.read())) { checkSum += (byte)b; }in.close();return checkSum; } },new PerfTestCase("BufferedChannelFile") { public int testWrite(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(PAGE_SIZE); int checkSum = 0;for (long i = 0; i < FILE_SIZE; i++) { byte b = (byte)i; checkSum += b; buffer.put(b);if (!buffer.hasRemaining()) { buffer.flip(); channel.write(buffer); buffer.clear(); } }channel.close();return checkSum; }public int testRead(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); ByteBuffer buffer = ByteBuffer.allocate(PAGE_SIZE); int checkSum = 0;while (-1 != (channel.read(buffer))) { buffer.flip();while (buffer.hasRemaining()) { checkSum += buffer.get(); }buffer.clear(); }return checkSum; } },new PerfTestCase("MemoryMappedFile") { public int testWrite(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); MappedByteBuffer buffer = channel.map(READ_WRITE, 0, Math.min(channel.size(), MAX_VALUE)); int checkSum = 0;for (long i = 0; i < FILE_SIZE; i++) { if (!buffer.hasRemaining()) { buffer = channel.map(READ_WRITE, i, Math.min(channel.size() - i , MAX_VALUE)); }byte b = (byte)i; checkSum += b; buffer.put(b); }channel.close();return checkSum; }public int testRead(final String fileName) throws Exception { FileChannel channel = new RandomAccessFile(fileName, "rw").getChannel(); MappedByteBuffer buffer = channel.map(READ_ONLY, 0, Math.min(channel.size(), MAX_VALUE)); int checkSum = 0;for (long i = 0; i < FILE_SIZE; i++) { if (!buffer.hasRemaining()) { buffer = channel.map(READ_WRITE, i, Math.min(channel.size() - i , MAX_VALUE)); }checkSum += buffer.get(); }channel.close();return checkSum; } }, }; }Results 400MB file =========== RandomAccessFile write=379,610,750 read=1,452,482,269 bytes/sec RandomAccessFile write=294,041,636 read=1,494,890,510 bytes/sec RandomAccessFile write=250,980,392 read=1,422,222,222 bytes/sec RandomAccessFile write=250,366,748 read=1,388,474,576 bytes/sec RandomAccessFile write=260,394,151 read=1,422,222,222 bytes/sec BufferedStreamFile write=98,178,331 read=286,433,566 bytes/sec BufferedStreamFile write=100,244,738 read=288,857,545 bytes/sec BufferedStreamFile write=82,948,562 read=154,100,827 bytes/sec BufferedStreamFile write=108,503,311 read=153,869,271 bytes/sec BufferedStreamFile write=113,055,478 read=152,608,047 bytes/sec BufferedChannelFile write=228,443,948 read=356,173,913 bytes/sec BufferedChannelFile write=265,629,053 read=374,063,926 bytes/sec BufferedChannelFile write=223,825,136 read=1,539,849,624 bytes/sec BufferedChannelFile write=232,992,036 read=1,539,849,624 bytes/sec BufferedChannelFile write=212,779,220 read=1,534,082,397 bytes/sec MemoryMappedFile write=300,955,180 read=305,899,925 bytes/sec MemoryMappedFile write=313,149,847 read=310,538,286 bytes/sec MemoryMappedFile write=326,374,501 read=303,857,566 bytes/sec MemoryMappedFile write=327,680,000 read=304,535,315 bytes/sec MemoryMappedFile write=326,895,450 read=303,632,320 bytes/sec 8GB File ============ RandomAccessFile write=167,402,321 read=251,922,012 bytes/sec RandomAccessFile write=193,934,802 read=257,052,307 bytes/sec RandomAccessFile write=192,948,159 read=248,460,768 bytes/sec RandomAccessFile write=191,814,180 read=245,225,408 bytes/sec RandomAccessFile write=190,635,762 read=275,315,073 bytes/sec BufferedStreamFile write=154,823,102 read=248,355,313 bytes/sec BufferedStreamFile write=152,083,913 read=253,418,301 bytes/sec BufferedStreamFile write=133,099,369 read=146,056,197 bytes/sec BufferedStreamFile write=131,065,708 read=146,217,827 bytes/sec BufferedStreamFile write=132,694,052 read=148,116,004 bytes/sec BufferedChannelFile write=186,703,740 read=215,075,218 bytes/sec BufferedChannelFile write=190,591,410 read=211,030,680 bytes/sec BufferedChannelFile write=187,220,038 read=223,087,606 bytes/sec BufferedChannelFile write=191,585,397 read=221,297,747 bytes/sec BufferedChannelFile write=192,653,214 read=211,789,038 bytes/sec MemoryMappedFile write=123,023,322 read=231,530,156 bytes/sec MemoryMappedFile write=121,961,023 read=230,403,600 bytes/sec MemoryMappedFile write=123,317,778 read=229,899,250 bytes/sec MemoryMappedFile write=121,472,738 read=231,739,745 bytes/sec MemoryMappedFile write=120,362,615 read=231,190,382 bytes/sec Analysis For years I was a big fan of using RandomAccessFile directly because of the control it gives and the predictable execution. I never found using buffered streams to be useful from a performance perspective and this still seems to be the case.In more recent testing I’ve found that using NIO FileChannel and ByteBuffer are doing much better. With Java 7 the flexibility of this programming approach has been improved for random access with SeekableByteChannel.It seems that for reading RandomAccessFile and NIO do very well with Memory Mapped files winning for writes in some cases.I’ve seen these results vary greatly depending on platform. File system, OS, storage devices, and available memory all have a significant impact. In a few cases I’ve seen memory-mapped files perform significantly better than the others but this needs to be tested on your platform because your mileage may vary…A special note should be made for the use of memory-mapped large files when pushing for maximum throughput. I’ve often found the OS can become unresponsive due the the pressure put on the virtual memory sub-system.ConclusionThere is a significant difference in performance for the different means of doing sequential file IO from Java. Not all methods are even remotely equal. For most IO I’ve found the use of ByteBuffers and Channels to be the best optimised parts of the IO libraries. If buffered streams are your IO libraries of choice, then it is worth branching out and and getting familiar with the implementations of Channel and Buffer or even falling back and using the good old RandomAccessFile.Reference: Java Sequential IO Performance from our JCG partner Martin Thompson at the Mechanical Sympathy blog....
software-development-2-logo

5 Ways to Think Wisely in Development

Recently I have been reading some popular and interesting social psychology books. The contents are based on empirical evidence and scientific research, and often provide stories about how society operates, and why people behave the way they do. Some of the books in this genre include: Freakonomics, The Tipping Point, Outliers and KlugeThe most recent book I read is Kluge: The Haphazard Construction of the Human Mind, by Gary Marcus. Marcus argues that the human mind is not the elegantly designed organ that we conventionally perceive it as, rather it is a cobbled together contraption which is a product of evolution. He offers explanations on why our minds do clumsy things, such as forget where our car is parked, or why we can’t remember what we ate for breakfast.Without getting into the details, he points out several characteristics of the human brain that are products of evolution. Our cognitive makeup contains several bugs which can be referenced by psychological terms, some of which include: context driven memory, confirmation bias, motivated reasoning, and framing. (I’ll leave the explanation of these terms to the book itself.) He also gives recommendations on how to overcome these mental pitfalls. It is a fascinating for the laymen psychologist.So what does all this have to do with developing software? From Marcus’ exploration of the mind, I see several recommendations that can help us become better software developers. Many of the technical and social decisions we make as part of a software team are often afflicted by the “kluges” of the mind. Some basic and common sense tactics can help offset these imperfections, not to mention a help us becomes clearer thinkers, wiser developers, and better teammates.1. When possible, consider alternative hypotheses.Often when we have an idea, we get stuck on it and want to see it through to the finish, just for the satisfaction of feeling good about ourselves. It could be a design pattern we see for a problem, or it could be some performance enhancement we think needs done. We tend to not evaluate our own ideas in a dispassionate or objective way. One of the simplest things we can do to improve our capacity to think and come up with good solutions is to consider an alternative track. Contemplate on the opposite and counter your own initial ideas. This can go a long way on improving your own initial thoughts or could lead to an entirely better solution. 2. Imagine your decisions will be spot-checked.Research has shown that people who believe that they will have to justify their answers are less biased than people who don’t. Hold yourself accountable for any decisions you make, technical or otherwise. If we do this, we will tend to invest more cognitive effort and make correspondingly better decisions based on analysis, not just feelings or habits. A good practice would be to write down rationale for any sophisticated decision made and make sure the reasoning is sound. This could be notes for yourself, or published to the software team in a collaborative tool such as a wiki. 3. Always weigh benefits against costs.There is always some feature or tool that is cool to use or enticing to learn. We should always weigh the benefits versus the costs before we proceed down a certain route. The feature may be cool to the developers, but how much business value does it provide? Does it help the business save money? The new ORM tool looks great and has some added benefits, but what cost will it incur versus the technical savings?The inverse argument should be considered just as much. A refactoring may incur some cost to implement upfront, but will payoff in the long run by resulting in more maintainable and defect free code. The new integration testing tool may require a week of investment, but could reap dividends by allowing the team to write automated tests and eliminate the painstaking manual and repeated tests. Sometimes the initial pain is worth enduring to get a long term benefit.4. Whenever possible, don’t make important decisions when you are tired or have other things on your mind.Marcus describes how we have two portions of the brain: the reflexive and the deliberative. The reflexive portion of the brain evolved early on and controls our bodily motions. It also controls ours emotions and fight or flight responses. The deliberative portion of the brain is the most recently evolved and controls rational thinking and logic.When making decisions related to software, make sure you are well rested and not stressed. Get enough sleep and keep your hunger under control. When your health is not optimal, your reflexive portion of the brain activates and overrides the rational part. This inhibits rational thinking and can especially inhibit complicated problem solving. In order to make the best technical and team decisions, keep in a rested state to leverage the rational part of the mind.5. Distance yourself.Our mind is set up to ponder the near and defer future decisions for a later time. It’s always about the now and the urgency of the present. The release needs to be done immediately, and we get into fire fighter mode where everything is an emergency. Or…The debate is on about the new design and we must engage in the battle and win the argument!It’s always best to take a step back and distance yourself from the situation. Imagine you are watching from afar and try to judge the situation objectively. Of course, the here and now is always important, but it’s also important to balance situation by distancing yourself. Doing so will help assess the situation fairly. It can also let the reflexive portion of the brain simmer down and let the deliberative mind step in to take control when needed.Even though we are rational people in a technical field, we are human after all. We are products of our ancestors and emotions and rationality are both part of our makeup, although not always in the correct proportion. However, simple mindful steps can be taken to offset any shortcomings we have.Reference: 5 Ways to Think Wisely in Development from our JCG partner Nirav Assar at the Assar Java Consulting blog....
software-development-2-logo

Native vs Green threads

Native vs Green threads  Understanding a multi-threaded program have always been a wild goose chase for many programmers. There are always many aspects to consider when writing a multi-threaded program. Green threads vs Native Threads The difference between green threads vs native threads is something that programmers may be unaware of. Both are mechanisms are ways of achieving a ‘multi-threaded program’. It is the compiler / interpreter variants that usually implements green or native threads. Native threads uses the operating systems threading capability to execute multi-threaded programs on the other hand, the green threads emulates the multi-threading without using the underlying capabilities of the OS. Green threads are also known as ‘Cooperative Threading’ where each processes co-operate with each other to emulate a multi-threaded environment. Execution in a multi-core machines Another advantage of native threads is that multiple processes would execute in parallel in a multi-core machine. On the other hand, green threads are executed on a single core the entire time and it is the VM that gives a multi-threading notion. So actually there is only singe executing in case of green threads. Process Scheduling Native threads uses OS scheduling algorithm. Modern day OSes support pre-emptive scheduling. Green threads can use any kind of scheduling algorithm. Synchronization and Resource sharing Native threads usually have complicated synchronization and resource sharing. Multiple processes would require kernel level locks for synchronization. Synchronizations are pretty easier in case of green threads. Reference: Native vs Green threads from our JCG partner George Janeve at the Janeve.Me blog....
software-development-2-logo

5′ on IT-Architecture: root concepts explained by the pioneers of software architecture

The last couple of weeks I am working on a new software architecture course specifically for the insurance and financial sector. During the preparations I was reading many of the most cited articles on software architecture. The concepts described in these articles are so fundamental (and still up-to-date) that every architect really should to know about them. I have enjoyed reading such ‘old’ stuff. I first read most of the cited articles during my studies at university in the mid 90s. It is surprising to realize that, the longer you’re in this business, the more you agree to the ideas explained – in articles that were written 40 years ago! I’ve decided to qoute the original text passages – may be I thought it would be overbearing to explain it in my own words ;-) I hope you enjoy reading these text passages from the pioneers of software architecture. On the criteria for system decomposition ‘Many readers will now see what criteria were used in each decomposition. In the first decomposition the criterion used was to make each major step in the processing a module. One might say that to get the first decomposition one makes a flowchart. This is the most common approach to decomposition or modularization. It is an outgrowth of all programmer training which teaches us that we should begin with a rough flowchart and move from there to a detailed implementation. The flowchart was a useful abstraction for systems with on the order of 5,000-10,000 instructions, but as we move beyond that it does not appear to be sufficient; something additional is needed. The second decomposition was made using ‘information hiding’ as a criterion. The modules no longer correspond to steps in the processing. [...] Every module in the second decomposition is characterized by its knowledge of a design decision which it hides from all others. Its interface or definition was chosen to reveal as little as possible about its inner workings.’ in: On the Criteria To Be Used in Decomposing Systems into Modules, D.L. Parnas, 1972 On the information hiding design principle ‘Our module structure is based on the decomposition criterion known as information hiding [IH]. According to this principle, system details that are likely to change independently should be the secrets of separate modules; the only assumptions that should appear in the interfaces between modules are those that are considered unlikely to change. Each data structure is used in only one module; it may be directly accessed by one or more programs within the module but not by programs outside the module. Any other program that requires information stored in a module’s data structures must obtain it by calling access programs belonging to that module. Applying this principle is not always easy. It is an attempt to minimize the expected cost of software and requires that the designer estimate the likelihood of changes. Such estimates are based on past experience, and may require knowledge of the application area, as well as an understanding of hardware and software technology.’ in: The Modular Structure of Complex Systems, D.L. Parnas, 1985 On module hierarchies ‘In discussions of system structure it is easy to confuse the benefits of a good decomposition with those of a hierarchical structure. We have a hierarchical structure if a certain relation may be defined between the modules or programs and that relation is a partial ordering. The relation we are concerned with is ‘uses’ or ‘depends upon’. [...] The partial ordering gives us two additional benefits. First, parts of the system are benefited (simplified) because they use the services of lower levels. Second, we are able to cut off the upper levels and still have a usable and useful product. [...] The existence of the hierarchical structure assures us that we can ‘prune’ off the upper levels of the tree and start a new tree on the old trunk. If we had designed a system in which the ‘low level’ modules made some use of the ‘high level’ modules, we would not have the hierarchy, we would find it much harder to remove portions of the system, and ‘level’ would not have much meaning in the system.’ in: On the Criteria To Be Used in Decomposing Systems into Modules, D.L. Parnas, 1972 On the separation of concerns ‘Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one’s subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained —on the contrary!— by tackling these various aspects simultaneously. It is what I sometimes have called ‘the separation of concerns’, which, even if not perfectly possible, is yet the only available technique for effective ordering of one’s thoughts, that I know of. This is what I mean by ‘focussing one’s attention upon some aspect': it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect’s point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously.’ in: On the role of scientific thought, Edsger W. Dijkstra, 1974 On conceptual integrity ‘Such design coherence in a tool not only delights, it also yields ease of learning and ease of use. The tool does what one expects it to do. I argued [...] that conceptual integrity is the most important consideration in system design. Sometimes the virtue is called coherence, sometimes consistency, sometimes uniformity of style [...] The solo designer or artist usually produces works with this integrity subconsciously; he tends to make each microsdecision the same way each time he encounters it (barring strong reasons). If he fails to produce such integrity, we consider the work flawed, not great.’ in: The Design of Design, Frederick P. Brooks, 2010 (originally introduced in: The Mythical Man Month, 1975) Reference: 5′ on IT-Architecture: root concepts explained by the pioneers of software architecture from our JCG partner Niklas....
spring-logo

Getting Started with Spring Social – Part 2

A few weeks ago I wrote a post demonstrating what I thought was the simplest application you could write using Spring Social. This application read and displayed a Twitter user’s public data and was written as an introduction to Spring Social and the social coding arena. However, getting your application to display your user’s public data is only half the story and most of the time you’ll need to display your user’s private data. In this blog, I’m going to cover the scenario where you have a requirement to display a user’s Facebook or other Software as a Service (SaaS) provider data on one or two pages of your application. The idea here is to try to demonstrate the smallest and simplest thing you can to to add Spring Social to an application that requires your user to log in to Facebook or other SaaS provider. Creating the App To create the application, the first step is to create a basic Spring MVC Project using the template section of the SpringSource Toolkit Dashboard. This provides a webapp that’ll get you started. The next step is to set up the pom.xml by adding the following dependencies: <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-crypto</artifactId> <version>${org.springframework.security.crypto-version}</version> </dependency><!-- Spring Social --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-core</artifactId> <version>${spring-social.version}</version> </dependency> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-web</artifactId> <version>${spring-social.version}</version> </dependency> <!-- Facebook API --> <dependency> <groupId>org.springframework.social</groupId> <artifactId>spring-social-facebook</artifactId> <version>${org.springframework.social-facebook-version}</version> </dependency><!-- JdbcUserConfiguration --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${org.springframework-version}</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.159</version> </dependency><!-- CGLIB, only required and used for @Configuration usage: could be removed in future release of Spring --> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.2</version> </dependency> …obviously you’ll also need to add the following to the %lt;properties/> section of the file: <spring-social.version>1.0.2.RELEASE</spring-social.version> <org.springframework.social-facebook-version>1.0.1.RELEASE</org.springframework.social-facebook-version> <org.springframework.security.crypto-version>3.1.0.RELEASE</org.springframework.security.crypto-version> You’ll notice that I’ve added a specific pom entry for spring-security-crypto: this is because I’m using Spring 3.0.6. In Spring 3.1.x, this has become part of the core libraries. The only other point to note is that there is also a dependency on spring-jdbc and h2. This is because Spring’s UserConnectionRepository default implementation: JdbcUsersConnectionRepository uses them and hence they’re required even though this app doesn’t persist anything to a database (so far as I can tell). The Classes The social coding functionality consists of four classes (and one of those I’ve pinched from Keith Donald’s Spring Social Quick Start Sample code):FacebookPostsController SocialContext FacebookConfig UserCookieGeneratorFacebookPostsController is the business end of the application responsible for getting hold of the user’s Facebook data and pushing it into the model ready for display. @Controllerpublic class FacebookPostsController {private static final Logger logger = LoggerFactory.getLogger(FacebookPostsController.class);private final SocialContext socialContext;@Autowiredpublic FacebookPostsController(SocialContext socialContext) {this.socialContext = socialContext;}@RequestMapping(value = 'posts', method = RequestMethod.GET)public String showPostsForUser(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {String nextView;if (socialContext.isSignedIn(request, response)) {List<Post> posts = retrievePosts();model.addAttribute('posts', posts);nextView = 'show-posts';} else {nextView = 'signin';}return nextView;}private List<Post> retrievePosts() {Facebook facebook = socialContext.getFacebook();FeedOperations feedOps = facebook.feedOperations();List<Post> posts = feedOps.getHomeFeed();logger.info('Retrieved ' + posts.size() + ' posts from the Facebook authenticated user');return posts;}} As you can see, from a high-level viewpoint the logic of what we’re trying to achieve is pretty simple: IF user is signed in THEN read Facebook data, display Facebook data ELSE ask user to sign in when user has signed in, go back to the beginning END IF The FacebookPostsController delegates the task of handling the sign in logic to the SocialContext class. You can probably guess that I got the idea for this class from Spring’s really useful ApplicationContext. The idea here is that there is one class that’s responsible for gluing your application to Spring Social. public class SocialContext implements ConnectionSignUp, SignInAdapter {/*** Use a random number generator to generate IDs to avoid cookie clashes* between server restarts*/private static Random rand;/*** Manage cookies - Use cookies to remember state between calls to the* server(s)*/private final UserCookieGenerator userCookieGenerator;/** Store the user id between calls to the server */private static final ThreadLocal<String> currentUser = new ThreadLocal<String>();private final UsersConnectionRepository connectionRepository;private final Facebook facebook;public SocialContext(UsersConnectionRepository connectionRepository, UserCookieGenerator userCookieGenerator,Facebook facebook) {this.connectionRepository = connectionRepository;this.userCookieGenerator = userCookieGenerator;this.facebook = facebook;rand = new Random(Calendar.getInstance().getTimeInMillis());}@Overridepublic String signIn(String userId, Connection<?> connection, NativeWebRequest request) {userCookieGenerator.addCookie(userId, request.getNativeResponse(HttpServletResponse.class));return null;}@Overridepublic String execute(Connection<?> connection) {return Long.toString(rand.nextLong());}public boolean isSignedIn(HttpServletRequest request, HttpServletResponse response) {boolean retVal = false;String userId = userCookieGenerator.readCookieValue(request);if (isValidId(userId)) {if (isConnectedFacebookUser(userId)) {retVal = true;} else {userCookieGenerator.removeCookie(response);}}currentUser.set(userId);return retVal;}private boolean isValidId(String id) {return isNotNull(id) && (id.length() > 0);}private boolean isNotNull(Object obj) {return obj != null;}private boolean isConnectedFacebookUser(String userId) {ConnectionRepository connectionRepo = connectionRepository.createConnectionRepository(userId);Connection<Facebook> facebookConnection = connectionRepo.findPrimaryConnection(Facebook.class);return facebookConnection != null;}public String getUserId() {return currentUser.get();}public Facebook getFacebook() {return facebook;}} SocialContext implements Spring Social’s ConnectionSignUp and SignInAdapter interfaces. It contains three methods isSignedIn(), signIn(), execute(). isSignedIn is called by the FacebookPostsController class to implement the logic above, whilst signIn() and execute() are called by Spring Social. From my previous blogs you’ll remember that OAuth requires lots of trips between the browser, your app and the SaaS provider. In making these trips the application needs to save the state of several OAuth arguments such as: client_id, redirect_uri and others. Spring Social hides all this complexity from your application by mapping the state of the OAuth conversation to one variable that your webapp controls. This is the userId; however, don’t think of think of this as a user name because it’s never seen by the user, it’s just a unique identifier that links a number of HTTP requests to an SaaS provider connection (such as Facebook) in the Spring Social core. Because of its simplicity, I’ve followed Keith Donald’s idea of using cookies to pass the user id between the browser and the server in order to maintain state. I’ve also borrowed his UserCookieGenerator class from the Spring Social Quick Start to help me along. The isSignedIn(...) method uses UserCookieGenerator to figure out if the HttpServletRequest object contains a cookie that contains a valid user id. If it does then it also figures out if Spring Social’s UsersConnectionRepository contains a ConnectionRepository linked to the same user id. If both of these tests return true then the application will request and display the user’s Facebook data. If one of the two tests returns false, then the user will be asked to sign in. SocialContext has been written specifically for this sample and contains enough functionality to demonstrate what I’m talking about in this blog. This means that it’s currently a little rough and ready, though it could be improved to cover connections to any / many providers and then reused in different applications. The final class to mention is FacebookConfig, which is loosely based upon the Spring Social sample code. There are two main differences between this code and the sample code with the first of these being that the FacebookConfig class implements the InitializingBean interface. This is so that the usersConnectionRepositiory variable can be injected into the socialContext and in turn the socialContext can be injected into the usersConnectionRepositiory as its ConnectionSignUp implementation. The second difference is that I’m implementing a providerSignInController(...) method to provide a correctly configured ProviderSignInController object to be used by Spring Social to sign in to Facebook. The only change to the default I’ve made here is to set the ProviderSignInController’s postSignInUrl property to “ /posts”. This is the url of the page that will contain the users Facebook data and will be called once the user sign in is complete. @Configurationpublic class FacebookConfig implements InitializingBean {private static final Logger logger = LoggerFactory.getLogger(FacebookConfig.class);private static final String appId = '439291719425239';private static final String appSecret = '65646c3846ab46f0b44d73bb26087f06';private SocialContext socialContext;private UsersConnectionRepository usersConnectionRepositiory;@Injectprivate DataSource dataSource;/*** Point to note: the name of the bean is either the name of the method* 'socialContext' or can be set by an attribute** @Bean(name='myBean')*/@Beanpublic SocialContext socialContext() {return socialContext;}@Beanpublic ConnectionFactoryLocator connectionFactoryLocator() {logger.info('getting connectionFactoryLocator');ConnectionFactoryRegistry registry = new ConnectionFactoryRegistry();registry.addConnectionFactory(new FacebookConnectionFactory(appId, appSecret));return registry;}/*** Singleton data access object providing access to connections across all* users.*/@Beanpublic UsersConnectionRepository usersConnectionRepository() {return usersConnectionRepositiory;}/*** Request-scoped data access object providing access to the current user's* connections.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public ConnectionRepository connectionRepository() {String userId = socialContext.getUserId();logger.info('Createung ConnectionRepository for user: ' + userId);return usersConnectionRepository().createConnectionRepository(userId);}/*** A proxy to a request-scoped object representing the current user's* primary Facebook account.** @throws NotConnectedException* if the user is not connected to facebook.*/@Bean@Scope(value = 'request', proxyMode = ScopedProxyMode.INTERFACES)public Facebook facebook() {return connectionRepository().getPrimaryConnection(Facebook.class).getApi();}/*** Create the ProviderSignInController that handles the OAuth2 stuff and* tell it to redirect back to /posts once sign in has completed*/@Beanpublic ProviderSignInController providerSignInController() {ProviderSignInController providerSigninController = new ProviderSignInController(connectionFactoryLocator(),usersConnectionRepository(), socialContext);providerSigninController.setPostSignInUrl('/posts');return providerSigninController;}@Overridepublic void afterPropertiesSet() throws Exception {JdbcUsersConnectionRepository usersConnectionRepositiory = new JdbcUsersConnectionRepository(dataSource,connectionFactoryLocator(), Encryptors.noOpText());socialContext = new SocialContext(usersConnectionRepositiory, new UserCookieGenerator(), facebook());usersConnectionRepositiory.setConnectionSignUp(socialContext);this.usersConnectionRepositiory = usersConnectionRepositiory;}} Application Flow If you run this application 2 you’re first presented with the home screen containing a simple link inviting you to display your posts. The first time you click on this link, you’re re-directed to the /signin page. Pressing the ‘sign in’ button tells the ProviderSignInController to contact Facebook. Once authentication is complete, then the ProviderSignInController directs the app back to the /posts page and this time it displays the Facebook data. Configuration For completeness, I thought that I should mention the XML config, although there’s not much of it because I’m using the Spring annotation @Configuration on the FacebookConfig class. I have imported “ data.xml” from the Spring Social so that JdbcUsersConnectionRepository works and added <context:component-scan base-package='com.captaindebug.social' /> …for autowiring. Summary Although this sample app is based upon connecting your app to your user’s Facebook data, it can be easily modified to use any of the Spring Social client modules. If you like a challenge, try implementing Sina-Weibo where everything’s in Chinese – it’s a challenge, but Google Translate comes in really useful. 1 Spring Social and Other OAuth Blogs:Getting Started with Spring Social Facebook and Twitter: Behind the Scenes The OAuth Administration Steps OAuth 2.0 Webapp Flow Overview2 The code is available on Github at: https://github.com/roghughe/captaindebug.git Reference: Getting Started with Spring Social – Part 2 from our JCG partner Roger Hughes at the Captain Debug’s Blog blog....
mongodb-logo

MongoDB in 30 minutes

I have recently been bitten by the NoSQL bug – or as colleague of mine Mark Atwell coined “Burn the Where!” movement. While I have no intention of shunning friendly “SELECT … WHERE” anytime soon – or in foreseeable future, I did manage to get my hands dirty with some code. In this article I share the knowledge of my first attempts in NoSQL world. In this article we will aim to get a basic java application up and running that is capable of interacting with MongoDB. By itself that is not really a tall task and perhaps you could get that in under 10 minutes. Click here or click here or click here, for some excellent material. However, I wanted to push it a bit further. I want to add ORM support. I have chosen Morphia for this article. I also want to add DAO pattern, unit testing, and logging. In short, I want to it feel, “almost like” the kind of code that most of us would have written for enterprise applications using, let’s say Java, Hibernate and Oracle. And, we will try to do all this in under 30 minutes. My intention is to give a reassurance to Java + RDBMS developers that Java + NoSQL is not very alien. It is similar code and easy to try out. It is perhaps pertinent to add at this point that I have no affinity to NoSQL and no issues with RDBMS. I beieve they both have their own uses ( click here for some excellent material). As a technologist, I just like knowing my tools better so that I can do justice to my profession. This article is solely aimed at helping likeminded people to dip their toes in NoSQL. Ok, enought talk. Let’s get started. You will need a few softwares / tools before you follow this article. Download and install MongoDB server, if you have not already done so. I am assuming you have Java, some Java IDE and a build and release tool. I am using jdk 7, Eclipse (STS) and Maven 3 for this article. I start by creating a vanilla standard java application using Maven. I like using a batch file for this. File: codeRepo\MavenCommands.bat ECHO OFFREM ============================= REM Set the env. variables. REM ============================= SET PATH=%PATH%;C:\ProgramFiles\apache-maven-3.0.3\bin; SET JAVA_HOME=C:\ProgramFiles\Java\jdk1.7.0REM ============================= REM Create a simple java application. REM ============================= call mvn archetype:create ^ -DarchetypeGroupId=org.apache.maven.archetypes ^ -DgroupId=org.academy ^ -DartifactId=dbLayer002pause Import it in Eclipse. Use Maven to compile and run just to be sure. mvn -e clean install. This should compile the code and run the default tests as well. Once you have crossed this hurdle, now let’s get down to some coding. Let’s create an Entity object to start with. I think a Person class with fname would serve our purpose. I acknowledge that it is trivial but it does the job for a tutorial. File: /dbLayer002/src/main/java/org/academy/entity/Person.java package org.academy.entity;public class Person { private String fname;[...] }I have not mentioned the getters and setters for brevity. Now let us get the MongoDB java driver and attach it to the application. I like have Maven do this bit for me. You could obviously do this bit manually as well. Your choice. I am just lazy. File: /dbLayer002/pom.xml [...] <!-- MongDB java driver to hook up to MongoDB server --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.7.3</version> </dependency> [...]This will allow us to write a util class for connecting to MongoDB server instance. I am assuming you have a server up and running in your machine with default settings. File: /dbLayer002/src/main/java/org/academy/util/MongoUtil.java public class MongoUtil {private final static Logger logger = LoggerFactory .getLogger(MongoUtil.class);private static final int port = 27017; private static final String host = "localhost"; private static Mongo mongo = null;public static Mongo getMongo() { if (mongo == null) { try { mongo = new Mongo(host, port); logger.debug("New Mongo created with [" + host + "] and [" + port + "]"); } catch (UnknownHostException | MongoException e) { logger.error(e.getMessage()); } } return mongo; } }We will need logger setup in our application for this class to compile. Click here for my article around logging. All we need to do is to hook up Maven with the correct dependencies. File: /dbLayer002/pom.xml [...] <slf4j.version>1.6.1</slf4j.version> [...] <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> <scope>runtime</scope> </dependency> And also, we will need to specify, exactly what to log. File: /dbLayer002/src/java/resources/log4j.properties # Set root logger level to DEBUG and its only appender to A1. log4j.rootLogger=DEBUG, A1# configure A1 to spit out data in console log4j.appender.A1=org.apache.log4j.ConsoleAppender log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n At this point, you already have an Entity class and a utility class to hook up to the database. Ideally I would go about writing a DAO and then somehow use the ORM to join up the DAO with the database. However, Morphia has some excellent DAO support. Also it has some annotations to tie up the Entity with database elements. So, although I would have liked the Entity and DAO to be totally agnostic of the ORM and database, it is not the case here. I know on the face of it, it sounds like Morphia or MongoDB is forcing me to deviate from good code structure, let me hasten to add, that it is not any worse than other ORMs e.g. Hibernate with Annotations would have also forced me to make the same kind of compromise. So, let’s bring in Morphia in the picture. Enters the stage our ever helpful tool, Maven. A bit of an avoidable hitch here. When I was writing this document I could not get the version of Morphia that I wanted in the central Maven repository. So, I had to configure Maven to use the Morphia repository as well. Hopefully this is just a temporary situation. File: /dbLayer002/pom.xml [...] <!-- Required for Morphia --> <repositories> <repository> <id>Morphia repository</id> <url>http://morphia.googlecode.com/svn/mavenrepo/</url> </repository> </repositories> [...] <!-- Morphia - ORM for MongoDB --> <dependency> <groupId>com.google.code.morphia</groupId> <artifactId>morphia</artifactId> <version>0.98</version> </dependency> As I mentioned above, Morphia allows us to annotate the Entity class (much like Hibernate annotations). So, here is how the updated Entity class looks like. File: /dbLayer002/src/main/java/org/academy/entity/Person.java [...] @Entity public class Person { @Id private ObjectId id; [...]And now we can also add a DAO layer and lean on the BasicDAO that Morphia provides. File: /dbLayer002/src/main/java/org/academy/dao/PersonDAO.java public class PersonDAO extends BasicDAO<Person, ObjectId> {public PersonDAO(Mongo mongo, Morphia morphia, String dbName) { super(mongo, morphia, dbName); } [...]The beauty of the BasicDAO is that just by extending that, my own DAO class already has enough functionality to do the basic CRUD operations, although I have just added a constructor. Don’t believe it? Ok, lets write a test for that. File: /dbLayer002/src/test/java/org/academy/dao/PersonDAOTest.java public class PersonDAOTest { private final static Logger logger = LoggerFactory .getLogger(PersonDAOTest.class);private Mongo mongo; private Morphia morphia; private PersonDAO personDao; private final String dbname = "peopledb";@Before public void initiate() { mongo = MongoUtil.getMongo(); morphia = new Morphia(); morphia.map(Person.class); personDao = new PersonDAO(mongo, morphia, dbname); }@Test public void test() { long counter = personDao.count(); logger.debug("The count is [" + counter + "]");Person p = new Person(); p.setFname("Partha"); personDao.save(p);long newCounter = personDao.count(); logger.debug("The new count is [" + newCounter + "]");assertTrue((counter + 1) == newCounter); [...]As you might have already noticed. I have used JUnit 4. If you have been following this article as is till now you would have an earlier version of JUnit in your project. To ensure that you use JUnit 4, you just have to configure Maven to use that by adding the correct dependency in pom.xml. File: /dbLayer002/pom.xml <!-- Unit test. --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency>You are good to go. If you run the tests they should pass. Of course you could / should get into your database and check that the data is indeed saved. I will refer you to the MongoDB documentation which I think are quite decent. Last but not least, let me assure you that BasicDAO is not restrictive in any way. I am sure puritans would point out that if my DAO class needs to extend the BasicDAO that is a limitation on the source code structure anyway. Ideally should not have been required. And I agree with that. However, I also want show that for all practical purposes of DAO, you have sufficient flexibility. Let’s go on and add a custom find method to our DAO, that is specific to this Entity i.e. Person. Let’s say we want to be able to search on the basis of firstname and that we want to use regular expression for that. Here is how the code will look like. File: /dbLayer002/src/main/java/org/academy/dao/PersonDAO.java public class PersonDAO extends BasicDAO<Person, ObjectId> {[...] public Iterator<Person> findByFname(String fname){ Pattern regExp = Pattern.compile(fname + ".*", Pattern.CASE_INSENSITIVE); return ds.find(entityClazz).filter("fname", regExp).iterator(); } [...] } Important to reemphasize here that, I have just added a custom search function to my DAO, by adding precisely three lines of code (four if you add the last parentheses). In my books, that is quite flexible. Being true to my unflinching love for automated testing, lets add a quick test to check this functionality before we wrap up. File: /dbLayer002/src/test/java/org/academy/dao/PersonDAOTest.java [...] Iterator<Person> iteratorPerson = personDao.findByFname("Pa"); int personCounter = 0 ; while(iteratorPerson.hasNext()){ personCounter ++; logger.debug("["+personCounter+"]" + iteratorPerson.next().getFname()); } [...]Before you point out, yes, there are no assert() here, so this is not a real test. Let me assure you that my test class is indeed complete. It’s just that this snippet here does not have the assert function. So, that’s it. You have used Java to connect to a NoSQL database, using an ORM, through a DAO layer (where you have used the ORM’s functionalities and done some addition as well). You have also done proper logging and unit testing. Not bad use of half an hour, eh? Happy coding. Further readingA version of this article – slightly edited, is also available at this link at Javalobby.Reference: MongoDB in 30 minutes from our JCG partner Partho at the Tech for Enterprise 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