<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>110j</title>
	<atom:link href="http://110j.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://110j.wordpress.com</link>
	<description>When people talk, listen completely. Most people never listen. (Ernest Hemingway)</description>
	<lastBuildDate>Thu, 08 Dec 2011 10:41:48 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='110j.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>110j</title>
		<link>http://110j.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://110j.wordpress.com/osd.xml" title="110j" />
	<atom:link rel='hub' href='http://110j.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Play framework</title>
		<link>http://110j.wordpress.com/2010/11/26/play-framework/</link>
		<comments>http://110j.wordpress.com/2010/11/26/play-framework/#comments</comments>
		<pubDate>Fri, 26 Nov 2010 08:48:15 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Playframework]]></category>
		<category><![CDATA[Play]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=426</guid>
		<description><![CDATA[Excellent! This is how java web frameworks should had been from 2005. Play is a full stack framework and has so many features that putting them all on this post it will end up being an index list. But it&#8217;s not only the long list of features it has, it&#8217;s that everything works out of the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=426&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Excellent! This is how java web frameworks should had been from 2005. Play is a full stack framework and has so many features that putting them all on this post it will end up being an index list. But it&#8217;s not only the long list of features it has, it&#8217;s that everything works out of the box, there is no need to figure out how to do something. As I said the list is big, so I will only list those that I found more exciting&#8230; (I am using this framework on one of my current projects and it works very well on production environment, it&#8217;s not just another experiment).</p>
<p>Here they are:</p>
<ul>
<li>Active Record style model, based on JPA annotations and backed by hibernate. This is probably the most missing feature form java frameworks, for some strange reason no other Java web framework (at least non that I am aware off) tackle this one and developers are stack with an anemic model &#8211; well this is probably a very controversial issue with pros and cons from both sides, anyway, this works fine for me and the fact that it removes the need for DAOs is a big win. Furthermore, just like POJOs you can transfer the model objects them from the service layer to the front-end and back again.</li>
<li>No need to compile the sources, just make a change and reload your browser.</li>
<li>Template engine, it uses Groovy as an expression language, I am not familiar with Groovy at all but I love this feature, it works just like the django templates, there is no need to know Groovy to use it.</li>
<li>Play is modular, there are already plenty of modules to use and it&#8217;s really easy to write yours. Standard distribution of Play comes with two optional modules, CRUD and Secure. I think all projects have a need for both modules. With CRUD you have a full web administration interface for all your model objects and it&#8217;s fully customizable. Secure is a simple module that helps you setup a basic authentication and authorization management, it&#8217;s also highly customizable.</li>
<li>Play also ships with an embedded application server, just type &#8221;play run&#8221; and the world is ready for your next cool app, of course you can deploy your application on any application server. It&#8217;s really nice that the embedded application server is ready for production, it&#8217;s not just a subset to help you during development.</li>
<li>Testing the app is easier than ever.  It uses the JUnit for unit and functional testing, in your functional testing you can access directly your web controller objects. And there is a third kind of testing, Selenium for your views. But it does not stop there you can run your tests from your web page. In fact the tests are loaded only when you run Play in test mode &#8220;play test CoolApp&#8221;. Even more, with the Fixtures help class you can load your test data from a yaml file in no time. Do you want more! Continuous Integration to run your test auto-magically, just run Play with the auto-test command. I know what you think, you can do all these with any framework since they are not framework specific, but just imagine the time you need to set everything up, in Play they just work.</li>
<li>Ready for REST, it is easily scaled by running multiple instances of the same application on several servers.</li>
<li>IDE agnostic :) it comes with a command line tool that converts your project so it can be used in your favorite IDE.</li>
<li>And it&#8217;s really fast</li>
</ul>
<p>There are a lot more cool things about this framework. It&#8217;s very different from the rest of the frameworks in a good way, just as Spring broke the rules of enterprise development years ago, Play does the same, it breaks the rules and takes an unconventional away of doing thing which is closer to the developer, with the usability and productivity in mind.</p>
<p>Give it a try <a href="http://www.playframework.org/">http://www.playframework.org</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/426/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/426/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/426/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=426&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2010/11/26/play-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>
	</item>
		<item>
		<title>Clean and usable URLs in Stripes</title>
		<link>http://110j.wordpress.com/2010/05/07/clean-and-usable-urls-in-stripes/</link>
		<comments>http://110j.wordpress.com/2010/05/07/clean-and-usable-urls-in-stripes/#comments</comments>
		<pubDate>Fri, 07 May 2010 22:42:13 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Stripes]]></category>
		<category><![CDATA[Clean URLs]]></category>
		<category><![CDATA[Stripes Framework]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[URLs]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=410</guid>
		<description><![CDATA[Cool URIs don&#8217;t change wrote Tim Berners-Lee more than a decade ago, URLs should be clean, usable and persistent. However, the biggest percentage of URLs around the web still are not clean and usable and even less persistent. There are lots of reasons that URLs are not persistent and most of the times it is [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=410&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.w3.org/Provider/Style/URI">Cool URIs don&#8217;t change</a> wrote Tim Berners-Lee more than a decade ago, URLs should be clean, usable and persistent. However, the biggest percentage of URLs around the web still are not clean and usable and even less persistent. There are lots of reasons that URLs are not persistent and most of the times it is not in the hands of the developer or webmasters, under certain circumstances some domains may not continue to be alive or they may change hands, anyway there isn&#8217;t much a framework can do about that. But for the URLs to be clean and usable is totally in the hands of the developers and webmasters. Unfortunately most web frameworks makes things even worse by not providing the mechanism to handle URLs or by making it really difficult to change the default behavior.</p>
<p>Stripes is not one of those frameworks and it really makes it easy to create clean URLs and provides a very flexible mechanism for <a href="http://110j.wordpress.com/2009/11/14/url-binding-in-stripes/" target="_blank">handling them</a>.</p>
<p>The simplest way to do it is using the @UrlBinding annotation. Let&#8217;s assume we have the following action bean:</p>
<pre><code>
package com.project.action;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;

/**
 * @author omer haderi
 * @version 1.0
 */
public class SimpleMathActionBean implements ActionBean {
	private static final String view = "/WEB-INF/jsp/index.jsp";

	private ActionBeanContext ctx;

	private double number;

	public ActionBeanContext getContext() {
		return ctx;
	}

	public void setContext(ActionBeanContext ctx) {
		this.ctx = ctx;
	}

	@DefaultHandler
	public Resolution view() {
		return new ForwardResolution(view);
	}

	public Resolution sqrt() {
		number = Math.sqrt(getNumber());
		return new ForwardResolution(view);
	}

	public double getNumber() {
		return number;
	}

	public void setNumber(double number) {
		this.number = number;
	}
}
</code></pre>
<p>The URL for this action bean to calculate the square root (assuming the default behavior) will be:</p>
<p>http://www.domain.com/SimpleMath.action?sqrt=&#038;number=10</p>
<p>To simplify this we just need to mark the bean with the following annotation:<br />
@UrlBinding(&#8220;/public/simple_math&#8221;)<br />
after this the URL will be:</p>
<p>http://www.domain.com/public/simple_math?sqrt=&#038;number=10</p>
<p>Of course the point is to remove the question mark, the ampersand and the equals sign. In the previews URL the [sqrt] is an event of the action bean as you can see from the action bean class. There is a special notation to identify the event in the UrlBinding which is {$event}, so we need to modify the annotation as follows:<br />
@UrlBinding(&#8220;/public/simple_math/{$event}&#8221;)<br />
after this the URL will be:</p>
<p>http://www.domain.com/public/simple_math/sqrt=&#038;number=10</p>
<p>Let&#8217;s move on and remove the rest of symbols. In our URL the [number] is a parameter and just like the events it can be embedded in the UrlBinding as follows:<br />
@UrlBinding(&#8220;/public/simple_math/{$event}/{number}&#8221;) and it can even have a default value<br />
@UrlBinding(&#8220;/public/simple_math/{$event}/{number=5}&#8221;)<br />
after this the URL will be:</p>
<p>http://www.domain.com/public/simple_math/sqrt/10/</p>
<p>That&#8217;s it just one annotation and the URL is simple, more readable and makes more sense.</p>
<p>This is how will the action bean class look like after marking it with the annotation that we just constructed:</p>
<pre><code>
/**
 * @author omer haderi
 * @version 1.0
 */
@UrlBinding("/public/simple_math/{$event}/{number=5}")
public class SimpleMathActionBean implements ActionBean {
...
}
</code></pre>
<p>Here are the two URLs:<br />
before: http://www.domain.com/public/simple_math?sqrt=&amp;number=10<br />
after   : http://www.domain.com/public/simple_math/sqrt/10/<br />
as you can see the later is much better.</p>
<p>You may be wondering what&#8217;s that /public over there!?<br />
That&#8217;s the url-mapping in the servlet-mapping of the DispatcherServlet in the web.xml which can be anything that makes sence for your project:</p>
<pre><code>&lt;servlet-mapping&gt;
	&lt;servlet-name&gt;DispatcherServlet&lt;/servlet-name&gt;
	&lt;url-pattern&gt;/public/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</code></pre>
<p>When using UrlBinding annotation only the URL of those action beans that are marked by the annotation will change, the rest of the actions will still have the default URL binding as explained in the &#8220;<a href="http://110j.wordpress.com/2009/11/14/url-binding-in-stripes/" target="_blank">URL Binding in Stripes</a>&#8220;.</p>
<p>To change the default behavior to all Action Beans we would need to create a subclass of NameBaseActionResolver and override its methods:</p>
<pre><code>
package com.project.extensions;
/**
 * @author omer haderi
 * @version 1.0
 */
public class CustomActionResolver extends NameBasedActionResolver {
        // this is the url-pattern from the DispatcherServlet servlet-mapping in the web.xml
	private static final String URL_PATTERN = "/public";

	@Override
	protected String getBindingSuffix() {
		return "";
	}

	@Override
	protected String getUrlBinding(String actionBeanName) {
		String result = super.getUrlBinding(actionBeanName);
		result = separeteCamelCaseWithUnderscore(result).toLowerCase();

		return URL_PATTERN + result;
	}

	private static String separeteCamelCaseWithUnderscore(String s) {
		String pattern = "(?&lt;=[A-Z])(?=[A-Z][a-z])|(?&lt;=[^A-Z])(?=[A-Z])|(?&lt;=[A-Za-z])(?=[^A-Za-z])";
		return s.replaceAll(pattern, "_");
	}
}
</code></pre>
<p>You need to add the extension package in the filter parameters in the web.xml see &#8220;<a href="../2009/11/14/url-binding-in-stripes/" target="_blank">URL Binding in Stripes</a>&#8221; for more information.</p>
<p>From now on all the action beans will have this as default URL binding.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/410/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/410/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/410/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/410/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/410/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/410/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/410/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/410/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/410/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/410/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/410/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/410/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/410/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/410/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=410&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2010/05/07/clean-and-usable-urls-in-stripes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>
	</item>
		<item>
		<title>Type safe JPA queries</title>
		<link>http://110j.wordpress.com/2009/11/29/type-safe-jpa-queries/</link>
		<comments>http://110j.wordpress.com/2009/11/29/type-safe-jpa-queries/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 00:49:55 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JPA 2]]></category>
		<category><![CDATA[Persistence]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Type Safe]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=384</guid>
		<description><![CDATA[Quite often I find myself refactoring parts of my applications for different reasons and I am sure most developers do the same thing. Refactoring a java application is relatively easy since java is statically typed language and compiler will catch all type mismatches, moreover, modern IDEs like eclipse, intelij and netBeans provide all the necessary [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=384&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Quite often I find myself refactoring parts of my applications for different reasons and I am sure most developers do the same thing. Refactoring a java application is relatively easy since java is statically typed language and compiler will catch all type mismatches, moreover, modern IDEs like eclipse, intelij and netBeans provide all the necessary tools to accomplish this task as easily as possible. However, there is one part of the application that java compiler and IDE tools cannot do much. This part is the JPA queries which are String literals and there is no way for the compiler to catch any changes from the model. It seems that things will change with JPA 2.</p>
<p>JPA 2 introduces the Metamodel API (proposed by Gavin King) which is useful regardless of type safe queries. The metamodel exposes a set of interfaces which can be used to write  type safe queries with the new API. Other advantages of metamodel API besides the type safe queries are that it protects from SQL injection, auto-complete support through IDE, refactoring support.</p>
<p>Here is an example of how cool feature this is. Consider the following entities:</p>
<pre><code>
package org.chemistry.domain;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Substance {
	@Id
	private Long id;

	private String name;
	private String symbol;
	private double atomicWeight;
	private double grams;

	// getters and setters
	// ...
}
<hr />
package org.chemistry.domain;

import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Mixture {
	@Id
	private Long id;

	@Basic
	private String name;

	@OneToMany
	private Set&lt;Substance&gt; substances;

	// getters &amp; setters
	// ...
}
</code></pre>
<p>The metamodel classes for the entities will look like the following:</p>
<pre><code>
package org.chemistry.domain;

import javax.persistence.metamodel.*;

@TypesafeMetamodel
public class Substance_ {
	public static volatile Attribute&lt;Substance, Long&gt; id;
	public static volatile Attribute&lt;Substance, String&gt; name;
	public static volatile Attribute&lt;Substance, String&gt; symbol;
	public static volatile Attribute&lt;Substance, Double&gt; atomicWeight;
	public static volatile Attribute&lt;Substance, Double&gt; grams;
}
<hr />
package org.chemistry.domain;

import javax.persistence.metamodel.*;

@TypesafeMetamodel
public class Mixture_ {
	public static volatile Attribute&lt;Mixture, Long&gt; id;
	public static volatile Attribute&lt;Mixture, String&gt; name;
	public static volatile Set&lt;Mixture, Substance&gt; substances;
}
</code></pre>
<p>Nothing impressive until now&#8230; the impressive part is how we can write the queries in a type safe way using the new criteria API. We can use the CriteriaQuery and the QueryBuilder to create the queries in the following way.</p>
<pre><code>
// get the entity manager
EntityManager em = ... ;

// JPQL
String query = "SELECT m.name FROM Mixture m JOIN m.substances s WHERE s.name = :name"
Query q = em.createQuery(query);
q.setParameter("name", "Beryllium");

// new query API
QueryBuilder qb = em.getQueryBuilder();
CriteriaQuery q = qb.create();
Root mixture = q.from(Mixture.class);
Join&lt;Mixture, Substance&gt; sub = mixture.join(Mixture_.substances);
q.where(qb.equals(sub.get(Substances_.name), "Beryllium")).select(mixture.get(Mixture_.name));
</code></pre>
<p>Now any refactoring in the Mixture or the Substance classes will immediately reflect the changes to the query. The metamodel classes are (or will be) auto generated by the time the entity class is compiled. So hopefully no more runtime exceptions because of domain model refactoring :) </p>
<p>This is JSR 317, <a href="http://jcp.org/aboutJava/communityprocess/edr/jsr317/">here</a> you can find all the necessary details about this cool API.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/384/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/384/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/384/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=384&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/11/29/type-safe-jpa-queries/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>
	</item>
		<item>
		<title>URL Binding in Stripes</title>
		<link>http://110j.wordpress.com/2009/11/14/url-binding-in-stripes/</link>
		<comments>http://110j.wordpress.com/2009/11/14/url-binding-in-stripes/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 21:46:40 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Stripes]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=342</guid>
		<description><![CDATA[The best thing about Stripes is that it follows the convention over configuration practice. One of the most convenient conventions is the automatic generation and binding of URLs to the action bean class names. During development this is very helpful since you don&#8217;t need to keep in sync a configuration file as you add or [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=342&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The best thing about Stripes is that it follows the convention over configuration practice. One of the most convenient conventions is the automatic generation and binding of URLs to the action bean class names. During development this is very helpful since you don&#8217;t need to keep in sync a configuration file as you add or delete action beans. To generate the URLs Stripes follows certain rules, of course as with everything else in Stripes you can change the default rules if they don&#8217;t meet your needs.</p>
<p>First lets see the default rules and then I&#8217;ll discus  how to change them if needed.</p>
<p>Stripes will automatically load all your action beans at start up, but we need to tell Stripes where to start looking for action beans, we need to declare at least one root package. We can do this by specifying the ActionResolver.Packages init-param in the declaration of the StripesFilter in web.xml which is the only mandatory configuration parameter. If you keep your action beans in different packages you can add all of them separated by comma as shown in the following spinet.</p>
<pre>&lt;filter&gt;
  &lt;filter-name&gt;StripesFilter&lt;/filter-name&gt;
  &lt;filter-class&gt;net.sourceforge.stripes.controller.StripesFilter&lt;/filter-class&gt;
  &lt;init-param&gt;
    &lt;param-name&gt;ActionResolver.Packages&lt;/param-name&gt;
    &lt;param-value&gt;com.pk1.action,com.pk2.action&lt;/param-value&gt;
  &lt;/init-param&gt;
&lt;/filter&gt;</pre>
<p>Now that Stripes knows how to load the action beans lets see how the URLs are generated and bound to the action bean class names. Lets suppose we have the following action bean:</p>
<pre><code>
package com.action.test;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;

public class HelloActionBean implements ActionBean {
	private ActionBeanContext context;

    public ActionBeanContext getContext() {
        return context;
    }
    public void setContext(ActionBeanContext context) {
        this.context = context;
    }

    @DefaultHandler
    public Resolution view () {
	return new ForwardResolution("/WEB-INF/jsp/home.jsp");
    }
}
</code></pre>
<p>Our action bean class name is HelloActionBean and it&#8217;s located under the package com.action.test; to refere to this action in a jps we can use the following name /test/Hello.action.</p>
<p>As mentioned previously to generate the URLs Stripes follows certain rules.<br />
1. It will remove the package name up to and including the the following names if present in the package [action, stripes, web, www]. That&#8217;s why we refer to the /test/Hello.action without the full package name since the package name of this bean includes the token action and is removed up to that token.<br />
2. It will remove from the class name the following suffixes [ActionBean, Action or Bean]. That&#8217;s why we have the /test/Hello.action instead of /test/HelloActionBean.action.<br />
3. It will convert package name and class names to paths and change all periods to forward slashes. Instead of [test.Hello.action] we have /test/Hello.action<br />
4. It will append the .action to the end of the striped bean name.</p>
<p>Fast forward:<br />
rule 1: from <strong>com.action.test.HelloActionBean</strong> we get <strong>test.HelloActionBean</strong><br />
rule 2: from <strong>test.HelloActionBean</strong> we get <strong>test.Hello</strong><br />
rule 3: from <strong>test.Hello</strong> we get <strong>/test/Hello</strong><br />
rule 4: from <strong>/test/Hello</strong> we get <strong>/test/Hello.action</strong></p>
<p>Lets see some examples of how this works:<br />
com.pk1.action.HelloActionBean &#8211;&gt; /Hello.action<br />
com.pk1.web.HelloAction &#8211;&gt; /Hello.action<br />
com.pk1.www.HelloBean &#8211;&gt; /Hello.action<br />
com.pk1.stripes.HelloActionBean &#8211;&gt; Hello.action<br />
com.pk2.module.HelloActionBean &#8211;&gt; /com/pk2/module/Hello.action</p>
<p>Some controversial examples:<br />
com.pk1.web.MyActionBeanX  &#8211;&gt; /MyActionBeanX.action (the ActionBean is not removed since it is not at the end)<br />
com.pk1.www.ActionBean &#8211;&gt; /.action (the ActionBean is removed based on the rule number 2)<br />
www.web.action.stripes.HelloBean &#8211;&gt; /Hello.action (all package tokens are removed since they are in the list of rule number 1)</p>
<p>Now that we know the rules for generating the URLs, lets see how we can change them to meet our needs. This process is quite easy.<br />
The class that implements the rules for URL binding is the NameBasedActionResolver. To change the rules for URL binding you just need to extend this class and override the getBasePackages() and/or getBindingSuffix(), (if you change the suffix do not forget to change url-pattern of the servlet mapping in the web.xml). You can change completely the behavior of URL binding by overriding the getUrlBinding(String). Your custom class for the URL bind rules should be registered as a Stripes extension.</p>
<p>Here is an example of how to change the suffix from [action] to [go]. As I said this is quite easy, it requires two steps:</p>
<p>1. Change the servlet mapping in web.xml</p>
<pre><code>
&lt;servlet-mapping&gt;
	&lt;servlet-name&gt;DispatcherServlet&lt;/servlet-name&gt;
	&lt;url-pattern&gt;*.go&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
</code></pre>
<p>2. Extend the NameBasedActionResolver and override the getBindingSuffix()</p>
<pre><code>
package com.ext;

import net.sourceforge.stripes.controller.NameBasedActionResolver;

public class CustomActionResolver extends NameBasedActionResolver {
	@Override
	protected String getBindingSuffix() {
		return ".go";
	}
}
</code></pre>
<p>Note that this is an extension and extensions are loaded automatically by Stripes but as with action beans we need to tell Stripes where to look for. To configure extensions we need to add another init-param to the StripesFilter as we did for the action beans. The parameter name for the extensions is [Extension.Packages].<br />
Here is an example:</p>
<pre><code>
&lt;init-param&gt;
	&lt;param-name&gt;Extension.Packages&lt;/param-name&gt;
	&lt;param-value&gt;com.ext&lt;/param-value&gt;
&lt;/init-param&gt;
</code></pre>
<p>Extending the NameBasedActionResolver we can tweak the URLs in any way we want and as you can see it is quite easy, an interesting tweak would be to implement clean URLs but that will be another post.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/342/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/342/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/342/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/342/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/342/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/342/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/342/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/342/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/342/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/342/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/342/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/342/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/342/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/342/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=342&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/11/14/url-binding-in-stripes/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>
	</item>
		<item>
		<title>The Stripes framework</title>
		<link>http://110j.wordpress.com/2009/10/03/the-stripes-framework/</link>
		<comments>http://110j.wordpress.com/2009/10/03/the-stripes-framework/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 23:59:54 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Stripes]]></category>
		<category><![CDATA[Stripes Features]]></category>
		<category><![CDATA[Stripes Framework]]></category>
		<category><![CDATA[Tec]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=310</guid>
		<description><![CDATA[Choosing a java web framework is somehow a complex process, not because they are difficult to evaluate but because there are so many of them (in fact it seems that there are more java frameworks than java developers :) but having many frameworks is a good thing. It means that there is a lot of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=310&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Choosing a java web framework is somehow a complex process, not because they are difficult to evaluate but because there are so many of them (in fact it seems that there are more java frameworks than java developers :) but having many frameworks is a good thing. It means that there is a lot of competition and the competition seems to be healthy since most of the frameworks are open source, so competition is based on quality and features instead of marketing and lobbing.</p>
<p>Different people have different criteria on selecting a framework and probably different needs, so I will list my criteria an the reasoning behind them for choosing Stripes.<br />
(Disclaimer: this expresses only my views on what I expect from a framework, I don&#8217;t think there are good or bad frameworks, from my point of view there are only convenient frameworks &#8211; just trying to avoid flame war here, although flame wars entertains me a lot!).</p>
<p>I would like to start with what I consider the most annoying thing when working with a Java framework which is not other than XML configuration files. Having worked with JSF and Struts where you need to configure all your managed-beans/action-beans and pretty much everything else into an xml configuration file, which during development becomes a mess to keep it in sync, I enjoy that Stripes removes all this configuration hassle with <strong>autoloading</strong> feature. The only xml configuration file that you need is the web.xml but that is required by the Servlet specification. Configuration by exception (a.k.a convention over configuration) is the way to go, developers should focus on business solutions and not in framework configuration details that will just disturb the flow of thinking. Hopefully other framework will follow &#8211; or maybe some already does.</p>
<p>Testing is the most important part of development and therefore frameworks should come with a build-in support for testing to make this process easy. So Stripes comes with a set of mock objects that help developers to easily write unit tests.</p>
<p>Easy extension and customization. Stripes is designed in modular form it is quite easy to add a customization plugin to change the behavior of any part of the framework, because of this modular design the extensibility of Stripes is trivial. Actually This is one of the areas that the framework really make the difference.</p>
<p>I don&#8217;t think that there&#8217;s a need to explain why internationalization of web application is important, all frameworks need to have a built-in support for i18n. Stripes tags comes with a default bundle lookup strategy so that i18n is just a mutter of adding key/value pairs in the resource bundle.</p>
<p>Never trust the user input, therefore a strong and flexible validation mechanism is needed. Stripes provides a powerful validation mechanism which is based on annotations (remember there is no XML configuration).</p>
<p>When working with request parameters the most annoying process is converting Strings to objects and vise versa, the Stripes support for this process is just amazing. But it is not just conversion there is also support for formating an object to string and that&#8217;s as easy as the conversion process.</p>
<p>Stripes comes with a built in support for layouts, with three tags you can achieve pretty much everything. If the built in support for templating is not enough you can use freemarker.</p>
<p>Since we are talking about web framework and web applications it would be a pity to not take advantage of Ajax. Any Ajax framework can be used due to Stripes simple and transparent request/response nature.</p>
<p>These are some of the features that I like to see in a framework and surely you can find this features in most frameworks and probably more but the difference is that with Stripes is easy and development is fun again as the book of Frederic Daoud suggests and proves it.</p>
<p>If you want to learn Stripes I suggest the &#8220;Stripes &#8230; and Java web development is fun again&#8221; from The Pragmatic Programmers, in fact this is the only book about Stripes but even if there were more books I am totally sure that I would suggest this book again, it is very well written and it covers everything about Stripes.</p>
<p>The following is a quick list of Stripes features, which I will try to explain and give an example in future post for each one of them and link them back to this page:</p>
<p><a href="http://110j.wordpress.com/2009/11/14/url-binding-in-stripes/" target="_blank">URL Binding</a><br />
Built in Validation<br />
Custom Validation<br />
Type Conversion<br />
Formatting<br />
Layouts<br />
Using Freemarker<br />
Localization<br />
Exception Handling<br />
Interceptors<br />
URL Customization<br />
Ajax Integration<br />
Framework Extension<br />
Framework Customization<br />
Testing<br />
Dependency Injection (Giuce/Spring)<br />
JPA Integration<br />
Security and Encryption<br />
Cache-ing</p>
<p>The examples will be deployed on google app engine.</p>
<p>P.S: Now that the jsr 330 is approved maybe the next version of Stripes will come with build in Dependency Injection.</p>
<p>If you would like to start playing with Stripes and google app engine have a look at the following links:<br />
<a href="http://110j.wordpress.com/2009/09/19/getting-started-with-stripes-google-app-engine/" target="_blank">http://110j.wordpress.com/2009/09/19/getting-started-with-stripes-google-app-engine/</a><br />
<a href="http://110j.wordpress.com/2009/09/20/redoing-guestbook-example-with-stripes/" target="_blank">http://110j.wordpress.com/2009/09/20/redoing-guestbook-example-with-stripes/</a></p>
<p>Stripes resources:<br />
<a href="http://www.stripesframework.org/display/stripes/Home" target="_blank">Stripes Home Page</a><br />
<a href="http://www.pragprog.com/titles/fdstr/stripes" target="_blank">Stripes &#8230; and Java development is fun again</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/310/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/310/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/310/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=310&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/10/03/the-stripes-framework/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>
	</item>
		<item>
		<title>Redoing Guestbook example with Stripes</title>
		<link>http://110j.wordpress.com/2009/09/20/redoing-guestbook-example/</link>
		<comments>http://110j.wordpress.com/2009/09/20/redoing-guestbook-example/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 17:48:29 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[App Engine]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Stripes]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[JDO]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Stripes Framework]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=316</guid>
		<description><![CDATA[Google has created an example on how to use google app engine with java. In this example they demonstrate the basic usage of Servlet API and JDO, it&#8217;s a simple example that stores, retrieves and renders entities in google app engine. After the first tutorial on how to deploy Stripes in google app engine I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=316&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Google has created an example on how to use google app engine with java. In this example they demonstrate the basic usage of Servlet API and JDO, it&#8217;s a simple example that stores, retrieves and renders entities in google app engine.<br />
After the <a href="http://110j.wordpress.com/2009/09/19/getting-started-with-stripes-google-app-engine/" target="_blank">first tutorial</a> on how to deploy Stripes in google app engine I decided to re-write this example using the Stripes framework of course.</p>
<p><a href="http://guestbook-stripes.googlecode.com/files/Guestbook.zip" target="_self"><strong>Download the source code!</strong></a></p>
<p>Steps:</p>
<p>1. Create a project and name it Guestbook</p>
<p>2. Follow the <a href="http://110j.wordpress.com/2009/09/19/getting-started-with-stripes-google-app-engine/" target="_blank">Getting started with Stripes and google app engine</a> to configure Stripes</p>
<p>3. Add the JSTL jars (standard.jar and jstl.jar) in the lib directory</p>
<p>4. Create an ActionBean that will handle the greeting requests</p>
<blockquote>
<pre><code>
package com.guestbook.action;

import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.guestbook.manager.PMF;
import com.guestbook.model.Greeting;

/**
 * @author 110j
 */
public class GreetingActionBean implements ActionBean {
	private static final String VIEW = "/guestbook.jsp";
	private ActionBeanContext ctx;
	private UserService userService = UserServiceFactory.getUserService();
	private Greeting greeting;

	@DefaultHandler
	public Resolution welcome() {
		return new ForwardResolution(VIEW);
	}

	public Resolution addGreeting() {
		if (greeting != null) {
			greeting.setAuthor(getUser());
			greeting.setDate(new Date());

			PersistenceManager pm = PMF.get().getPersistenceManager();
	        try {
	            pm.makePersistent(greeting);
	        } finally {
	            pm.close();
	        }
		}
		return new ForwardResolution(VIEW);
	}

	public Resolution signin() {
		ForwardResolution fd = new ForwardResolution(VIEW);
		if (!userService.isUserLoggedIn())
			fd = new ForwardResolution(userService.createLoginURL("/Greeting.action"));
		return fd;
	}

	public Resolution signout() {
		ForwardResolution ForwardResolution "&gt;fd = new ForwardResolution(VIEW);
		if (userService.isUserLoggedIn())
			fd = new ForwardResolution(userService.createLogoutURL("/Greeting.action"));
		return fd;
	}

	@SuppressWarnings("unchecked")
	public List getGreetings() {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		String query = "select from " + Greeting.class.getName() + " order by date desc range 0,5";
	    return (List) pm.newQuery(query).execute();
	}

	public Greeting getGreeting() {
		return greeting;
	}

	public void setGreeting(Greeting greeting) {
		this.greeting = greeting;
	}

	public User getUser() {
		return userService.getCurrentUser();
	}

	public ActionBeanContext getContext() {
		return this.ctx;
	}

	public void setContext(ActionBeanContext ctx) {
		this.ctx = ctx;
	}
}
</code></pre>
</blockquote>
<p>5. Create the model class called Greeting (as described in the google example, no changes here!)</p>
<blockquote>
<pre><code>
package com.guestbook.model;

import java.util.Date;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.users.User;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Greeting {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Long id;

    @Persistent
    private User author;

    @Persistent
    private String content;

    @Persistent
    private Date date;

    public Greeting() {}

    public Greeting(User author, String content, Date date) {
        this.author = author;
        this.content = content;
        this.date = date;
    }

    public Long getId() {
        return id;
    }

    public User getAuthor() {
        return author;
    }

    public String getContent() {
        return content;
    }

    public Date getDate() {
        return date;
    }

    public void setAuthor(User author) {
        this.author = author;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}
</code></pre>
</blockquote>
<p>6. Create the utility class that will instantiate the EntityManager (no changes here also!)</p>
<blockquote>
<pre><code>package com.guestbook.manager;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

public final class PMF {
    private static final PersistenceManagerFactory pmfInstance =
        JDOHelper.getPersistenceManagerFactory("transactions-optional");

    private PMF() {}

    public static PersistenceManagerFactory get() {
        return pmfInstance;
    }
}
</code></pre>
</blockquote>
<p>7. Modify the guestbook.jsp, there are a lot of changes here since in their example google uses scriptlets, I have replaced the scriptlets with jstl tags and Stripes tags, all the logic has moved to the ActionBean.</p>
<table style="width:auto;" border="0">
<tbody>
<tr>
<td><img src="http://lh4.ggpht.com/_zJMWXmr_TzU/SrY15HMZ85I/AAAAAAAAACg/yvsAnK5kwi8/s800/guest_book.png" alt="" /></td>
</tr>
</tbody>
</table>
<p>8. Modify the welcome file list in the web.xml and set as welcome file the <strong>Greeting.action</strong></p>
<p><a href="http://guestbook-stripes.googlecode.com/files/Guestbook.zip" target="_self"><strong>Download the source code!</strong></a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/316/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/316/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/316/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=316&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/09/20/redoing-guestbook-example/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>

		<media:content url="http://lh4.ggpht.com/_zJMWXmr_TzU/SrY15HMZ85I/AAAAAAAAACg/yvsAnK5kwi8/s800/guest_book.png" medium="image" />
	</item>
		<item>
		<title>Getting started with Stripes &amp; Google App Engine</title>
		<link>http://110j.wordpress.com/2009/09/19/getting-started-with-stripes-google-app-engine/</link>
		<comments>http://110j.wordpress.com/2009/09/19/getting-started-with-stripes-google-app-engine/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 01:29:48 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[App Engine]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Stripes]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[google app engine]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=298</guid>
		<description><![CDATA[This is a basic example of using Stripes Framework with the cloud infrastructure of Google. I am using Stripes in one of my projects that I am thinking to move it to google app engine so I decided to experiment before the migration. More posts will follow in this topic as I progress with it. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=298&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is a basic example of using Stripes Framework with the cloud infrastructure of Google. I am using Stripes in one of my projects that I am thinking to move it to google app engine so I decided to experiment before the migration. More posts will follow in this topic as I progress with it. The first objective is to create the basic project structure, configure and deploy, well&#8230; a hello world web application. This is a trivial application but there are some limitations using google app engine so trying to use the framework as is will fail with some non-sense stack traces.</p>
<p>The following is a list of things that we will be need to complete this application:<br />
1. Stripes Framework (home page: <a href="http://www.stripesframework.org/display/stripes/Home" target="_blank">http://www.stripesframework.org/display/stripes/Home</a> )<br />
2. Google app engine sdk &#8211; if you use eclipse and google plugin the sdk is included in the plugin.<br />
3. Eclipse (you can use whatever IDE or environment you like, it&#8217;s not mandatory to use eclipse, it&#8217;s just easier).</p>
<p>Note: For information on how to install the google plugin visit <a href="http://code.google.com/appengine/docs/java/tools/eclipse.html" target="_blank">http://code.google.com/appengine/docs/java/tools/eclipse.html</a></p>
<p>I assume you are familiar with java web frameworks and that you will use eclipse with the google plugin.</p>
<p>The first step is to create a project in the eclipse IDE:<br />
<img class="alignnone" title="new project" src="http://lh3.ggpht.com/_zJMWXmr_TzU/SrQo4zxDU-I/AAAAAAAAABo/QpE0JFRNJd4/s800/1_new_project.png" alt="" width="605" height="580" /></p>
<p>Give a name to the project and an initial package name. For the moment we do not need GWT so just deselect it.<br />
<img class="alignnone" title="settings" src="http://lh3.ggpht.com/_zJMWXmr_TzU/SrQo5LvetyI/AAAAAAAAABs/H5xuyMV2cIk/s800/2_project_settings.png" alt="" width="605" height="671" /></p>
<p>After pressing finish we have the following project structure.<br />
<img class="alignnone" title="structure" src="http://lh4.ggpht.com/_zJMWXmr_TzU/SrQo5Fq_d2I/AAAAAAAAABw/j8eBGQ_6CoA/s800/3_project_stucture.png" alt="" width="388" height="521" /></p>
<p>Before continuing copy the Stripes jars in the the lib directory under hello_project/web/WEB_INF/lib and add them to the project&#8217;s build path by selecting them, right click-&gt; Build Path -&gt; Add to Build Path. Also copy and paste the StripesResources.properties in the directory &#8220;src&#8221; (not in a package).</p>
<p>By default the google plugin will generate a servlet for us, under the package name that we entered in the previews step. It will also generate the following configuration files:<br />
Servlet spec requirement:<br />
1. web.xml (this is the well known deployment descriptor required by the servlet specification)</p>
<p>Google App engine specific (we will not use them for this application):<br />
1. appengine-web.xml<br />
2. jdoconfig.xml</p>
<p>Logging property files:<br />
1. log4j.properties<br />
2. logging.properties</p>
<p>For the purpose of this trivial application we will only need to edit the web.xml (a.k.a Deployment Descriptor so from know on I will call it DD).<br />
By default the plugin registers the generated servlet in the DD, so open the DD and delete the servlet and servlet-mapping it&#8217;s not needed.</p>
<p>The following is the generated DD that need to be edited:</p>
<table style="width:auto;" border="0">
<tbody>
<tr>
<td><img src="http://lh6.ggpht.com/_zJMWXmr_TzU/SrQo5Fd9NuI/AAAAAAAAAB0/YZ-SN85McUU/s800/4_generated_web_xml.png" alt="" /></td>
</tr>
</tbody>
</table>
<p>The following is the new and final DD containing the Stripes filter and dispatcher servlet:</p>
<table style="width:auto;" border="0">
<tbody>
<tr>
<td><img src="http://lh4.ggpht.com/_zJMWXmr_TzU/SrQo5cQuGrI/AAAAAAAAAB4/mlWZPJg_79o/s800/5_new_web_xml.png" alt="" /></td>
</tr>
</tbody>
</table>
<p>Note that the web-app tag version has changed from 2.5 to 2.4 there are some jsp exceptions with the 2.5.</p>
<p>The Stripes filter includes two initial parameters the <strong>ActionResolver.Packages </strong>which tells Stripes where to find the ActionBeans (more on this in next post or in Stripes documentation) and the <strong>MultipartWrapperFactory.Class, </strong>a factory class used to upload files, but uploading files is not supported by google app engine and the Stripes filter will fail to initialize. Therefore we need to disable this by providing an empty configuration.</p>
<p>The first step to disable file uploading is to add MultipartWrapperFactory.Class initial parameter to the Stripes filter as shown in the DD and the second step is to create the appropriate class. So create a package in the project (I created the com.helloworld.exclude but you can create anything that make sense for your project) and add the following class:</p>
<blockquote>
<pre><code>
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import net.sourceforge.stripes.config.Configuration;
import net.sourceforge.stripes.controller.FileUploadLimitExceededException;
import net.sourceforge.stripes.controller.multipart.MultipartWrapper;
import net.sourceforge.stripes.config.ConfigurableComponent;
import net.sourceforge.stripes.controller.multipart.MultipartWrapperFactory;

/**
 * GAE does not support file uploading so we need to disable this feature from Stripes.
 *
 * @author 110j
 */
public class EmptyMultipartWapper implements ConfigurableComponent, MultipartWrapperFactory {

	/**
	 * @see net.sourceforge.stripes.config.ConfigurableComponent#init(net.sourceforge.stripes.config.Configuration)
	 */
	public void init(Configuration conf) throws Exception {
	}

	/**
	 * @see net.sourceforge.stripes.controller.multipart.MultipartWrapperFactory#wrap(javax.servlet.http.HttpServletRequest)
	 */
	public MultipartWrapper wrap(HttpServletRequest request) throws IOException, FileUploadLimitExceededException {
		return null;
	}
}
</code></pre>
</blockquote>
<p>Now that we disabled the file uploading lets create an ActionBean that will handle our request. Create a package in the project called com.helloworld.action and add the following class:</p>
<blockquote>
<pre><code>
package com.helloworld.action;

import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.action.ActionBeanContext;
import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;

/**
 * The action bean that will handle the our simple request.
 *
 * @author 110j
 */
public class EasyActionBean implements ActionBean {
	private static final String VIEW = "/WEB-INF/jsp/hello_world.jsp";
	private static final String MY_MESSAGE = "hello world";
	private ActionBeanContext ctx;

	private String message;

	@DefaultHandler
	public Resolution showMe() {
		this.setMessage(MY_MESSAGE);
		return new ForwardResolution(VIEW);
	}

	/**
	 * @see net.sourceforge.stripes.action.ActionBean#getContext()
	 */
	public ActionBeanContext getContext() {
		return this.ctx;
	}

	/**
	 * @see net.sourceforge.stripes.action.ActionBean#setContext(ActionBeanContext)
	 */
	public void setContext(ActionBeanContext ctx) {
		this.ctx = ctx;
	}

	/**
	 * @return the message
	 */
	public String getMessage() {
		return message;
	}

	/**
	 * @param message the message to set
	 */
	public void setMessage(String message) {
		this.message = message;
	}
}
</code></pre>
</blockquote>
<p>Next lets create a jsp file that will render the response, create the hello_world.jsp under WEB_INF/jsp/ and add the following content:</p>
<table style="width:auto;" border="0"><img src="http://lh6.ggpht.com/_zJMWXmr_TzU/SrQpE4WyYSI/AAAAAAAAAB8/3de0C5b5iok/s800/6_hello_world_jsp.png" alt="" /></table>
<p>Finally create a welcome file called index.jsp if it does not exist or rename the index.html to index.jsp and add just a forward to the action:</p>
<table style="width:auto;" border="0">
<tbody>
<tr>
<td><img src="http://lh5.ggpht.com/_zJMWXmr_TzU/SrQpE4_FTbI/AAAAAAAAACA/BPpemvYTUkc/s800/7_index_jsp.png" alt="" /></td>
</tr>
</tbody>
</table>
<p>You can delete the servlet generated by the google plugin there is no need for it.</p>
<p>In order to test it you just need to run the hello_world in the Run history of eclipse as the google plugin will create one for us, or under the run button in the toolbar, and then visit the address localhost:8080</p>
<p>NOTE: if your application require session you need to enable it in the appengine-web.xml since it is disabled by default (but keep in mind the implication it may have in a distributed environment such as google app engine, maybe your attributes will need to implement the HttpSessionActivationListener if you plan to add them in the session).</p>
<p>You can upload your application by using eclipse or the command line tool, for more information visit <a href="http://code.google.com/appengine/docs/java/gettingstarted/uploading.html" target="_blank">http://code.google.com/appengine/docs/java/gettingstarted/uploading.html</a></p>
<p>To be continued!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/298/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/298/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/298/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=298&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/09/19/getting-started-with-stripes-google-app-engine/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>

		<media:content url="http://lh3.ggpht.com/_zJMWXmr_TzU/SrQo4zxDU-I/AAAAAAAAABo/QpE0JFRNJd4/s800/1_new_project.png" medium="image">
			<media:title type="html">new project</media:title>
		</media:content>

		<media:content url="http://lh3.ggpht.com/_zJMWXmr_TzU/SrQo5LvetyI/AAAAAAAAABs/H5xuyMV2cIk/s800/2_project_settings.png" medium="image">
			<media:title type="html">settings</media:title>
		</media:content>

		<media:content url="http://lh4.ggpht.com/_zJMWXmr_TzU/SrQo5Fq_d2I/AAAAAAAAABw/j8eBGQ_6CoA/s800/3_project_stucture.png" medium="image">
			<media:title type="html">structure</media:title>
		</media:content>

		<media:content url="http://lh6.ggpht.com/_zJMWXmr_TzU/SrQo5Fd9NuI/AAAAAAAAAB0/YZ-SN85McUU/s800/4_generated_web_xml.png" medium="image" />

		<media:content url="http://lh4.ggpht.com/_zJMWXmr_TzU/SrQo5cQuGrI/AAAAAAAAAB4/mlWZPJg_79o/s800/5_new_web_xml.png" medium="image" />

		<media:content url="http://lh6.ggpht.com/_zJMWXmr_TzU/SrQpE4WyYSI/AAAAAAAAAB8/3de0C5b5iok/s800/6_hello_world_jsp.png" medium="image" />

		<media:content url="http://lh5.ggpht.com/_zJMWXmr_TzU/SrQpE4_FTbI/AAAAAAAAACA/BPpemvYTUkc/s800/7_index_jsp.png" medium="image" />
	</item>
		<item>
		<title>tail the log file inside eclipse</title>
		<link>http://110j.wordpress.com/2009/07/08/tail-the-log-file-inside-eclipse/</link>
		<comments>http://110j.wordpress.com/2009/07/08/tail-the-log-file-inside-eclipse/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 22:55:55 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[eclipse tools]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[tail]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=293</guid>
		<description><![CDATA[Most common tool to follow the logs of the application is tail at least under unix, linux and probably mac osx operating systems. So we just need to open a console and type tail -f path/app.log. Fairly simple but it would be nice to have it inside eclipse, which turns out to be also very simple to configure it with the external tools of eclipse.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=293&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Most common tool to follow the logs of the application is tail at least under unix, linux and probably mac osx operating systems. So we just need to open a console and type tail -f path/app.log. Fairly simple but it would be nice to have it inside eclipse, which turns out to be also very simple to configure it with the external tools of eclipse.</p>
<p>Open External Tools Configurations:</p>
<div class="wp-caption alignnone" style="width: 810px"><img title="External tool configuration" src="http://lh4.ggpht.com/_y9ipUdwtLqo/SlUhJ-tnlkI/AAAAAAAAAUw/ic25lpFUpEA/s800/Picture%202.png" alt="External tool configuration" width="800" height="655" /><p class="wp-caption-text">External tool configuration</p></div>
<p>Hit Run and that&#8217;s it. Windows users should install a tail for windows first!</p>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/293/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=293&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/07/08/tail-the-log-file-inside-eclipse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>

		<media:content url="http://lh4.ggpht.com/_y9ipUdwtLqo/SlUhJ-tnlkI/AAAAAAAAAUw/ic25lpFUpEA/s800/Picture%202.png" medium="image">
			<media:title type="html">External tool configuration</media:title>
		</media:content>
	</item>
		<item>
		<title>image-a-nation challenge &#8211; using Java</title>
		<link>http://110j.wordpress.com/2009/06/30/image-a-nation-challenge-using-java/</link>
		<comments>http://110j.wordpress.com/2009/06/30/image-a-nation-challenge-using-java/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 22:29:23 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Other]]></category>
		<category><![CDATA[challenge]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[image-a-nation]]></category>
		<category><![CDATA[images]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=284</guid>
		<description><![CDATA[Interesting challenge from google image team… here’s an attempt to create the image using java,
(more work is needed to make it more resposive while reading the image files, also reading the clues directly from the web would be better! :)<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=284&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Interesting challenge from google image team&#8230; here&#8217;s an attempt to create the image using java,<br />
(more work is needed to make it more resposive while reading the image files, also reading the clues directly from the web would be better! :)</p>
<div class="wp-caption alignnone" style="width: 396px"><img title="Sceenshot" src="http://lh6.ggpht.com/_y9ipUdwtLqo/SkqPhumNqJI/AAAAAAAAAUQ/zU-BldEYV-c/s400/Picture%201.jpg" alt="Screenshot" width="386" height="400" /><p class="wp-caption-text">Screenshot</p></div>
<pre>import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class GoogleImageBuilder extends JComponent {

	private static final String GOOGLE_URL = "http://google.com/images?q=tbn:";
    private static BufferedImage picture = null;

    public GoogleImageBuilder() {
    	setPreferredSize(new Dimension(16 * 32, 16 * 32));
    }

    public void paintComponent(Graphics g) {
    	Map clues = HardCodedClues.getClues();
    	SortedSet keys = new TreeSet(clues.keySet());

        int x = 0;
        int y = 0;

        for (Integer key : keys) {
			try {
				URL url = new URL(GOOGLE_URL  + clues.get(key));
				System.out.println("reading: " + url.toString());
				URLConnection uc = url.openConnection();
				picture = ImageIO.read(uc.getInputStream());

			} catch (MalformedURLException e) {
				System.out.println("The following error occured!: " + e);
	            System.exit(0);

			} catch (IOException e) {
				System.out.println("The following error occured!: " + e);
	            System.exit(0);
			}

			x = (key % 16) * 32;
            y = (key / 16) * 32;

			g.drawImage(picture, x, y, 32, 32, null);
		}
    }

    private static void createAndShowGUI() {
        JFrame f = new JFrame("Google images");
        f.setLayout(new BorderLayout());
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GoogleImageBuilder test = new GoogleImageBuilder();
        f.add(test);
        f.validate();
        f.pack();
        f.setVisible(true);
    }

    public static void main(String args[]) {
        Runnable doCreateAndShowGUI = new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        };
        SwingUtilities.invokeLater(doCreateAndShowGUI);
    }
}</pre>
<p>Here are the clues hardcoded:</p>
<pre>import java.util.HashMap;
import java.util.Map;

public class HardCodedClues {
	private static final int RADIX_16 = 16;

    public static Map getClues() {
    	String [] clues = {
			 "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "84:h5LxuUdV03oJ", "D9:-Eup1YnE6-0J", "FC:7fjrc7LzjskJ", "03:LJouzaZ6nakJ",

			  "C3:3cyoIZdesRYJ", "EB:GumIzK6Xwv8J", "12:KYkKkVzbW-UJ", "AB:EHkO0tMtSN4J",

			  "30:vrZQ1rXJEg4J", "CE:AbXWG_eCFZYJ", "6B:EOhnwwtJMz4J", "5F:PyDg0PjbgxkJ",

			  "62:zzxVlWrc94AJ", "F2:CwpwlljQ5RUJ", "7F:9aqBJNfDaUEJ", "EE:CWVFy5sgo9MJ",

			  "4C:JDNgZADQwGkJ", "58:uJB16vUcH38J", "3D:Jij2JFUry5gJ", "C8:v7juRN1cZ4EJ",

			  "1E:16e59DDxd1QJ", "69:y1f3FuaNqhEJ", "B0:4cYEeKseVRYJ", "37:Hnm8AysFIvgJ",

			  "1D:qFpNdOAQ868J", "21:Ypml6jLyoaEJ", "34:UhJBrAWg8MAJ", "A0:xTaArVPF51IJ",

			  "EF:14kwBS4zH4kJ", "ED:eUzfBgFaYAYJ", "51:1RWzov84HGsJ", "72:WRUq1C2UF7YJ",

			  "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "84:h5LxuUdV03oJ", "D9:-Eup1YnE6-0J", "FC:7fjrc7LzjskJ", "03:LJouzaZ6nakJ",

			  "C3:3cyoIZdesRYJ", "EB:GumIzK6Xwv8J", "12:KYkKkVzbW-UJ", "AB:EHkO0tMtSN4J",

			  "30:vrZQ1rXJEg4J", "CE:AbXWG_eCFZYJ", "6B:EOhnwwtJMz4J", "5F:PyDg0PjbgxkJ",

			  "62:zzxVlWrc94AJ", "F2:CwpwlljQ5RUJ", "7F:9aqBJNfDaUEJ", "EE:CWVFy5sgo9MJ",

			  "4C:JDNgZADQwGkJ", "58:uJB16vUcH38J", "3D:Jij2JFUry5gJ", "C8:v7juRN1cZ4EJ",

			  "1E:16e59DDxd1QJ", "69:y1f3FuaNqhEJ", "B0:4cYEeKseVRYJ", "37:Hnm8AysFIvgJ",

			  "1D:qFpNdOAQ868J", "21:Ypml6jLyoaEJ", "34:UhJBrAWg8MAJ", "A0:xTaArVPF51IJ",

			  "EF:14kwBS4zH4kJ", "ED:eUzfBgFaYAYJ", "51:1RWzov84HGsJ", "72:WRUq1C2UF7YJ",

			  "24:TkF3I-3AqsoJ", "6E:Cxb4nb_-6wQJ", "CC:Cfwjydcm5VUJ", "94:3V77coCFoyUJ",

			  "0E:lfqBck_AckoJ", "C7:qTuFDoAZZAIJ", "E4:X9O9H0rf7UwJ", "A1:dh_aVJQg-fQJ",

			  "1B:SSUHFP88ICIJ", "9A:8LRpia1kQyoJ", "A8:6OB8e96ajfIJ", "8D:sekIn_D0FY4J",

			  "9D:sQbLyZCjcMwJ", "9C:at2mlybzsckJ", "2D:gagHFe3EgRcJ", "7C:sbERUkuwrgkJ",

			  "DF:jIbY1S4jGOQJ", "15:sQ5gc2skXDoJ", "B5:qpQ_jThwIfwJ", "E7:bujGGLRs6f8J",

			  "B9:FC8WDc6FfQAJ", "AC:7PqlCpunKtMJ", "90:6bCXBm-ZoeMJ", "05:kUDeAWh_o54J",

			  "46:BTA_qt_HhUkJ", "3E:3fscTyozTmYJ", "14:dsppEkkJ6vIJ", "AA:q8Xw6c1aDJQJ",

			  "5C:1Yy-Elilf_wJ", "67:sYb7HA_7lCwJ", "99:kPiuzGwRUKIJ", "E2:3NCEoBX-P-gJ",

			  "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "84:h5LxuUdV03oJ", "D9:-Eup1YnE6-0J", "FC:7fjrc7LzjskJ", "03:LJouzaZ6nakJ",

			  "C3:3cyoIZdesRYJ", "EB:GumIzK6Xwv8J", "12:KYkKkVzbW-UJ", "AB:EHkO0tMtSN4J",

			  "30:vrZQ1rXJEg4J", "CE:AbXWG_eCFZYJ", "6B:EOhnwwtJMz4J", "5F:PyDg0PjbgxkJ",

			  "62:zzxVlWrc94AJ", "F2:CwpwlljQ5RUJ", "7F:9aqBJNfDaUEJ", "EE:CWVFy5sgo9MJ",

			  "4C:JDNgZADQwGkJ", "58:uJB16vUcH38J", "3D:Jij2JFUry5gJ", "C8:v7juRN1cZ4EJ",

			  "1E:16e59DDxd1QJ", "69:y1f3FuaNqhEJ", "B0:4cYEeKseVRYJ", "37:Hnm8AysFIvgJ",

			  "1D:qFpNdOAQ868J", "21:Ypml6jLyoaEJ", "34:UhJBrAWg8MAJ", "A0:xTaArVPF51IJ",

			  "EF:14kwBS4zH4kJ", "ED:eUzfBgFaYAYJ", "51:1RWzov84HGsJ", "72:WRUq1C2UF7YJ",

			  "24:TkF3I-3AqsoJ", "6E:Cxb4nb_-6wQJ", "CC:Cfwjydcm5VUJ", "94:3V77coCFoyUJ",

			  "0E:lfqBck_AckoJ", "C7:qTuFDoAZZAIJ", "E4:X9O9H0rf7UwJ", "A1:dh_aVJQg-fQJ",

			  "1B:SSUHFP88ICIJ", "9A:8LRpia1kQyoJ", "A8:6OB8e96ajfIJ", "8D:sekIn_D0FY4J",

			  "9D:sQbLyZCjcMwJ", "9C:at2mlybzsckJ", "2D:gagHFe3EgRcJ", "7C:sbERUkuwrgkJ",

			  "DF:jIbY1S4jGOQJ", "15:sQ5gc2skXDoJ", "B5:qpQ_jThwIfwJ", "E7:bujGGLRs6f8J",

			  "B9:FC8WDc6FfQAJ", "AC:7PqlCpunKtMJ", "90:6bCXBm-ZoeMJ", "05:kUDeAWh_o54J",

			  "46:BTA_qt_HhUkJ", "3E:3fscTyozTmYJ", "14:dsppEkkJ6vIJ", "AA:q8Xw6c1aDJQJ",

			  "5C:1Yy-Elilf_wJ", "67:sYb7HA_7lCwJ", "99:kPiuzGwRUKIJ", "E2:3NCEoBX-P-gJ",

			  "7D:gOHngHfzX8YJ", "2C:1j66DXvpuf8J", "07:rWnu8lphvZcJ", "CA:PFnVqjCPIKIJ",

			  "D7:ydg0kWMXDeoJ", "5A:n33l1U6zbEIJ", "57:hKzAPG_v3g4J", "3F:XGwx9FgVixQJ",

			  "36:abLa4yOIyW4J", "10:sMDENsqLts0J", "D2:gJsgjLw3nSQJ", "E0:Z_K4hdZq7h8J",

			  "75:3C-XszC6kyMJ", "77:rtHRfe9A27YJ", "97:-eflxIU8g04J", "F0:SwVcyzirnnQJ",

			  "65:7-hjyVDnHjEJ", "A3:hruuOW22_L8J", "F9:lEPeKx6ket4J", "88:M3DdYOcDTWwJ",

			  "FD:Cfwjydcm5VUJ", "42:HNXS6FBy7AUJ", "4A:-n4dEXmbmyMJ", "F7:IPDuatbjjRoJ",

			  "52:2xrwdGDvyaEJ", "5B:vEMG_nMaZygJ", "27:hfidgDDREMsJ", "70:DJ1-bAcdQE8J",

			  "78:aej8Xg6iVhkJ", "61:4SHBf-6ctTQJ", "BF:oJWMF8g4n98J", "3C:wbyliY5Fw7cJ",

			  "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "84:h5LxuUdV03oJ", "D9:-Eup1YnE6-0J", "FC:7fjrc7LzjskJ", "03:LJouzaZ6nakJ",

			  "C3:3cyoIZdesRYJ", "EB:GumIzK6Xwv8J", "12:KYkKkVzbW-UJ", "AB:EHkO0tMtSN4J",

			  "30:vrZQ1rXJEg4J", "CE:AbXWG_eCFZYJ", "6B:EOhnwwtJMz4J", "5F:PyDg0PjbgxkJ",

			  "62:zzxVlWrc94AJ", "F2:CwpwlljQ5RUJ", "7F:9aqBJNfDaUEJ", "EE:CWVFy5sgo9MJ",

			  "4C:JDNgZADQwGkJ", "58:uJB16vUcH38J", "3D:Jij2JFUry5gJ", "C8:v7juRN1cZ4EJ",

			  "1E:16e59DDxd1QJ", "69:y1f3FuaNqhEJ", "B0:4cYEeKseVRYJ", "37:Hnm8AysFIvgJ",

			  "1D:qFpNdOAQ868J", "21:Ypml6jLyoaEJ", "34:UhJBrAWg8MAJ", "A0:xTaArVPF51IJ",

			  "EF:14kwBS4zH4kJ", "ED:eUzfBgFaYAYJ", "51:1RWzov84HGsJ", "72:WRUq1C2UF7YJ",

			  "24:TkF3I-3AqsoJ", "6E:Cxb4nb_-6wQJ", "CC:Cfwjydcm5VUJ", "94:3V77coCFoyUJ",

			  "0E:lfqBck_AckoJ", "C7:qTuFDoAZZAIJ", "E4:X9O9H0rf7UwJ", "A1:dh_aVJQg-fQJ",

			  "1B:SSUHFP88ICIJ", "9A:8LRpia1kQyoJ", "A8:6OB8e96ajfIJ", "8D:sekIn_D0FY4J",

			  "9D:sQbLyZCjcMwJ", "9C:at2mlybzsckJ", "2D:gagHFe3EgRcJ", "7C:sbERUkuwrgkJ",

			  "DF:jIbY1S4jGOQJ", "15:sQ5gc2skXDoJ", "B5:qpQ_jThwIfwJ", "E7:bujGGLRs6f8J",

			  "B9:FC8WDc6FfQAJ", "AC:7PqlCpunKtMJ", "90:6bCXBm-ZoeMJ", "05:kUDeAWh_o54J",

			  "46:BTA_qt_HhUkJ", "3E:3fscTyozTmYJ", "14:dsppEkkJ6vIJ", "AA:q8Xw6c1aDJQJ",

			  "5C:1Yy-Elilf_wJ", "67:sYb7HA_7lCwJ", "99:kPiuzGwRUKIJ", "E2:3NCEoBX-P-gJ",

			  "7D:gOHngHfzX8YJ", "2C:1j66DXvpuf8J", "07:rWnu8lphvZcJ", "CA:PFnVqjCPIKIJ",

			  "D7:ydg0kWMXDeoJ", "5A:n33l1U6zbEIJ", "57:hKzAPG_v3g4J", "3F:XGwx9FgVixQJ",

			  "36:abLa4yOIyW4J", "10:sMDENsqLts0J", "D2:gJsgjLw3nSQJ", "E0:Z_K4hdZq7h8J",

			  "75:3C-XszC6kyMJ", "77:rtHRfe9A27YJ", "97:-eflxIU8g04J", "F0:SwVcyzirnnQJ",

			  "65:7-hjyVDnHjEJ", "A3:hruuOW22_L8J", "F9:lEPeKx6ket4J", "88:M3DdYOcDTWwJ",

			  "FD:Cfwjydcm5VUJ", "42:HNXS6FBy7AUJ", "4A:-n4dEXmbmyMJ", "F7:IPDuatbjjRoJ",

			  "52:2xrwdGDvyaEJ", "5B:vEMG_nMaZygJ", "27:hfidgDDREMsJ", "70:DJ1-bAcdQE8J",

			  "78:aej8Xg6iVhkJ", "61:4SHBf-6ctTQJ", "BF:oJWMF8g4n98J", "3C:wbyliY5Fw7cJ",

			  "BD:dyCQwPoi_QoJ", "6D:ROtjpJaaM3AJ", "D1:u77vCPi7NX4J", "DA:jr7lZOIXHE4J",

			  "80:hvDWT2JOOHIJ", "48:hfidgDDREMsJ", "8B:TMDNdWekwlEJ", "73:13SgY09fd9QJ",

			  "7E:tx3mt6GYR5oJ", "B3:JTLUoSksUFAJ", "63:DyaRtEUhtg4J", "0B:1q-lkiRNa7kJ",

			  "93:L3R7clDgu44J", "F5:o-lzUg48_5UJ", "01:6YJy7S3OGt8J", "26:vs3cbrj7Bi0J",

			  "7A:C6L9XGQS6i8J", "A4:iMWi3RNzLHUJ", "8F:2ELg7mGC5yUJ", "1A:rZEfAj2wHgYJ",

			  "A6:kP-bP5hmF9cJ", "18:KcznZAsaAk0J", "FF:kp-fx5_9CzsJ", "6C:5I-cinT_0_4J",

			  "8C:zaUGihUPAJwJ", "0F:AIt7UQkMmZkJ", "9B:FYtibg-zD20J", "B7:A2SiPb4NwWQJ",

			  "89:isoWmMm2QssJ", "C5:CibMCkpl2kAJ", "0D:g9lghtXOAFMJ", "38:gWcquZBJFPIJ",

			  "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "84:h5LxuUdV03oJ", "D9:-Eup1YnE6-0J", "FC:7fjrc7LzjskJ", "03:LJouzaZ6nakJ",

			  "C3:3cyoIZdesRYJ", "EB:GumIzK6Xwv8J", "12:KYkKkVzbW-UJ", "AB:EHkO0tMtSN4J",

			  "30:vrZQ1rXJEg4J", "CE:AbXWG_eCFZYJ", "6B:EOhnwwtJMz4J", "5F:PyDg0PjbgxkJ",

			  "62:zzxVlWrc94AJ", "F2:CwpwlljQ5RUJ", "7F:9aqBJNfDaUEJ", "EE:CWVFy5sgo9MJ",

			  "4C:JDNgZADQwGkJ", "58:uJB16vUcH38J", "3D:Jij2JFUry5gJ", "C8:v7juRN1cZ4EJ",

			  "1E:16e59DDxd1QJ", "69:y1f3FuaNqhEJ", "B0:4cYEeKseVRYJ", "37:Hnm8AysFIvgJ",

			  "1D:qFpNdOAQ868J", "21:Ypml6jLyoaEJ", "34:UhJBrAWg8MAJ", "A0:xTaArVPF51IJ",

			  "EF:14kwBS4zH4kJ", "ED:eUzfBgFaYAYJ", "51:1RWzov84HGsJ", "72:WRUq1C2UF7YJ",

			  "24:TkF3I-3AqsoJ", "6E:Cxb4nb_-6wQJ", "CC:Cfwjydcm5VUJ", "94:3V77coCFoyUJ",

			  "0E:lfqBck_AckoJ", "C7:qTuFDoAZZAIJ", "E4:X9O9H0rf7UwJ", "A1:dh_aVJQg-fQJ",

			  "1B:SSUHFP88ICIJ", "9A:8LRpia1kQyoJ", "A8:6OB8e96ajfIJ", "8D:sekIn_D0FY4J",

			  "9D:sQbLyZCjcMwJ", "9C:at2mlybzsckJ", "2D:gagHFe3EgRcJ", "7C:sbERUkuwrgkJ",

			  "DF:jIbY1S4jGOQJ", "15:sQ5gc2skXDoJ", "B5:qpQ_jThwIfwJ", "E7:bujGGLRs6f8J",

			  "B9:FC8WDc6FfQAJ", "AC:7PqlCpunKtMJ", "90:6bCXBm-ZoeMJ", "05:kUDeAWh_o54J",

			  "46:BTA_qt_HhUkJ", "3E:3fscTyozTmYJ", "14:dsppEkkJ6vIJ", "AA:q8Xw6c1aDJQJ",

			  "5C:1Yy-Elilf_wJ", "67:sYb7HA_7lCwJ", "99:kPiuzGwRUKIJ", "E2:3NCEoBX-P-gJ",

			  "7D:gOHngHfzX8YJ", "2C:1j66DXvpuf8J", "07:rWnu8lphvZcJ", "CA:PFnVqjCPIKIJ",

			  "D7:ydg0kWMXDeoJ", "5A:n33l1U6zbEIJ", "57:hKzAPG_v3g4J", "3F:XGwx9FgVixQJ",

			  "36:abLa4yOIyW4J", "10:sMDENsqLts0J", "D2:gJsgjLw3nSQJ", "E0:Z_K4hdZq7h8J",

			  "75:3C-XszC6kyMJ", "77:rtHRfe9A27YJ", "97:-eflxIU8g04J", "F0:SwVcyzirnnQJ",

			  "65:7-hjyVDnHjEJ", "A3:hruuOW22_L8J", "F9:lEPeKx6ket4J", "88:M3DdYOcDTWwJ",

			  "FD:Cfwjydcm5VUJ", "42:HNXS6FBy7AUJ", "4A:-n4dEXmbmyMJ", "F7:IPDuatbjjRoJ",

			  "52:2xrwdGDvyaEJ", "5B:vEMG_nMaZygJ", "27:hfidgDDREMsJ", "70:DJ1-bAcdQE8J",

			  "78:aej8Xg6iVhkJ", "61:4SHBf-6ctTQJ", "BF:oJWMF8g4n98J", "3C:wbyliY5Fw7cJ",

			  "BD:dyCQwPoi_QoJ", "6D:ROtjpJaaM3AJ", "D1:u77vCPi7NX4J", "DA:jr7lZOIXHE4J",

			  "80:hvDWT2JOOHIJ", "48:hfidgDDREMsJ", "8B:TMDNdWekwlEJ", "73:13SgY09fd9QJ",

			  "7E:tx3mt6GYR5oJ", "B3:JTLUoSksUFAJ", "63:DyaRtEUhtg4J", "0B:1q-lkiRNa7kJ",

			  "93:L3R7clDgu44J", "F5:o-lzUg48_5UJ", "01:6YJy7S3OGt8J", "26:vs3cbrj7Bi0J",

			  "7A:C6L9XGQS6i8J", "A4:iMWi3RNzLHUJ", "8F:2ELg7mGC5yUJ", "1A:rZEfAj2wHgYJ",

			  "A6:kP-bP5hmF9cJ", "18:KcznZAsaAk0J", "FF:kp-fx5_9CzsJ", "6C:5I-cinT_0_4J",

			  "8C:zaUGihUPAJwJ", "0F:AIt7UQkMmZkJ", "9B:FYtibg-zD20J", "B7:A2SiPb4NwWQJ",

			  "89:isoWmMm2QssJ", "C5:CibMCkpl2kAJ", "0D:g9lghtXOAFMJ", "38:gWcquZBJFPIJ",

			  "11:_TotMQXuZdgJ", "6A:24tx-mIpwmwJ", "8A:-FAi_YRhbrgJ", "1F:kQEIlYRdi2QJ",

			  "41:FoWhbx2IxiUJ", "4E:XFlq06C_YeMJ", "13:vKSdbEgs9aoJ", "D5:m415gDZ2B-UJ",

			  "AD:hWBrF9YLK78J", "2B:HqEtb7AADmMJ", "DE:eCFYrqg0WsEJ", "16:QLTeOYg-yB8J",

			  "BB:jk-d_Ua8BtIJ", "C9:u0J9izcWwvAJ", "91:NM3JgAgreZQJ", "04:sYb7HA_7lCwJ",

			  "08:VwTb3zO7tL8J", "DD:kwlsYdonpIgJ", "F4:_LIV45PtumsJ", "EC:rpMyxZmO6LwJ",

			  "54:bDNO5Nsce9EJ", "2A:XFgcPHiQ6SYJ", "71:b8UD6gHfO6IJ", "9E:rwusJNoWjiQJ",

			  "FB:c-wHLtEdkf0J", "AE:brdZuMrvAMQJ", "E8:mzaxbrVLBOUJ", "4B:6ye4zJaCE_oJ",

			  "22:6fwxGNK3bJgJ", "B8:jwvALeEfsbcJ", "33:Yqx6f_8RvNgJ", "C2:sxB_6QG_Qb4J",

			  "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "84:h5LxuUdV03oJ", "D9:-Eup1YnE6-0J", "FC:7fjrc7LzjskJ", "03:LJouzaZ6nakJ",

			  "C3:3cyoIZdesRYJ", "EB:GumIzK6Xwv8J", "12:KYkKkVzbW-UJ", "AB:EHkO0tMtSN4J",

			  "30:vrZQ1rXJEg4J", "CE:AbXWG_eCFZYJ", "6B:EOhnwwtJMz4J", "5F:PyDg0PjbgxkJ",

			  "62:zzxVlWrc94AJ", "F2:CwpwlljQ5RUJ", "7F:9aqBJNfDaUEJ", "EE:CWVFy5sgo9MJ",

			  "4C:JDNgZADQwGkJ", "58:uJB16vUcH38J", "3D:Jij2JFUry5gJ", "C8:v7juRN1cZ4EJ",

			  "1E:16e59DDxd1QJ", "69:y1f3FuaNqhEJ", "B0:4cYEeKseVRYJ", "37:Hnm8AysFIvgJ",

			  "1D:qFpNdOAQ868J", "21:Ypml6jLyoaEJ", "34:UhJBrAWg8MAJ", "A0:xTaArVPF51IJ",

			  "EF:14kwBS4zH4kJ", "ED:eUzfBgFaYAYJ", "51:1RWzov84HGsJ", "72:WRUq1C2UF7YJ",

			  "24:TkF3I-3AqsoJ", "6E:Cxb4nb_-6wQJ", "CC:Cfwjydcm5VUJ", "94:3V77coCFoyUJ",

			  "0E:lfqBck_AckoJ", "C7:qTuFDoAZZAIJ", "E4:X9O9H0rf7UwJ", "A1:dh_aVJQg-fQJ",

			  "1B:SSUHFP88ICIJ", "9A:8LRpia1kQyoJ", "A8:6OB8e96ajfIJ", "8D:sekIn_D0FY4J",

			  "9D:sQbLyZCjcMwJ", "9C:at2mlybzsckJ", "2D:gagHFe3EgRcJ", "7C:sbERUkuwrgkJ",

			  "DF:jIbY1S4jGOQJ", "15:sQ5gc2skXDoJ", "B5:qpQ_jThwIfwJ", "E7:bujGGLRs6f8J",

			  "B9:FC8WDc6FfQAJ", "AC:7PqlCpunKtMJ", "90:6bCXBm-ZoeMJ", "05:kUDeAWh_o54J",

			  "46:BTA_qt_HhUkJ", "3E:3fscTyozTmYJ", "14:dsppEkkJ6vIJ", "AA:q8Xw6c1aDJQJ",

			  "5C:1Yy-Elilf_wJ", "67:sYb7HA_7lCwJ", "99:kPiuzGwRUKIJ", "E2:3NCEoBX-P-gJ",

			  "7D:gOHngHfzX8YJ", "2C:1j66DXvpuf8J", "07:rWnu8lphvZcJ", "CA:PFnVqjCPIKIJ",

			  "D7:ydg0kWMXDeoJ", "5A:n33l1U6zbEIJ", "57:hKzAPG_v3g4J", "3F:XGwx9FgVixQJ",

			  "36:abLa4yOIyW4J", "10:sMDENsqLts0J", "D2:gJsgjLw3nSQJ", "E0:Z_K4hdZq7h8J",

			  "75:3C-XszC6kyMJ", "77:rtHRfe9A27YJ", "97:-eflxIU8g04J", "F0:SwVcyzirnnQJ",

			  "65:7-hjyVDnHjEJ", "A3:hruuOW22_L8J", "F9:lEPeKx6ket4J", "88:M3DdYOcDTWwJ",

			  "FD:Cfwjydcm5VUJ", "42:HNXS6FBy7AUJ", "4A:-n4dEXmbmyMJ", "F7:IPDuatbjjRoJ",

			  "52:2xrwdGDvyaEJ", "5B:vEMG_nMaZygJ", "27:hfidgDDREMsJ", "70:DJ1-bAcdQE8J",

			  "78:aej8Xg6iVhkJ", "61:4SHBf-6ctTQJ", "BF:oJWMF8g4n98J", "3C:wbyliY5Fw7cJ",

			  "BD:dyCQwPoi_QoJ", "6D:ROtjpJaaM3AJ", "D1:u77vCPi7NX4J", "DA:jr7lZOIXHE4J",

			  "80:hvDWT2JOOHIJ", "48:hfidgDDREMsJ", "8B:TMDNdWekwlEJ", "73:13SgY09fd9QJ",

			  "7E:tx3mt6GYR5oJ", "B3:JTLUoSksUFAJ", "63:DyaRtEUhtg4J", "0B:1q-lkiRNa7kJ",

			  "93:L3R7clDgu44J", "F5:o-lzUg48_5UJ", "01:6YJy7S3OGt8J", "26:vs3cbrj7Bi0J",

			  "7A:C6L9XGQS6i8J", "A4:iMWi3RNzLHUJ", "8F:2ELg7mGC5yUJ", "1A:rZEfAj2wHgYJ",

			  "A6:kP-bP5hmF9cJ", "18:KcznZAsaAk0J", "FF:kp-fx5_9CzsJ", "6C:5I-cinT_0_4J",

			  "8C:zaUGihUPAJwJ", "0F:AIt7UQkMmZkJ", "9B:FYtibg-zD20J", "B7:A2SiPb4NwWQJ",

			  "89:isoWmMm2QssJ", "C5:CibMCkpl2kAJ", "0D:g9lghtXOAFMJ", "38:gWcquZBJFPIJ",

			  "11:_TotMQXuZdgJ", "6A:24tx-mIpwmwJ", "8A:-FAi_YRhbrgJ", "1F:kQEIlYRdi2QJ",

			  "41:FoWhbx2IxiUJ", "4E:XFlq06C_YeMJ", "13:vKSdbEgs9aoJ", "D5:m415gDZ2B-UJ",

			  "AD:hWBrF9YLK78J", "2B:HqEtb7AADmMJ", "DE:eCFYrqg0WsEJ", "16:QLTeOYg-yB8J",

			  "BB:jk-d_Ua8BtIJ", "C9:u0J9izcWwvAJ", "91:NM3JgAgreZQJ", "04:sYb7HA_7lCwJ",

			  "08:VwTb3zO7tL8J", "DD:kwlsYdonpIgJ", "F4:_LIV45PtumsJ", "EC:rpMyxZmO6LwJ",

			  "54:bDNO5Nsce9EJ", "2A:XFgcPHiQ6SYJ", "71:b8UD6gHfO6IJ", "9E:rwusJNoWjiQJ",

			  "FB:c-wHLtEdkf0J", "AE:brdZuMrvAMQJ", "E8:mzaxbrVLBOUJ", "4B:6ye4zJaCE_oJ",

			  "22:6fwxGNK3bJgJ", "B8:jwvALeEfsbcJ", "33:Yqx6f_8RvNgJ", "C2:sxB_6QG_Qb4J",

			  "C1:RDCyEcRfSgYJ", "AF:crKfJjXw_5MJ", "53:0DMvhUWTKb8J", "DC:e91ckrM89cEJ",

			  "B4:WDoT2alpGIUJ", "4D:bFmzm_4qu2kJ", "C4:0vD_dZABzHMJ", "1C:sz33mz3wOUQJ",

			  "C6:E7OZk_UQ4CkJ", "98:cLfnrVphpKwJ", "06:oZjZXvq5HtcJ", "64:iVU_MpjctIIJ",

			  "9F:X-bZvp5icB4J", "95:fNZpE0lgEn8J", "A2:RxHFAXHJtyAJ", "E3:6HrAalsLflAJ",

			  "3B:KqNbjwDqqCMJ", "BE:0RUKM-BlaPsJ", "0A:1q-lkiRNa7kJ", "76:m1ROBo00yiEJ",

			  "32:SkX0iYQQY_AJ", "40:vl95ZOX_Q4IJ", "09:ep_I291MX2cJ", "2F:2H1dZ2lZ248J",

			  "D4:N-GQv-Nx1z8J", "19:f561wYNWgkEJ", "D3:UON-_Wr60O8J", "74:KQJPHtyNoj4J",

			  "3A:lzls7PYvd34J", "F1:yQFSR4MaUpwJ", "CF:oRRo9yGdXSQJ", "4F:W6-iAz1ZqaUJ",

			  "28:Kx7vy-VBtpYJ", "7B:PyDg0PjbgxkJ", "F3:Rd1xXw4alLkJ", "31:FeaBmsxfey8J",

			  "20:YsNAjeTGJVEJ", "A9:leYDU1RuuwIJ", "81:jufN-4x1RnAJ", "CB:IhifTIhRpmoJ",

			  "87:8Maz8upc508J", "FA:5dh9_zqVdkIJ", "BA:xyZftsH8RFsJ", "50:L_zmPN_48bMJ",

			  "49:iLtQE1Q7CWMJ", "D6:TuKm3fTasSYJ", "FE:pls5MhpkpK8J", "60:thDCBIkyQ2EJ",

			  "85:CizK2j2yCBIJ", "23:IkmAcC6lNjIJ", "F8:kRRYwomQWhIJ", "8E:_v-YolETks4J",

			  "E1:Bf8Ltpee0v4J", "D0:0YM5CoDmx8MJ", "92:D9zUj4QVc2sJ", "0C:FsKZkZ1R7t4J",

			  "45:NVX4OCi9WXAJ", "A7:aQAFb1464l4J", "68:aej8Xg6iVhkJ", "A5:EHkO0tMtSN4J",

			  "F6:49-gxPeD0IwJ", "5E:bpLwYqr-990J", "C0:mawuaWJa1boJ", "00:NEU6wRmGVq4J",

			  "84:h5LxuUdV03oJ", "D9:-Eup1YnE6-0J", "FC:7fjrc7LzjskJ", "03:LJouzaZ6nakJ",

			  "C3:3cyoIZdesRYJ", "EB:GumIzK6Xwv8J", "12:KYkKkVzbW-UJ", "AB:EHkO0tMtSN4J",

			  "30:vrZQ1rXJEg4J", "CE:AbXWG_eCFZYJ", "6B:EOhnwwtJMz4J", "5F:PyDg0PjbgxkJ",

			  "62:zzxVlWrc94AJ", "F2:CwpwlljQ5RUJ", "7F:9aqBJNfDaUEJ", "EE:CWVFy5sgo9MJ",

			  "4C:JDNgZADQwGkJ", "58:uJB16vUcH38J", "3D:Jij2JFUry5gJ", "C8:v7juRN1cZ4EJ",

			  "1E:16e59DDxd1QJ", "69:y1f3FuaNqhEJ", "B0:4cYEeKseVRYJ", "37:Hnm8AysFIvgJ",

			  "1D:qFpNdOAQ868J", "21:Ypml6jLyoaEJ", "34:UhJBrAWg8MAJ", "A0:xTaArVPF51IJ",

			  "EF:14kwBS4zH4kJ", "ED:eUzfBgFaYAYJ", "51:1RWzov84HGsJ", "72:WRUq1C2UF7YJ",

			  "24:TkF3I-3AqsoJ", "6E:Cxb4nb_-6wQJ", "CC:Cfwjydcm5VUJ", "94:3V77coCFoyUJ",

			  "0E:lfqBck_AckoJ", "C7:qTuFDoAZZAIJ", "E4:X9O9H0rf7UwJ", "A1:dh_aVJQg-fQJ",

			  "1B:SSUHFP88ICIJ", "9A:8LRpia1kQyoJ", "A8:6OB8e96ajfIJ", "8D:sekIn_D0FY4J",

			  "9D:sQbLyZCjcMwJ", "9C:at2mlybzsckJ", "2D:gagHFe3EgRcJ", "7C:sbERUkuwrgkJ",

			  "DF:jIbY1S4jGOQJ", "15:sQ5gc2skXDoJ", "B5:qpQ_jThwIfwJ", "E7:bujGGLRs6f8J",

			  "B9:FC8WDc6FfQAJ", "AC:7PqlCpunKtMJ", "90:6bCXBm-ZoeMJ", "05:kUDeAWh_o54J",

			  "46:BTA_qt_HhUkJ", "3E:3fscTyozTmYJ", "14:dsppEkkJ6vIJ", "AA:q8Xw6c1aDJQJ",

			  "5C:1Yy-Elilf_wJ", "67:sYb7HA_7lCwJ", "99:kPiuzGwRUKIJ", "E2:3NCEoBX-P-gJ",

			  "7D:gOHngHfzX8YJ", "2C:1j66DXvpuf8J", "07:rWnu8lphvZcJ", "CA:PFnVqjCPIKIJ",

			  "D7:ydg0kWMXDeoJ", "5A:n33l1U6zbEIJ", "57:hKzAPG_v3g4J", "3F:XGwx9FgVixQJ",

			  "36:abLa4yOIyW4J", "10:sMDENsqLts0J", "D2:gJsgjLw3nSQJ", "E0:Z_K4hdZq7h8J",

			  "75:3C-XszC6kyMJ", "77:rtHRfe9A27YJ", "97:-eflxIU8g04J", "F0:SwVcyzirnnQJ",

			  "65:7-hjyVDnHjEJ", "A3:hruuOW22_L8J", "F9:lEPeKx6ket4J", "88:M3DdYOcDTWwJ",

			  "FD:Cfwjydcm5VUJ", "42:HNXS6FBy7AUJ", "4A:-n4dEXmbmyMJ", "F7:IPDuatbjjRoJ",

			  "52:2xrwdGDvyaEJ", "5B:vEMG_nMaZygJ", "27:hfidgDDREMsJ", "70:DJ1-bAcdQE8J",

			  "78:aej8Xg6iVhkJ", "61:4SHBf-6ctTQJ", "BF:oJWMF8g4n98J", "3C:wbyliY5Fw7cJ",

			  "BD:dyCQwPoi_QoJ", "6D:ROtjpJaaM3AJ", "D1:u77vCPi7NX4J", "DA:jr7lZOIXHE4J",

			  "80:hvDWT2JOOHIJ", "48:hfidgDDREMsJ", "8B:TMDNdWekwlEJ", "73:13SgY09fd9QJ",

			  "7E:tx3mt6GYR5oJ", "B3:JTLUoSksUFAJ", "63:DyaRtEUhtg4J", "0B:1q-lkiRNa7kJ",

			  "93:L3R7clDgu44J", "F5:o-lzUg48_5UJ", "01:6YJy7S3OGt8J", "26:vs3cbrj7Bi0J",

			  "7A:C6L9XGQS6i8J", "A4:iMWi3RNzLHUJ", "8F:2ELg7mGC5yUJ", "1A:rZEfAj2wHgYJ",

			  "A6:kP-bP5hmF9cJ", "18:KcznZAsaAk0J", "FF:kp-fx5_9CzsJ", "6C:5I-cinT_0_4J",

			  "8C:zaUGihUPAJwJ", "0F:AIt7UQkMmZkJ", "9B:FYtibg-zD20J", "B7:A2SiPb4NwWQJ",

			  "89:isoWmMm2QssJ", "C5:CibMCkpl2kAJ", "0D:g9lghtXOAFMJ", "38:gWcquZBJFPIJ",

			  "11:_TotMQXuZdgJ", "6A:24tx-mIpwmwJ", "8A:-FAi_YRhbrgJ", "1F:kQEIlYRdi2QJ",

			  "41:FoWhbx2IxiUJ", "4E:XFlq06C_YeMJ", "13:vKSdbEgs9aoJ", "D5:m415gDZ2B-UJ",

			  "AD:hWBrF9YLK78J", "2B:HqEtb7AADmMJ", "DE:eCFYrqg0WsEJ", "16:QLTeOYg-yB8J",

			  "BB:jk-d_Ua8BtIJ", "C9:u0J9izcWwvAJ", "91:NM3JgAgreZQJ", "04:sYb7HA_7lCwJ",

			  "08:VwTb3zO7tL8J", "DD:kwlsYdonpIgJ", "F4:_LIV45PtumsJ", "EC:rpMyxZmO6LwJ",

			  "54:bDNO5Nsce9EJ", "2A:XFgcPHiQ6SYJ", "71:b8UD6gHfO6IJ", "9E:rwusJNoWjiQJ",

			  "FB:c-wHLtEdkf0J", "AE:brdZuMrvAMQJ", "E8:mzaxbrVLBOUJ", "4B:6ye4zJaCE_oJ",

			  "22:6fwxGNK3bJgJ", "B8:jwvALeEfsbcJ", "33:Yqx6f_8RvNgJ", "C2:sxB_6QG_Qb4J",

			  "C1:RDCyEcRfSgYJ", "AF:crKfJjXw_5MJ", "53:0DMvhUWTKb8J", "DC:e91ckrM89cEJ",

			  "B4:WDoT2alpGIUJ", "4D:bFmzm_4qu2kJ", "C4:0vD_dZABzHMJ", "1C:sz33mz3wOUQJ",

			  "C6:E7OZk_UQ4CkJ", "98:cLfnrVphpKwJ", "06:oZjZXvq5HtcJ", "64:iVU_MpjctIIJ",

			  "9F:X-bZvp5icB4J", "95:fNZpE0lgEn8J", "A2:RxHFAXHJtyAJ", "E3:6HrAalsLflAJ",

			  "3B:KqNbjwDqqCMJ", "BE:0RUKM-BlaPsJ", "0A:1q-lkiRNa7kJ", "76:m1ROBo00yiEJ",

			  "32:SkX0iYQQY_AJ", "40:vl95ZOX_Q4IJ", "09:ep_I291MX2cJ", "2F:2H1dZ2lZ248J",

			  "D4:N-GQv-Nx1z8J", "19:f561wYNWgkEJ", "D3:UON-_Wr60O8J", "74:KQJPHtyNoj4J",

			  "3A:lzls7PYvd34J", "F1:yQFSR4MaUpwJ", "CF:oRRo9yGdXSQJ", "4F:W6-iAz1ZqaUJ",

			  "29:C-dd67rIqqwJ", "66:GO4Tc1u-ugYJ", "DB:eC0ElD1t9J0J", "43:d6NIXjVJ7KUJ",

			  "82:Io93RHeLXQEJ", "CD:NXjNyJgzy4IJ", "25:_n6PawUEkHcJ", "B2:Lc1qYSv3UhUJ",

			  "BC:I-13107CCxIJ", "83:Y61PENPCqEkJ", "EA:9TqNFzh4Z_oJ", "47:NwDZxatOEc4J",

			  "B1:B-TsYBhWagAJ", "6F:fHVktF7dziUJ", "D8:xzpGFu00WYwJ", "35:9Rk1mF1piREJ",

			  "E9:JFkbdecjI8MJ", "96:CBItbsrnoXMJ", "55:noMLzjxCNboJ", "86:sKdRXX1_KzwJ",

			  "B6:VUPwfdt9GXQJ", "39:rCHm8PFbAI8J", "5D:4NwxRMobURQJ", "79:kiWLB6a7E5MJ",

			  "02:wS3Nm-eK00cJ", "E5:eRnVynYCgSsJ", "2E:Pus5p0uY2KkJ", "17:tOuRl4j_h8EJ",

			  "56:YmAwCsJOu2kJ", "59:zl6uZ0sBNPkJ", "E6:gDEADZ7sg_4J", "44:IrzQsQh4XsIJ",

			};

		Map entries = new HashMap();
		for (String clue : clues) {
			String key = clue.substring(0, clue.indexOf(':'));
			String val = clue.substring(clue.indexOf(':') + 1, clue.length());

			entries.put(Integer.parseInt(key, RADIX_16), val);
		}
		return entries;
    }
}</pre>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/284/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/284/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/284/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=284&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/06/30/image-a-nation-challenge-using-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>

		<media:content url="http://lh6.ggpht.com/_y9ipUdwtLqo/SkqPhumNqJI/AAAAAAAAAUQ/zU-BldEYV-c/s400/Picture%201.jpg" medium="image">
			<media:title type="html">Sceenshot</media:title>
		</media:content>
	</item>
		<item>
		<title>Setting up logging mechanism in Django</title>
		<link>http://110j.wordpress.com/2009/06/27/setting-up-logging-mechanism-in-django/</link>
		<comments>http://110j.wordpress.com/2009/06/27/setting-up-logging-mechanism-in-django/#comments</comments>
		<pubDate>Sat, 27 Jun 2009 22:30:28 +0000</pubDate>
		<dc:creator>Omer Haderi</dc:creator>
				<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://110j.wordpress.com/?p=277</guid>
		<description><![CDATA[Coming from a Java world where projects and libraries without logging are unheard, it was a big surprise to see that all django apps that I have downloaded so far do not include logging, even though Python has a very good support for logging, it was inspired by the log4j. For a reason that I [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=277&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Coming from a Java world where projects and libraries without logging are unheard, it was a big surprise to see that all django apps that I have downloaded so far do not include logging, even though Python has a very good support for logging, it was inspired by the log4j. For a reason that I do not know they choose not to log, I suppose it is a kind of situation where everyone else knows but me!</p>
<p>So as a java developer used to work with a lot of logging I decided to put in place a logging mechanism for my django project and fortunately python has great support for that:<br />
1. create a logging.conf file for the logging options<br />
2. configuring the logging module<br />
3. using the logger in my modules</p>
<p>So here is my simple set up:<br />
1. create a logging.conf file for the logging options with the following content:</p>
<pre>[loggers]
keys=root,core_view_logger

[handlers]
keys=consoleHandler,core_view_handler

[formatters]
keys=simpleFormatter

[logger_root]
level=NOTSET
handlers=consoleHandler

[logger_core_view_logger]
level=DEBUG
handlers=core_view_handler
qualname=core_view_logger
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[handler_core_view_handler]
class=handlers.RotatingFileHandler
level=DEBUG
formatter=simpleFormatter
args=('logs/core_logger.log', 'a', 1000000, 4)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=</pre>
<p>2. configuring the logging module in the settings.py</p>
<pre>import logging
import logging.config

LOGGING_CONFIG = 'logging.conf' # logging configuration file
logging.config.fileConfig(LOGGING_CONFIG)</pre>
<p>3.use the logger in your modules</p>
<pre>import logging 

logger = logging.getLogger('core_view_logger');

def doSomething(request):
    logger.debug('This is a debug message')
    logger.info('This is an info message')
    logger.warning('This is a warning message')
    logger.error('This is an error message')
    logger.critical('Yes it is so simple :)')</pre>
<p>That&#8217;s all folks!<br />
But of course this is a simple set up and you can do more much more:</p>
<ul>
<li>Logging to multiple destinations</li>
<li>Adding contextual information to the output</li>
<li>Send and receive logging information across network</li>
<li>Send logging information through email</li>
</ul>
<p>Check the python official documentation for all the options <a title="Python Docs" href="http://docs.python.org/library/logging.html" target="_blank">http://docs.python.org/library/logging.html</a></p>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/110j.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/110j.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/110j.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/110j.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/110j.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/110j.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/110j.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/110j.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/110j.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/110j.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/110j.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/110j.wordpress.com/277/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/110j.wordpress.com/277/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/110j.wordpress.com/277/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=110j.wordpress.com&amp;blog=4040246&amp;post=277&amp;subd=110j&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://110j.wordpress.com/2009/06/27/setting-up-logging-mechanism-in-django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/9c36e5681a3f88b95dd5d402fb2baf01?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96" medium="image">
			<media:title type="html">110j</media:title>
		</media:content>
	</item>
	</channel>
</rss>
