Posts Tagged ‘Java’

Rendering Global t:messages After Redirect

March 8th, 2010

A common problem when working with JSF is getting global info messages  via <t:messages globalOnly="true"> or <f:messages globalOnly="true"> to display messages set in the previous request when you have a <redirect/> in your faces-config for a particular page You will not see your <t:messages> that are set on the previous page.

The Problem

For instance, say you have two pages – page1.xhtml and page2.xhtml. In your faces-config.xml, you will have 2 entries.

<navigation-case>
	<from-outcome>page1</from-outcome>
	<to-view-id>/pages/page1.xhtml</to-view-id>
	<redirect/>
</navigation-case>
 
<navigation-case>
	<from-outcome>page2</from-outcome>
	<to-view-id>/pages/page2.xhtml</to-view-id>
	<redirect/>
</navigation-case>

Let’s say page1Bean is called in page1 and you want it to display messages in page2. So your bean would have something like this:

public class page1Bean {
	...
	public String page1Action{
		...
		/** Add message */
		FacesMessage facesMessage = new FacesMessage();
		...
		FacesContext.getCurrentInstance().addMessage(null, facesMessage);
		...
		return "page2";
	}
	...
}

Your page2.xhtml has like the following somewhere in it.

<t:messages globalOnly="true">

One would expect that this would display the message on the next page, however these messages are request scoped and so are not available in this second request and you do not see your message unless you remove the <redirect/> on page2.

Fortunately, there is a nifty and quick solution. Basically, it is a phase listener that saves the messages from the previous request and then restores them just before the RENDER_RESPONSE phase of the second request.

The Solution

To solve the problem, save the following class into some package where your faces-config will be able to access it

package com.myproject.web.jsf.phaselistener;
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
 
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
 
/**
 * Enables messages to be rendered on different pages from which they were set.
 * To produce this behaviour, this class acts as a <code>PhaseListener</code>.
 *
 * This is performed by moving the FacesMessage objects:
 *
	<li>After each phase where messages may be added, this moves the messages from
 * the page-scoped FacesContext to the session-scoped session map.
 *</li>
	<li>Before messages are rendered, this moves the messages from the session-scoped
 * session map back to the page-scoped FacesContext.
 *</li>
 * Only messages that are not associated with a particular component are ever
 * moved. These are the only messages that can be rendered on a page that is different
 * from where they originated.
 *
 * To enable this behaviour, add a <code>lifecycle</code> block to your
 * faces-config.xml file. That block should contain a single <code>phase-listener</code>
 * block containing the fully-qualified classname of this file.
 *
 * EDIT: This code was minimally modified by Max Kuipers to address some of the Java 1.6
 * compiler warnings.  All code was originally written by Jesse Wilson.
 *
 * @author <a href="mailto:jesse@odel.on.ca">Jesse Wilson</a>
 * @author <a href="mailto:mkuipers@sourceallies.com">Max Kuipers</a>
 */
 
public class MessageHandler implements PhaseListener {
	private static final long serialVersionUID = 1L;
 
	/**
	 * a name to save messages in the session under
	 */
	private static final String sessionToken = "MULTI_PAGE_MESSAGES_SUPPORT";
 
	/**
	 * Return the identifier of the request processing phase during which this
	 * listener is interested in processing PhaseEvent events.
	 */
	public PhaseId getPhaseId() {
		return PhaseId.ANY_PHASE;
	}
 
	/**
	 * Handle a notification that the processing for a particular phase of the
	 * request processing lifecycle is about to begin.
	 */
	public void beforePhase(PhaseEvent event) {
 
		if(event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
			FacesContext facesContext = event.getFacesContext();
			restoreMessages(facesContext);
		}
	}
 
	/**
	 * Handle a notification that the processing for a particular phase has just
	 * been completed.
	 */
	public void afterPhase(PhaseEvent event) {
 
		if(event.getPhaseId() == PhaseId.APPLY_REQUEST_VALUES ||
				event.getPhaseId() == PhaseId.PROCESS_VALIDATIONS ||
				event.getPhaseId() == PhaseId.INVOKE_APPLICATION) {
 
			FacesContext facesContext = event.getFacesContext();
			saveMessages(facesContext);
		}
 
	}
 
	/**
	 * Remove the messages that are not associated with any particular component
	 * from the faces context and store them to the user's session.
	 *
	 * @return the number of removed messages.
	 */
	private int saveMessages(FacesContext facesContext) {
		// remove messages from the context
		List messages = new ArrayList();
		for(Iterator i = facesContext.getMessages(null); i.hasNext(); ) {
			messages.add(i.next());
			i.remove();
		}
		// store them in the session
		if(messages.size() == 0) {
			return 0;
		}
		Map sessionMap = facesContext.getExternalContext().getSessionMap();
		// if there already are messages
		@SuppressWarnings("unchecked")
		List existingMessages = (List) sessionMap.get(sessionToken);
		if(existingMessages != null) {
			existingMessages.addAll(messages);
		}
		else {
			sessionMap.put(sessionToken, messages); // if these are the first messages
		}
 
		return messages.size();
	}
 
