<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Michael Root's Blog</title>
	<atom:link href="http://mroot.serensystems.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://mroot.serensystems.com</link>
	<description>Integrated Open Souce Technology Solutions</description>
	<pubDate>Sun, 16 Nov 2008 08:01:32 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>JSF - Rendering Images stored in Database</title>
		<link>http://mroot.serensystems.com/?p=24</link>
		<comments>http://mroot.serensystems.com/?p=24#comments</comments>
		<pubDate>Mon, 03 Nov 2008 17:00:36 +0000</pubDate>
		<dc:creator>mroot</dc:creator>
		
		<category><![CDATA[JAVA]]></category>

		<category><![CDATA[JSF]]></category>

		<category><![CDATA[Spring]]></category>

		<category><![CDATA[Hibernate]]></category>

		<category><![CDATA[JPA]]></category>

		<category><![CDATA[RichFaces]]></category>

		<guid isPermaLink="false">http://mroot.serensystems.com/?p=24</guid>
		<description><![CDATA[by Michael Root

This article shows how to render images from data stored in the database to a JSF view.

This solution was created for the following environment, but will work in other configurations.

    * JavaServer Faces (JSF) 1.2
    * Richfaces 3.2.2.GA
    * SpringFramework 2.5.5
    * Spring Webflow 2.0.3
    * Hibernate 3.2.6.ga

Instead of storing the image data in the database one could store the images to an external directory. I have used external image directories in several projects but I find scalability and image management is more difficult. For performance, I always store image data in a separate table as will be shown later.]]></description>
			<content:encoded><![CDATA[<p>by Michael Root</p>
<p>This article shows how to render images from data stored in the database to a JSF view.</p>
<p>This solution was created for the following environment, but will work in other configurations.</p>
<ul>
<li>JavaServer Faces (JSF) 1.2</li>
<li>Richfaces 3.2.2.GA</li>
<li>SpringFramework 2.5.5</li>
<li>Spring Webflow 2.0.3</li>
<li>Hibernate 3.2.6.ga</li>
</ul>
<p>Instead of storing the image data in the database one could store the images to an external directory.  I have used external image directories in several projects but I find scalability and image management is more difficult. This post will describe how to perform image management using the database to store the images.</p>
<p><span id="more-24"></span></p>
<p><strong>UserImage - BaseDAOHibernateJPA - ImageManager</strong><br />
First it is necessary implement the code to retrieve the data from the database.  In our case we were using JPA with Hibernate so I will identify the UserImage entity class along with the DAO and ImageManager classes to achieve this functionality.</p>
<div class="geshi no html">
<div class="head">@Entity</div>
<ol>
<li class="li1">
<div class="de1">@Table(name = &quot;user_image&quot;)
</div>
</li>
<li class="li1">
<div class="de1">public class UserImage extends BaseObject {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private static final long serialVersionUID = 1410602442670943241L;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Id
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @GeneratedValue(strategy = GenerationType.AUTO)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Column(name = &quot;id&quot;)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private Long id;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Version
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private int version;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Enumerated(EnumType.STRING)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Column(name=&quot;image_type&quot;, nullable=false)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private ImageTypeEnum imageType = ImageTypeEnum.USER;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @ManyToOne(fetch=FetchType.LAZY)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @JoinColumn(name=&quot;user&quot;, nullable=false)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private User user;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Column(name=&quot;filename&quot;)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private String filename;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Column(name=&quot;filesize&quot;)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private long filesize;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Column(name=&quot;data&quot;, columnDefinition=&quot;mediumBlob&quot;)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private byte[] data;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Column(name=&quot;content_type&quot;)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private String contentType;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Column(name=&quot;created_on&quot;, updatable=false, insertable=true)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private Date createdOn;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public UserImage() {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; // Setters and Getters have been removed
</div>
</li>
<li class="li1">
<div class="de1">}</div>
</li>
</ol>
</div>
<p>The UserImage.data field has been mapped to a mediumBlob which is fine for MySQL.  For Oracle this would have to be changed to Blob.  I have also added a ImageType so that this table can be used to store different types of image data.</p>
<p>The following code segment displays the DAO base class which for our purposes is used to retrieve the UserImage data from the database through its CRUD operation getObject.</p>
<div class="geshi no html">
<div class="head">/**</div>
<ol>
<li class="li1">
<div class="de1">&nbsp;* This class serves as the Base class DAO JPA support.
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* Can be used for standard CRUD operations.
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;*
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* @author &lt;a href=&quot;mailto:mroot@serensystems.com&quot;&gt;Michael Root&lt;/a&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* @since August 31, 2008
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">@Repository(&quot;baseDAO&quot;)
</div>
</li>
<li class="li1">
<div class="de1">public class BaseDAOHibernateJPA implements DAO {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; protected final transient Log log = LogFactory.getLog(getClass());
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @PersistenceContext
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; protected EntityManager entityManager;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* @see com.serensys.golf.dao.DAO#saveObject( entity)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public &nbsp;T saveObject(T entity) throws DataAccessException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; return entityManager.merge(entity);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* @see com.serensys.golf.dao.DAO#getObject(Class, Object)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public &nbsp;T getObject(Class entityClass, Object primaryKey) throws DataAccessException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; T entity = entityManager.find(entityClass, primaryKey);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; if (entity == null) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new DataRetrievalFailureException(&quot;Entity could not be found by key=&quot; + primaryKey);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; return entity;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* @see com.serensys.golf.dao.DAO#removeObject(Object)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public void removeObject(Object entity) throws DataAccessException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; entityManager.remove(entity);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* @return the entityManager
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public EntityManager getEntityManager() {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; return entityManager;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* @param entityManager the entityManager to set
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public void setEntityManager(EntityManager entityManager) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; this.entityManager = entityManager;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">}</div>
</li>
</ol>
</div>
<p>The following class is the ImageManager that is called from the ImageDBServlet to retrieve the actual UserImage entity.</p>
<div class="geshi no html">
<div class="head">/**</div>
<ol>
<li class="li1">
<div class="de1">&nbsp;* Implementation of UserImage interface.
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;*
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* @author &lt;a href=&quot;mailto:mroot@serensystems.com&quot;&gt;Michael Root&lt;/a&gt;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* @since October 31, 2008
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">@Service(&quot;imageManager&quot;)
</div>
</li>
<li class="li1">
<div class="de1">public class ImageManagerImpl extends BaseManager implements ImageManager {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* @see com.serensys.golf.service.ImageManager#getUserImage(Long)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; @Transactional(readOnly = true)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public UserImage getUserImage(Long id) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; return this.baseDAO.getObject(UserImage.class, id);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">}</div>
</li>
</ol>
</div>
<p><strong>ImageDBServlet</strong><br />
The following servlet renders the image data to the output stream as shown in the class below.</p>
<div class="geshi no html">
<div class="head">/**</div>
<ol>
<li class="li1">
<div class="de1">&nbsp;* Special image servlet for efficiently resolving and rendering image resources from a database.
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;*
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;* @author Michael Root
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">public class ImageDBServlet extends HttpServletBean {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private static final long serialVersionUID = -8604559719271081403L;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private static final String HTTP_CONTENT_LENGTH_HEADER = &quot;Content-Length&quot;;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private static final String HTTP_LAST_MODIFIED_HEADER = &quot;Last-Modified&quot;;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private static final String HTTP_EXPIRES_HEADER = &quot;Expires&quot;;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private static final String HTTP_CACHE_CONTROL_HEADER = &quot;Cache-Control&quot;;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private boolean gzipEnabled = true;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private static ApplicationContext appContext = null;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private ImageManager imageManager;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private Set compressedMimeTypes = new HashSet();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; compressedMimeTypes.add(&quot;text/css&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; compressedMimeTypes.add(&quot;text/javascript&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* Method called by base class to allow subclass to initialize. &nbsp;The applicationContext
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* imageManager will be retrieved from the applicationContext.
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; protected void initServletBean() throws ServletException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; appContext = WebApplicationContextUtils.getWebApplicationContext(super.getServletContext());
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; if (appContext != null) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageManager = (ImageManager)appContext.getBean(&quot;imageManager&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; String rawResourcePath = request.getPathInfo();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; Long imageId = null;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; if (logger.isDebugEnabled()) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.debug(&quot;Attempting to GET resource: &quot; + rawResourcePath);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; // Get the index from the rawResourcePath
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; int idx = rawResourcePath.lastIndexOf(&quot;_&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; // If index &amp;gt; 0 then parse imageId
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; if (idx &amp;gt; -1) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String imageIdStr = rawResourcePath.substring(idx+1);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (logger.isDebugEnabled()) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.debug(&quot;doGet: imageIdStr: &quot; + imageIdStr);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageId = Long.parseLong(imageIdStr);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (logger.isDebugEnabled()) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.debug(&quot;doGet: imageId: &quot; + imageId);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; if (imageId == null || imageId.longValue() == 0) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (logger.isDebugEnabled()) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.debug(&quot;Resource not found: &quot; + rawResourcePath);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.sendError(HttpServletResponse.SC_NOT_FOUND);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; try {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; UserImage userImage = imageManager.getUserImage(imageId);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; prepareResponse(response, userImage);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OutputStream out = selectOutputStream(request, response);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InputStream in = new ByteArrayInputStream(userImage.getData());
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte[] buffer = new byte[1024];
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (in.available() &amp;gt; 0) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int len = in.read(buffer);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.write(buffer, 0, len);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } finally {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; in.close();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } finally {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.close();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; } finally {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private OutputStream selectOutputStream(HttpServletRequest request, HttpServletResponse response)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; String acceptEncoding = request.getHeader(&quot;Accept-Encoding&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; String mimeType = response.getContentType();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; if (gzipEnabled &amp;amp;&amp;amp; StringUtils.hasText(acceptEncoding) &amp;amp;&amp;amp; acceptEncoding.indexOf(&quot;gzip&quot;) &amp;gt; -1
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &amp;amp;&amp;amp; compressedMimeTypes.contains(mimeType)) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; logger.debug(&quot;Enabling GZIP compression for the current response.&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new GZIPResponseStream(response);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; } else {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return response.getOutputStream();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private void prepareResponse(HttpServletResponse response, UserImage userImage)
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; long lastModified = -1; &nbsp; &nbsp;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; response.setContentType(userImage.getContentType());
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; response.setHeader(HTTP_CONTENT_LENGTH_HEADER, Long.toString(userImage.getFilesize()));
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; response.setDateHeader(HTTP_LAST_MODIFIED_HEADER, lastModified);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; configureCaching(response, 31556926);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; /**
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* Set HTTP headers to allow caching for the given number of seconds.
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;* @param seconds number of seconds into the future that the response should be cacheable for
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp;*/
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private void configureCaching(HttpServletResponse response, int seconds) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; // HTTP 1.0 header
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; response.setDateHeader(HTTP_EXPIRES_HEADER, System.currentTimeMillis() + seconds * 1000L);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; // HTTP 1.1 header
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; response.setHeader(HTTP_CACHE_CONTROL_HEADER, &quot;max-age=&quot; + seconds);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; private class GZIPResponseStream extends ServletOutputStream {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; private ByteArrayOutputStream byteStream = null;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; private GZIPOutputStream gzipStream = null;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; private boolean closed = false;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; private HttpServletResponse response = null;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; private ServletOutputStream servletStream = null;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public GZIPResponseStream(HttpServletResponse response) throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; super();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; closed = false;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.response = response;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.servletStream = response.getOutputStream();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byteStream = new ByteArrayOutputStream();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gzipStream = new GZIPOutputStream(byteStream);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public void close() throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (closed) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IOException(&quot;This output stream has already been closed&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gzipStream.finish();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; byte[] bytes = byteStream.toByteArray();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.setContentLength(bytes.length);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; response.addHeader(&quot;Content-Encoding&quot;, &quot;gzip&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servletStream.write(bytes);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servletStream.flush();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; servletStream.close();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; closed = true;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public void flush() throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (closed) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IOException(&quot;Cannot flush a closed output stream&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gzipStream.flush();
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public void write(int b) throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (closed) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IOException(&quot;Cannot write to a closed output stream&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gzipStream.write((byte) b);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public void write(byte b[]) throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write(b, 0, b.length);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public void write(byte b[], int off, int len) throws IOException {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (closed) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new IOException(&quot;Cannot write to a closed output stream&quot;);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gzipStream.write(b, off, len);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public boolean closed() {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return (this.closed);
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; public void reset() {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // noop
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; public void setGzipEnabled(boolean gzipEnabled) {
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; this.gzipEnabled = gzipEnabled;
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; }
</div>
</li>
<li class="li1">
<div class="de1">}</div>
</li>
</ol>
</div>
<p>This code has implemented compression on the rendered image.  More importantly I have implemented caching which will be discussed when we talk about the usage.</p>
<p><strong>Configuration</strong><br />
In order to get the ImageServlet to work, add the following entries to the Web Deployment Descriptor web.xml:</p>
<div class="geshi no html">
<div class="head">ImageDB Servlet</div>
<ol>
<li class="li1">
<div class="de1">&nbsp; com.serensys.golf.webapp.servlets.ImageDBServlet
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; 0
</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; ImageDB Servlet
</div>
</li>
<li class="li1">
<div class="de1">&nbsp; /imagedb/*</div>
</li>
</ol>
</div>
<p><strong>Usage</strong><br />
The following code fragment shows the usage to display an image from the database</p>
<p>I am using the graphicImage from the JSF html library.  The user.version and user.userImageId are added to the url of the userImage.  The image is cached based on this name (e.g. userImage_1_23).  If the userImage data does not change the image will be pulled from the cache.  If the userImage data is changed the user.version property will be incremented and the userImage will be re-rendered with a new user.version.  I hope this article helps in creating a solution to render images from the database.</p>
]]></content:encoded>
			<wfw:commentRss>http://mroot.serensystems.com/?feed=rss2&amp;p=24</wfw:commentRss>
		</item>
		<item>
		<title>Developing a Lightweight DND Portal</title>
		<link>http://mroot.serensystems.com/?p=23</link>
		<comments>http://mroot.serensystems.com/?p=23#comments</comments>
		<pubDate>Thu, 14 Feb 2008 07:07:05 +0000</pubDate>
		<dc:creator>mroot</dc:creator>
		
		<category><![CDATA[JAVA]]></category>

		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://mroot.serensystems.com/?p=23</guid>
		<description><![CDATA[Many web sites have this drag-n-drop portal management feature like the home page for iGoogle.  Google created their Google Gadgets that are simple HTML and JavaScript mini-applications served in iFrames that can be embedded in webpages and other apps.
Although there are several technologies available that one could use to develop this functionality within their [...]]]></description>
			<content:encoded><![CDATA[<p>Many web sites have this drag-n-drop portal management feature like the home page for iGoogle.  Google created their Google Gadgets that are simple HTML and JavaScript mini-applications served in iFrames that can be embedded in webpages and other apps.</p>
<p>Although there are several technologies available that one could use to develop this functionality within their web application, this article will focus on requirements, technology alternatives and in latter posts I will develop this technology with our chose technology alternative.</p>
<h3>Requirements:</h3>
<ol>
<li>Drag - and - Drop AJAX functionality which allows customization for logged on users.</li>
<li>There will be a fixed number of components that can be displayed.</li>
<li>Each component has its own display and controller for handling requests.  All components are developed to a standard interface.</li>
<li>Each component has a wrapper that contains a title bar and menu.</li>
</ol>
<h3>Technology Alternatives:</h3>
<ol>
<li>JSR 168 / 268 Solution</li>
<li>Utilize YUI Drag &amp; Drop Component</li>
<li>Utilize Google Web Toolkit (GWT) with  DND extensions by Allen Sauer</li>
</ol>
<p>The JSR 168 defines a Java Portlet Specification that defines a contract between the portlet container and portlets and provides a convenient programming model for portlet developers.  There are many commercial and open source portal servers:</p>
<h4>Commercial Portal Servers:</h4>
<ul>
<li>IBM WEbSphere</li>
<li>Sun Java System Portal Server</li>
<li>BEA Weblogic</li>
<li>Oracle iAS</li>
<li>Liferay</li>
<li>Vignette</li>
<li>SAP</li>
<li>TIBCO</li>
<li>uPortal</li>
<li>OpenPortal</li>
</ul>
<h4>Open Source Portal Servers:</h4>
<ul>
<li>JBoss Enterprise Portal Platform</li>
<li>Apache Pluto</li>
<li>JetSpeed Portal</li>
<li>eXo Platform Portal</li>
</ul>
<p>The JSR 168 standard is an overkill to our solution and require s a full blown portal server which is not what we are looking for.</p>
<p>YUI has some amazing components and I use these on several web sites.  They have a Drag &amp; Drop component that could be used but from my experience this control would only give me a partial solution which then would require modification of the YUI javascript.  I don&#8217;t mind tweaking 3rd party components but this would require major modification to achieve our requirements.</p>
<p>From my initial research I believe the only alternative would be to develop a component using GWT.   Future articles will describe the development of this component that we will call PortLight.</p>
]]></content:encoded>
			<wfw:commentRss>http://mroot.serensystems.com/?feed=rss2&amp;p=23</wfw:commentRss>
		</item>
		<item>
		<title>Maven 2 Life Cycle</title>
		<link>http://mroot.serensystems.com/?p=8</link>
		<comments>http://mroot.serensystems.com/?p=8#comments</comments>
		<pubDate>Wed, 13 Dec 2006 06:30:12 +0000</pubDate>
		<dc:creator>mroot</dc:creator>
		
		<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://mroot.serensystems.com/?p=8</guid>
		<description><![CDATA[This post contains information helpful in using maven 2.0.  Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project&#8217;s build, reporting and documentation from a central piece of information.
Maven’s Default Build Life Cycle


validate
Validate the project is correct and all necessary [...]]]></description>
			<content:encoded><![CDATA[<p>This post contains information helpful in using maven 2.0.  Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project&#8217;s build, reporting and documentation from a central piece of information.</p>
<h3>Maven’s Default Build Life Cycle</h3>
<table border="1">
<tr>
<td><strong>validate</strong></td>
<td>Validate the project is correct and all necessary information is available.</td>
</tr>
<tr>
<td><strong>initialize</strong></td>
<td>Initialize the build process.</td>
</tr>
<tr>
<td><strong>generate-sources</strong></td>
<td>Generate any source code for inclusion in compilation.</td>
</tr>
<tr>
<td><strong>process-sources</strong></td>
<td>Process the source code, for example to filter any values.</td>
</tr>
<tr>
<td><strong>generate-resources</strong></td>
<td>Generate resources for inclusion in the package.</td>
</tr>
<tr>
<td><strong>process-resources</strong></td>
<td>Copy and process the resources into the destination directory, ready for packaging.</td>
</tr>
<tr>
<td><strong>compile</strong></td>
<td>Compile the source code of the project.</td>
</tr>
<tr>
<td><strong>process-classes</strong></td>
<td>Post-process the generated files from compilation, for example to do byte code enhancement on Java classes.</td>
</tr>
<tr>
<td><strong>generate-test-sources</strong></td>
<td>Create resources for testing.</td>
</tr>
<tr>
<td><strong>process-test-sources</strong></td>
<td>Process the test source code, for example to filter any values.</td>
</tr>
<tr>
<td><strong>generate-test-resources</strong></td>
<td>Create resources for testing.</td>
</tr>
<tr>
<td><strong>process-test-resources</strong></td>
<td>Copy and process the resources into the test destination directory.</td>
</tr>
<tr>
<td><strong>test-compile</strong></td>
<td>Compile the test source code into the test destination directory test Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.</td>
</tr>
<tr>
<td><strong>test</strong></td>
<td>Run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.</td>
</tr>
<tr>
<td><strong>package</strong></td>
<td>Take the compiled code and package it in its distributable format, such as a JAR.</td>
</tr>
<tr>
<td><strong>pre-integration-test</strong></td>
<td>Perform actions required before integration tests are executed. This may involve things such as setting up the required environment.</td>
</tr>
<tr>
<td><strong>integration-test</strong></td>
<td>Process and deploy the package if necessary into an environment where integration tests can be run.</td>
</tr>
<tr>
<td><strong>post-integration-test</strong></td>
<td>Perform actions required after integration tests have been executed. This may including cleaning up the environment.</td>
</tr>
<tr>
<td><strong>verify</strong></td>
<td>Run any checks to verify the package is valid and meets quality criteria.</td>
</tr>
<tr>
<td><strong>install</strong></td>
<td>Install the package into the local repository, for use as a dependency in other projects locally.</td>
</tr>
<tr>
<td><strong>deploy</strong></td>
<td>Done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.</td>
</tr>
</table>
<p><span class="article_seperator"><br />
</span></p>
]]></content:encoded>
			<wfw:commentRss>http://mroot.serensystems.com/?feed=rss2&amp;p=8</wfw:commentRss>
		</item>
		<item>
		<title>AOP Definitions</title>
		<link>http://mroot.serensystems.com/?p=7</link>
		<comments>http://mroot.serensystems.com/?p=7#comments</comments>
		<pubDate>Sun, 08 Oct 2006 06:24:02 +0000</pubDate>
		<dc:creator>mroot</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://mroot.serensystems.com/?p=7</guid>
		<description><![CDATA[Aspect-Oriented Programming (AOP) complements OOP by providing another way of thinking about program structure. While OO decomposes applications into a hierarchy of objects, AOP decomposes programs into aspects or concerns. This enables modularization of concerns such as transaction management that would otherwise cut across multiple objects. (Such concerns are often termed crosscutting concerns.)
AOP Concepts
There are [...]]]></description>
			<content:encoded><![CDATA[<p>Aspect-Oriented Programming (AOP) complements OOP by providing another way of thinking about program structure. While OO decomposes applications into a hierarchy of objects, AOP decomposes programs into aspects or concerns. This enables modularization of concerns such as transaction management that would otherwise cut across multiple objects. (Such concerns are often termed crosscutting concerns.)</p>
<h2>AOP Concepts</h2>
<p>There are two distinct types of AOP:</p>
<ul>
<li><strong>static: </strong>crosscutting logic is applied to your code at compile time, and you cannot change it without modifying the code and recompiling. <a href="http://eclipse.org/aspectj">Aspectj</a> provides this type of implementation.</li>
<li><strong>dynamic: </strong>With dynamic AOP, like spring AOP, crosscutting logic is applied dynamically, at runtime.</li>
</ul>
<p>These types of AOP are complementary and, when used together, they form a powerful combination that you can use in your applications.In defining the copcepts of AOP the definitions that I use will be SpringFramwork centric.</p>
<ul>
<li><strong>Aspect</strong>: A modularization of a concern for which the implementation might otherwise cut across multiple objects. Transaction management is a good example of a crosscutting concern in J2EE applications. Aspects are implemented using Spring as Advisors or interceptors.</li>
<li><strong>Joinpoint</strong>: Point during the execution of a program, such as a method invocation or a particular exception being thrown. In Spring AOP, a joinpoint is always method invocation. Spring does not use the term joinpoint prominently; joinpoint information is accessible through methods on the MethodInvocation argument passed to interceptors, and is evaluated by implementations of the org.springframework.aop.Pointcut interface.</li>
<li><strong>Advice</strong>: Action taken by the AOP framework at a particular joinpoint. Different types of advice include &#8220;around,&#8221; &#8220;before&#8221; and &#8220;throws&#8221; advice. Advice types are discussed below. Many AOP frameworks, including Spring, model an advice as an interceptor, maintaining a chain of interceptors &#8220;around&#8221; the joinpoint.</li>
<li><strong>Pointcuts</strong>: Are predicates determining which joinpoints a piece of advice should apply to. It&#8217;s more intuitive &#8212; although not entirely accurate &#8212; to think of a pointcut as a set of jointponts. Pointcuts identify where advice should apply. Thye majic of AOP lies more in the specification of where action should be taken (pointcut) than what action to apply (advice).</li>
</ul>
<h3>Spring Advice Types</h3>
<ul>
<li><strong>Around Advice</strong>: Advice that surrounds a joinpoint such as a method invocation. This is the most powerful kind of advice. Around advices will perform custom behavior before and after the method invocation. They are responsible for choosing whether to proceed to the joinpoint or to shortcut executing by returning their own return value or throwing an exception.</li>
<li><strong>Before Advice</strong>: Advice that executes before a joinpoint, but which does not have the ability to prevent execution flow proceeding to the joinpoint (unless it throws an exception).</li>
<li><strong>After Returning Advice</strong>: is invoked when a method returns successfully, without throwing an exception. As with before advice, the return type is void; after returning advices are not intended to change the return value.</li>
<li><strong>Throws Advice</strong>: Advice to be executed if a method throws an exception. Spring provides strongly typed throws advice, so you can write code that catches the exception (and subclasses) you&#8217;re interested in, without needing to cast from Throwable or Exception.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://mroot.serensystems.com/?feed=rss2&amp;p=7</wfw:commentRss>
		</item>
		<item>
		<title>DarwinPorts to Install Apache2 and PHP5</title>
		<link>http://mroot.serensystems.com/?p=6</link>
		<comments>http://mroot.serensystems.com/?p=6#comments</comments>
		<pubDate>Sun, 09 Jul 2006 06:19:26 +0000</pubDate>
		<dc:creator>mroot</dc:creator>
		
		<category><![CDATA[MAC OSX]]></category>

		<guid isPermaLink="false">http://mroot.serensystems.com/?p=6</guid>
		<description><![CDATA[This post discusses the installation of Apache 2.2.2and PHP 5.1.4 on Mac OS X 10.4.7. Initially I tried to build the open source applications and install but after a few attempts I decided to use DarwinPorts to automatically build and install these two applications.This weekend I decided to upgrade my apache and php versions on [...]]]></description>
			<content:encoded><![CDATA[<p>This post discusses the installation of Apache 2.2.2and PHP 5.1.4 on Mac OS X 10.4.7. Initially I tried to build the open source applications and install but after a few attempts I decided to use DarwinPorts to automatically build and install these two applications.This weekend I decided to upgrade my apache and php versions on my MacBook to the latest version. I searched the web for any existing articles regarding this upgrade and came across the following article:</p>
<p><a href="http://www.phpmac.com/articles.php?view=252" target="_blank">Building and Installing Apache 2.2.2 and PHP 5.1.4 on Mac OS X 10.4.6</a></p>
<p>I had no problem building and installing Apache 2.2.2, at least after I installed XTools from the OS X development disk. During the make of PHP there was an issue with dependency. After doing more research others having the same problem had to buid php with mySQL 4.x instead of 5.x. I decided to utilize <a href="http://darwinports.opendarwin.org/">DarwinPorts</a> to build and install the open source software.</p>
<p>I downloaded and installed DarwinPorts-1.2.1.  After DarwinPorts was install I peformed the following steps to install apache2:</p>
<ol>
<li>Build and install Apache2.
<pre>sudo port install apache2</pre>
</li>
<li>Create a default conf file for apache.
<pre>cd /opt/local/apache2/conf
sudo cp httpd.conf.sample httpd.conf</pre>
</li>
<li>Start apache2 on startup.
<pre>sudo launchctl load -w /Library/LaunchDaemons/org.darwinports.apache2.plist</pre>
</li>
</ol>
<p>When apache2 is installed the default DocumentRoot is <em>/opt/local/apache2/htdocs/</em>.  I modified the DocumentRoot to point back to the default OS X location of <em>/Library/WebServer/Documents/</em>.</p>
<p>I would refer to the apache2 documentation to configure the <strong>httpd.conf</strong> according to your requirements.</p>
<p>To start apache2 execute the followng command:</p>
<pre>sudo /opt/local/apache2/bin/apachectl -k start</pre>
<p>The following steps were followed to install php5.</p>
<ol>
<li>Install wget which is required by php5.
<pre>sudo port install wget</pre>
</li>
<li>Build and install php5.
<pre>sudo port install php5 +apache2 +mysql4</pre>
</li>
<li>Register PHP with Apache.
<pre>cd /opt/local/apache2/modules
/opt/local/apache2/bin/apxs -a -e -n "php5" libphp5.so</pre>
</li>
<li>Create php.ini file
<pre>cp /opt/local/etc/php.ini-dist to  /opt/local/etc/php.ini</pre>
</li>
</ol>
<p>One other article was useful in installing apache2 using DarwinPorts:  <a href="http://wiki.opendarwin.org/index.php/DarwinPorts:MAMP#Install_Apache" target="_blank">DarwinPorts:MAMP</a><br />
I hope this post helps in setting up apache2 and php5.</p>
]]></content:encoded>
			<wfw:commentRss>http://mroot.serensystems.com/?feed=rss2&amp;p=6</wfw:commentRss>
		</item>
		<item>
		<title>JAXB</title>
		<link>http://mroot.serensystems.com/?p=5</link>
		<comments>http://mroot.serensystems.com/?p=5#comments</comments>
		<pubDate>Wed, 07 Jun 2006 06:14:38 +0000</pubDate>
		<dc:creator>mroot</dc:creator>
		
		<category><![CDATA[JAVA]]></category>

		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://mroot.serensystems.com/?p=5</guid>
		<description><![CDATA[The JavaTM Architecture for XML Binding (JAXB) provides an API and tools that automate the mapping between XML documents and Java objects.
The JAXB framework enables developers to perform the following operations:

Unmarshal XML content into a Java representation
Access and update the Java representation
Marshal the Java representation of the XML content into XML content

JAXB gives Java developers [...]]]></description>
			<content:encoded><![CDATA[<p>The JavaTM Architecture for XML Binding (JAXB) provides an API and tools that automate the mapping between XML documents and Java objects.</p>
<p>The JAXB framework enables developers to perform the following operations:</p>
<ol>
<li>Unmarshal XML content into a Java representation</li>
<li>Access and update the Java representation</li>
<li>Marshal the Java representation of the XML content into XML content</li>
</ol>
<p>JAXB gives Java developers an efficient and standard way of mapping between XML and Java code. Java developers using JAXB are more productive because they can write less code themselves and do not have to be experts in XML. JAXB makes it easier for developers to extend their applications with XML and Web Services technologies.</p>
]]></content:encoded>
			<wfw:commentRss>http://mroot.serensystems.com/?feed=rss2&amp;p=5</wfw:commentRss>
		</item>
		<item>
		<title>Extending Acegi Security</title>
		<link>http://mroot.serensystems.com/?p=4</link>
		<comments>http://mroot.serensystems.com/?p=4#comments</comments>
		<pubDate>Mon, 10 Apr 2006 05:25:10 +0000</pubDate>
		<dc:creator>mroot</dc:creator>
		
		<category><![CDATA[JAVA]]></category>

		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://mroot.serensystems.com/?p=4</guid>
		<description><![CDATA[This article shows how to add several security enhancements to a web application that is utilizing Acegi Security. These security enhancements include:

How to add funcitonality to force the user to change thier password on thier first login
After a selected number of failed login attempts the system will temporarily lock the user account for a pre-determined [...]]]></description>
			<content:encoded><![CDATA[<p>This article shows how to add several security enhancements to a web application that is utilizing Acegi Security. These security enhancements include:</p>
<ul>
<li>How to add funcitonality to force the user to change thier password on thier first login</li>
<li>After a selected number of failed login attempts the system will temporarily lock the user account for a pre-determined amount of time</li>
<li>Not allow the user to re-use a pe-selected number of previous passwords that are stored in a password history.</li>
</ul>
<p><span id="more-4"></span></p>
<h3>Acegi Security Fundamentals</h3>
<p>Acegi Security provides comprehensive security services for J2EE-based enterprise software applications. There is a particular emphasis on supporting projects built using The Spring Framework, which is the leading J2EE solution for enterprise software development. If you&#8217;re not using Spring for developing enterprise applications, we warmly encourage you to take a closer look at it. Some familiarity with Spring - and in particular dependency injection principles - will help you get up to speed with Acegi Security more easily.</p>
<p>To help understand this article I will explain some of Acegi security fundamentals.</p>
<p><strong> SecurityContextHolder - </strong>This is where the details of the present security context of the application is stored, which includes details of the principal currently using the application. By default the SecurityContextHolder uses a ThreadLocal to store these details, which means that the security context is always available to methods in the same thread of execution, even if the security context is not explicitly passed around as an argument those methods.</p>
<p>Inside the SecurityContextHolder we store details of the principal currently interacting with the application. Acegi Security uses an Authentication object to represent this information. You won&#8217;t normally need to create an Authentication object yourself, it is fairly common for users to query the Authentication object.<br />
You can use the following code block - from anywhere in your application - to do this:</p>
<pre>
Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

if (obj instanceof UserDetails) {

   String username = ((UserDetails)obj).getUsername();

} else {

   String username = obj.toString();

}</pre>
<p>As the above code indicates the principal can be a username (String) or an object then implements the UserDeails interface. In our application we use the latter approach.</p>
<p><strong>SecurityContext</strong> - Holds the Authentication and possibly request-specific security information.<br />
<strong>HttpSessionContextIntegrationFilter</strong> - Stores the SecurityContext in the HttpSession between web requests.<br />
<strong>Authentication</strong> - Represents the principal in an Acegi Security-specific manner.<br />
<strong>GrantedAuthority</strong> - Reflects the application-wide permissions granted to a principal.<br />
<strong>UserDetails</strong> - to provide the necessary information to build an Authentication object from your application&#8217;s DAOs.<br />
<strong>UserDetailsService</strong> - Creates a UserDetails when passed in a String-based username (or certificate ID or alike).<br />
<strong>Filters</strong> - Acegi Security uses many filters. You have a choice in how these filters are added to your web application, in that you can use either FilterToBeanProxy or FilterChainProxy. In my example application I use FilterChainProxy, which is configured through the web.xml as:</p>
<pre>
    &lt;filter&gt;
        &lt;filter-name&gt;securityFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;org.acegisecurity.util.FilterToBeanProxy&lt;/filter-class&gt;
        &lt;init-param&gt;
            &lt;param-name&gt;targetClass&lt;/param-name&gt;
            &lt;param-value&gt;org.acegisecurity.util.FilterChainProxy&lt;/param-value&gt;
        &lt;/init-param&gt;
    &lt;/filter&gt;</pre>
<p>Notice that the filter in web.xml is actually a FilterToBeanProxy, and not the filter that will actually implement the logic of the filter. What FilterToBeanProxy does is delegate the Filter&#8217;s methods through to a bean which is obtained from the Spring application context. This enables the bean to benefit from the Spring application context lifecycle support and configuration flexibility. The bean must implement javax.servlet.Filter. The FilterToBeanProxy only requires a single initialization parameter, targetClass or targetBean. The targetClass parameter locates the first object in the application context of the specified class, whilst targetBean locates the object by bean name. Like standard Spring web applications, the FilterToBeanProxy accesses the application context via WebApplicationContextUtils.getWebApplicationContext(ServletContext), so you should configure a ContextLoaderListener in web.xml.In our sample application the FilterChainProxy is defined as follows:</p>
<pre>
    &lt;bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"&gt;
        &lt;property name="filterInvocationDefinitionSource"&gt;
            &lt;value&gt;
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /remoting/**=httpSessionContextIntegrationFilterWithASCFalse,
			basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
		/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
			remoteUserFilter,anonymousProcessingFilter,concurrentSessionFilter,
			exceptionTranslationFilter,passwordChangeFilter,vendorSetupFilter,
			filterInvocationInterceptor
            &lt;/value&gt;
        &lt;/property&gt;
    &lt;/bean&gt;</pre>
<p>The above declarations will cause every web request to be passed through to Acegi Security&#8217;s FilterChainProxy. As explained in the filters section of the Acegi reference guide, the FilterChainProxy is a generally-useful class that enables web requests to be passed to different filters based on the URL patterns. Those delegated filters are managed inside the application context, so they can benefit from dependency injection.We are now ready to discuss the the security enhancements listed in the introduction.</p>
<h3>Force the user to change password on first login</h3>
<p>This requirement ensures that the user changes the password after the account is created. But this functionality can be expanded to force the user to change their password at specified intervals.</p>
<p>DaoAuthenticationProvider returns an Authentication object which in turn has its principal property set. The principal will be either a String (which is essentially the username) or a UserDetails object (which was looked up from the UserDetailsService). By default the UserDetails is returned, as this enables applications to add extra properties potentially of use in applications, such as the user&#8217;s full name, email address etc. If using container adapters, or if your applications were written to operate with Strings (as was the case for releases prior to Acegi Security 0.6), you should set the DaoAuthenticationProvider.forcePrincipalAsString<br />
property to true in your application context.</p>
<p>In our sample application we are returning a user object that implements the UserDetails interface. We added the boolean property passwordChangeRequired to the user object to indicate if a password change is required.</p>
<p>The next step will be to add a filter that will direct the user to the change password page. This will be handled by adding a changePasswordFilter that intercepts all requests. This filter will redirect the request to the changePassword jsp page if the passwordChangeRequired flag is set on the user object.</p>
<p>The diagram below displays a simple login flow:</p>
<p>The passwordChangeFilter will have to be robust enough to avoid recursion and avoid redirect if the logout page is being displayed.</p>
<p>The setting of the User.passwordChangeRequired property can be defaulted to true so that all users added to the system will be required to have their password changed. This works great if an admin is adding users to the system but may not be desired if the users are registering themselves. Clearng of the User.passwordChangeRequired property is handled thorugh the changePasswordController which is a standard Model-View-Controller (MVC) that handles setting the user password and clearing this User.passwordChangeRequired property.</p>
<h3>Temporarily lock user account after failed login attempts</h3>
<p>This requirement is usefull at discouraging attempts at hacking the user password using automatted bots. If the user account is lociked for 30 minutes after three invalid login attempts this would presumably stop any attempt at trying to automatically guess the password, it would take to long.</p>
]]></content:encoded>
			<wfw:commentRss>http://mroot.serensystems.com/?feed=rss2&amp;p=4</wfw:commentRss>
		</item>
	</channel>
</rss>