	/**
	 * Remove the messages that are not associated with any particular component
	 * from the user's session and add them to the faces context.
	 *
	 * @return the number of removed messages.
	 */
	private int restoreMessages(FacesContext facesContext) {
		// remove messages from the session
		Map sessionMap = facesContext.getExternalContext().getSessionMap();
		@SuppressWarnings("unchecked")
		List messages = (List)sessionMap.remove(sessionToken);
		// store them in the context
		if(messages == null) {
			return 0;
		}
		int restoredCount = messages.size();
		for(Iterator i = messages.iterator(); i.hasNext(); ) {
			facesContext.addMessage(null, i.next());
		}
 
		return restoredCount;
	}
}

And then add something like the following in your faces-config.xml. Be sure to replace the example package location with your own.

<lifecycle>
	<phase-listener>com.myproject.web.jsf.phaselistener.MessageHandler</phase-listener>
</lifecycle>

The forum post that documented this solution is here.

Environment Specific Properties in Spring

March 1st, 2010

On many occasions I want to be able to inject environment specific property values into my Spring managed beans. These may be things like web service endpoints, database URLs, etc. Values I know for each environment at build time, but I want to use the same WAR/EAR file in each environment. I would like to keep the actual values separate from the Spring config files themselves. And I would really like to manage a set of default values for each property, so that I do not need to specify a value for every property in every environment (ex. my credit card processing URL for dev, test, uat is the same, but for production it is different.)

» Read more: Environment Specific Properties in Spring

Replacing and Patching Java Application and Core classes

February 15th, 2010

Why would you ever need that?

Say you get a jar file. After using the jar for a while you realise that there is a bug in a class in the jar file. Unfortunately you also find out that the jar is no longer supported and there is no way you will get a fix from the author (who is long gone fishing).

In order to solve this issue, you first need to get the source of the class. If you are lucky enough and the author did not obfuscate the class file you can decompile it with a decompiler (my favourite one is JD-GUI).

» Read more: Replacing and Patching Java Application and Core classes

Keep your dataTable clean with a custom popup

January 13th, 2010

The basic idea is to output some data to a user in a table and allow them to take an action on each row individually. A fairly straightforward solution is to create a separate page to link to, passing the necessary row information along. If the action is simple enough, like a single checkbox, you could just embed the necessary component(s) in each row of the table. Too many components, however, can bloat the table and make the UI cumbersome to the user. Instead we can create a popup window to overlay our page, containing whatever components are needed, and activate it by a link embedded in our table. Passing the row information is a little trickier, but the result is a cleaner interface and a better user experience.
» Read more: Keep your dataTable clean with a custom popup

Spring’s refreshable beans

January 8th, 2010

A couple of days ago I found out about a really nice feature in Spring, called ‘refreshable bean’.

Spring’s vision a refreshable bean is a dynamic-language-backed bean that monitors changes to its source code and then reloads itself when changes occur. And it is all this is done without restarting/re-deploying entire app. Sweet!
» Read more: Spring’s refreshable beans

Musings of a SpringOne 2009 Attendee – Day 3

October 26th, 2009

Agile Architecture – Technologies and Patterns – Kirk Knoernschild

Some of the questions this session set out to attempt to answer were

  1. What is architecture?
  2. What defines architecture?
  3. What are architectural decisions?
  4. Is architecture a forward only decision?

Several definitions of Architecture were quoted from prior literature. Such as architecture being the the shared understanding of the system being built. Shared understanding between a group of people who need to communicate about it — developers and architects, or technical and management etc.
Lean principles are you delay » Read more: Musings of a SpringOne 2009 Attendee – Day 3

Musings of a SpringOne 2009 Attendee – Day 2

October 21st, 2009

Running a day late on my posts. Here’s day two (yesterday)

Grails Quick Start – David Klien

David walked through the creation of a Grails web application to track a JUG’s meeting schedule. I liked his presentation style or maybe because the room wasn’t very crowded things just registered better. Picked up a few tips such as the Bootstrap class. Grails still has a ways to go in the eclipse tooling. It would’ve been nice to have been able to File –> New Project and follow along. Too bad IntelliJIDEA CE doesn’t support grails though there has been plenty of buzz on the latest STS. Downloading this right now. Only 3 more hours for the download to complete!

I think I’m beginning to dig duck typing. All in all the presentation encouraged me to put my head down and hammer out a sample app to start building some grails knowledge. More homework! » Read more: Musings of a SpringOne 2009 Attendee – Day 2

Hands-on OSGi and Modular Web Applications – Part I – Toes First

October 19th, 2009

A Brief Introduction

This is the first in a series of blog posts that will attempt to demystify OSGi and demonstrate how it enables the creation of modular web applications. We will explore various aspects of the technology along with the challenges of using this technology. I encourage you to join in the discussion by posting any comments about your own experiences or challenges you have faced developing OSGi applications. We start with the assumption that we understand what OSGi is and the specific modularity problem it tries to solve. Here are some resources you can visit to read up on this.

  1. http://neilbartlett.name/blog/2008/06/06/what-is-osgi-for/ – this one talks about the problem space
  2. http://www.infoq.com/interviews/osgi-adrian-colyer – this one brings Spring and OSGi together

Turn on the ignition

Lets get started. This first post will show you how to launch an OSGi framework and how you can interact with it. You will first need to have a JDK installed. I recommend the Sun JDK. You then need an OSGi implementation. » Read more: Hands-on OSGi and Modular Web Applications – Part I – Toes First

Hibernate Criteria trick

October 8th, 2009

So here’s the situation.

Let’s say I have this query here:

SELECT * FROM employees
WHERE employee_id NOT IN ( 1234 , 3456 , 5678 );

How do we do that with the Hibernate Criteria object with a Restriction?  You would think that the Restrictions API would have a “not in” method, since it does have a not equals method(ne), but alas, there is nothing…

Well, here’s the solution:

//Create the criteria
Criteria crit = factory.getCurrentSession().createCriteria(Employee.class);
 
//add my restriction where idList is a list of emp ids that need to be excluded
crit.add(Restrictions.not(Restrictions.in("employeeId", idList)));
 
//get some results
List employees = crit.list();

There you go!  Now you know this neat little trick and you can use it in your own app… Be forewarned though, it can be slow…

Image Processing Using ImageMagick and JMagick

October 4th, 2009

Introduction to ImageMagick

ImageMagick® is a software suite to create, edit, and compose bitmap images. It can read, convert and write images in a variety of formats (over 100) including DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, and TIFF. Use ImageMagick to translate, flip, mirror, rotate, scale, shear and transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, ellipses and Bézier curves.

The functionality of ImageMagick is typically utilized from the command line. In this blog I am focussing on how to use Java with ImageMagick. There are two options available to use ImageMagick

1)      JMagick provides an object-oriented Java interface to ImageMagick which I am going to show in this blog.

2)      Calling the ImagicMagick directly as the Command line using Runtime.getRuntime().exec(command);

Jmagick

JMagick is an open source Java interface of ImageMagick. It is implemented in the form of Java Native Interface (JNI) into the ImageMagick API.

JMagick does not attempt to make the ImageMagick API object-oriented. It is merely a thin interface layer into the ImageMagick API.

Image Conversion using Jmagick

This function shows how to convert one file format to other format mainly I am focusing on PDF to TIFF conversion. Conversion of PDF into multiple page TIFF  or single page TIFF and also the function is also extensible for accepting Compression Format such as GROUP4, FAX or JPEG.

public void convert(File inputFile, File outputDirectory, ImageType outputType, boolean multiple) {
 
if (inputFile != null &amp;&amp; inputFile.exists() &amp;&amp; ImageUtil.isValidMime(inputFile)) {
 
try {
 
ImageInfo info = getImageInfo(inputFile);
 
String fileName = inputFile.getName();
 
fileName = inputFile.getName().split("\\.")[0];
 
if (multiple) {
 
MagickImage image = new MagickImage(info);
 
MagickImage[] imArray = image.breakFrames();
 
for (int i = 0; i &lt; imArray.length; i++) {
 
StringBuilder outputFile = new StringBuilder(outputDirectory.getAbsolutePath());
 
outputFile.append(File.separatorChar);
 
File file = new File(outputFile.toString());
 
imArray[i].setFileName(file.getAbsolutePath());
 
imArray[i].writeImage(info);
 
}
 
} else {
 
StringBuilder outputFile = new StringBuilder(outputDirectory.getAbsolutePath());
 
outputFile.append(File.separatorChar);
 
outputFile.append(fileName);
 
outputFile.append(".");
 
outputFile.append(outputType.name().toLowerCase());
 
File file = new File(outputFile.toString());
 
report.addOutputFile(file);
 
info.setAdjoin(1);
 
MagickImage image = new MagickImage(info);
 
image.setFileName(file.getAbsolutePath());
 
image.writeImage(info);
 
}
 
} catch (Exception e) {
 
e.printStackTrace();
 
}
 
}
 
}
 
private ImageInfo getImageInfo(File inputName) throws MagickException {
 
String density = this.getProperties().getProperty(IMAGEMAGIC_DENSITY, "300");
 
ImageInfo info = new ImageInfo(inputName.getAbsolutePath());
 
info.setDensity(density);
 
info.setCompression(CompressionType.Group4Compression);
 
info.setColorspace(ColorspaceType.RGBColorspace);
 
return info;
 
}