<?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/"
	>

<channel>
	<title>Object Partners Inc &#187; Blog</title>
	<atom:link href="http://www.objectpartners.com/category/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.objectpartners.com</link>
	<description>Object Partners Inc.</description>
	<lastBuildDate>Tue, 31 Jan 2012 15:39:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Adding a Web Module to a Gradle Project</title>
		<link>http://www.objectpartners.com/2012/01/31/adding-a-web-module-to-a-gradle-project/</link>
		<comments>http://www.objectpartners.com/2012/01/31/adding-a-web-module-to-a-gradle-project/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 15:39:31 +0000</pubDate>
		<dc:creator>jholland</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Gradle Jetty JEE Java War]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4556</guid>
		<description><![CDATA[It&#8217;s common in a lot of projects the need to separate parts of the system into their own modules. Gradle is well suited for this approach by allowing a single project to have many logically different modules. This post is continuation of my previous post Building With Gradle. In this post we&#8217;ll create a second [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s common in a lot of projects the need to separate parts of the system into their own modules.  Gradle is well suited for this approach by allowing a single project to have many logically different modules.  This post is continuation of my previous post <a href="http://www.objectpartners.com/?p=4003">Building With Gradle</a>. </p>
<p>In this post we&#8217;ll create a second module for deploying to a servlet container. We&#8217;ll call this module example-web and it will produce a WAR artifact for deployment in Tomcat, Jetty, or any other suitable application server.</p>
<p>So lets roll&#8230;</p>
<p><span id="more-4556"></span></p>
<p>Lets review, currently we have our project structured as shown below:</p>
<pre>
	trunk
		example-core
		example-parent
</pre>
<p>Now we&#8217;ll add one more directory for our web module and our new structure will be so:</p>
<pre>
	trunk
		example-core
		example-parent
		example-web
</pre>
<p>Now we&#8217;ll need to crack open the settings.Gradle file located in trunk and change it to add the new module.</p>
<p><script src="https://gist.github.com/1515224.js?file=settings.Gradle"></script></p>
<p>At this point we can start creating the web module, we&#8217;ll start with a simple build file (build.Gradle in the example-web directory) to get it going.</p>
<p><script src="https://gist.github.com/1515256.js?file=build.Gradle"></script></p>
<p>At the top of the file you notice the apply plugin: &#8216;war&#8217; line. The war plugin is a standard Gradle plugin that is used to create compliant war archives. The war plugin also includes the java plugin so all of those conventions will also be present. The default layout for the source, test and web files is as follows.</p>
<pre>
	example-web
		src
			main
				java
				resources
				webapp
			test
				java
				resources
</pre>
<p>All source files are found in the main directory while tests are in tests.  Within the main directory the java, resources, and webapp directories hold java source files, non-java resource files and the webapp files (css, html, css, web.xml etc.) respectively.</p>
<p>I&#8217;ve built a simple web app that greets the guest when the root of the application is accessed, this builds on the previous post. To do this I needed to add a dependency on the javax servlet API. But, since the official API jar dependency isn&#8217;t found in maven central I used the one from the geronimo project. I&#8217;ve also added a dependency to the example-core project.  </p>
<p>In order to include the project as a dependency I used two lines:</p>
<pre>
	dependsOn(':example-core')
</pre>
<p>And</p>
<pre>
	compile project(':example-core')
</pre>
<p>The first line is used by Gradle internally to order how projects are built. Without the dependsOn clause Gradle would build them in the order found, usually alphabetical. The second line adds the example-core project to the compile dependencies for example-web. You should always include both of these lines when adding a project as a dependency.  </p>
<p>Finally we&#8217;ll add the jetty plugin to the example-web build file so we can run the app. The final build file will appear as below.</p>
<p><script src="https://gist.github.com/1525011.js?file=build.Gradle"></script></p>
<p>Now we can start the webapp by issuing the Gradle task
<pre>jettyRun</pre>
<p>. Here&#8217;s the output:</p>
<p><script src="https://gist.github.com/1525223.js?file=jettyRun.out"></script></p>
<p>At this point a jetty instance should be running on port 8080 with our application.  This link should get you to the front page <a href="http://localhost:8080/example-web/">http://localhost:8080/example-web/</a>. To kill the server issue a Ctrl-C at the command line.</p>
<p>Well that wraps up setting up the web module and if you&#8217;d like you can still go back and run example-core.  The implementation is still there and works exactly the same as the web version. As usual you can find the project at <a href="https://github.com/jhollandus/opiblog">https://github.com/jhollandus/opiblog</a>,  for this post look at the <a href="https://github.com/jhollandus/opiblog/zipball/p2">p2 tag</a>.  You&#8217;ll also note that I&#8217;ve added eclipse files to the projects.  In the next post I&#8217;ll go through how to set that up so you can keep it up to date with the Gradle build files as they change.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/31/adding-a-web-module-to-a-gradle-project/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building with Gradle</title>
		<link>http://www.objectpartners.com/2012/01/26/building-with-gradle/</link>
		<comments>http://www.objectpartners.com/2012/01/26/building-with-gradle/#comments</comments>
		<pubDate>Thu, 26 Jan 2012 14:41:09 +0000</pubDate>
		<dc:creator>jholland</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Ant]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4003</guid>
		<description><![CDATA[Recently I was on a project that needed to chose a build system. We looked at the usual suspects, ant and maven and after having less then wonderful experiences with both I looked for an alternative. That&#8217;s where Gradle came in. In this post I&#8217;m going to go through getting started on a simple project. [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was on a project that needed to chose a build system. We looked at the usual suspects, ant and maven and after having less then wonderful experiences with both I looked for an alternative.  That&#8217;s where Gradle came in.  In this post I&#8217;m going to go through getting started on a simple project.  In subsequent posts I plan on increasing the complexity and offer solutions to common issues found on a project.</p>
<h3><strong>Why choose gradle</strong></h3>
<p>I&#8217;ll assume since you&#8217;re here that you have an interest in gradle and may have already scoured the internet for comparisons of it with other popular build tools (Ant and Maven).  Below are some of the reasons why I chose Gradle for my project and not the others.</p>
<p>1. Gradle is built on top of a full fledged programming language (groovy) and has direct access to all of it&#8217;s goodies.  No reliance on plugins for custom scripting (Maven, Ant plugin), no overhead of creating custom Java classes or plugins, and finally no angle bracket soup (ant scripting).</p>
<p>2. Gradle out of the box has support for dependency management via Ivy and is compatible with all Maven repositories including enterprise ones (Artifactory, Nexus, etc.).</p>
<p>3. Gradle supports multi-module projects without having to reinvent the wheel (ant).</p>
<p>4. Finally, Gradle is extremely flexible allowing for just about any build configuration you could imagine unlike other build tools (I&#8217;m looking at you Maven).</p>
<p><span id="more-4003"></span></p>
<p>First thing first, install gradle.  There is good online documentation on how this is done here <a href="http://gradle.org/installation">http://gradle.org/installation</a>.</p>
<h3><strong>Project Layout</strong></h3>
<p>So lets get started with our first project.  For this post lets keep it simple with a single module.  We&#8217;ll set it up though with the forethought that we may be adding more modules in the future.</p>
<p>I&#8217;ll use a flat layout since this is most compatible with the Eclipse IDE. The project layout will look thusly:</p>
<ul>
<li>trunk
<ul>
<li>example-core</li>
<li>example-parent</li>
</ul>
</li>
</ul>
<p>Gradle also allows for a hierarchical layout but I&#8217;ve found that Eclipse does not do well with projects that include sub-projects.</p>
<p>The modules are intended to be used in the following manner:</p>
<dl>
<dt><strong>example-core</strong></dt>
<dd style="margin-left: 2em;">Contains domain classes, services, and any data access objects.  Really the essence of the whole system.</dd>
<p></p>
<dt><strong>example-parent</strong></dt>
<dd style="margin-left: 2em;">Contains common configuration information for the entire projects (all modules).  This is where our main build.gradle script will be found.</dd>
</dl>
<p>Most of our build configuration will be done  in example-parent with details specific to modules found in the module directories.  The module build files usually contain information on dependencies and artifacts.  They&#8217;ll also have custom tasks that are specific to that module. But before we start our build file we need to setup one other piece of information, the settings.gradle file.</p>
<p>&nbsp;</p>
<h3><strong>settings.gradle</strong></h3>
<p>The settings.gradle file is responsible for letting gradle know what modules are part of the project and where they are.  By default Gradle assumes that settings.gradle will be found in the directory in which the build is executed but if it&#8217;s not then gradle will look in the parent directory. If still not found in the parent it will continue going up the directory hierarchy until it&#8217;s found.  There is one exception though, if there happens to be a directory named &#8216;master&#8217; then it will look in there also.  This facilitates flat layouts.</p>
<p>Here&#8217;s our settings.gradle file found in the trunk directory:</p>
<p><script src="https://gist.github.com/1514257.js?file=settings.gradle"></script></p>
<p>Now with that there we are ready to create our first build script in example-parent.</p>
<p>&nbsp;</p>
<h3>build.gradle</h3>
<p>All default gradle build scripts should be named build.gradle, it&#8217;s the name that the gradle command will look for by default when run. Let&#8217;s look at our simple build script, I&#8217;ll go through the sections afterwards.</p>
<p><script src="https://gist.github.com/1514282.js?file=build.gradle"></script></p>
<p>Now let&#8217;s walk through it.  Remember that this script is really a groovy script with a very detailed and structured DSL, you can do anything in this DSL that you could do in groovy.  An example is the SLF4J_VERSION variable set at the top.  This is a regular old groovy variable and is used later in constructing the dependency strings (using GString replacement).</p>
<p>The group and version propeties set at the top are part of the Project object which is the groovy object that the DSL is delegating to by default.  By setting these properties you tell gradle what group and version this project is and can be used for dependency management.  If this project is pushed into a maven repository it will use these properties as part of the pom.xml.</p>
<p>Next is the allprojects block which is part of the DSL. This block will apply all configurations found in the block to each module in the project. For this example that would be example-parent and example-core. You are free to do any configuration you care to here as if this was a single module project.</p>
<p>Inside the allprojects block is the repositories block.  This block is used to configure what repositories will be used to locate dependencies. Here I have used a convenient method to include the maven central repository.  Gradle supports all kinds of different repositories from maven and ivy to even a  file system. It is extremely flexible. In a previous project I was on we stored all of our dependenies in source control inside a subdirectory found in our project and Gradle used that as it&#8217;s repository.</p>
<p>The subprojects block is used to configure all projects except for the root project. Generally the root project does not produce any artifacts therefore won&#8217;t have a need for many configuration parts. Here we set up a couple of configurations.</p>
<p>Configurations are used to store sets of dependencies and files.  In this example I&#8217;ve created two common configurations for common test dependencies and common compile dependencies later on we&#8217;ll use these in our other modules.</p>
<p>The dependencies block is where all dependencies for this project are declared.  A dependency needs to be added to a configuration, here I&#8217;ve added JUnit to the commonTest configuration and slf4j with log4j to the common configuration. You&#8217;ll notice that the dependencies are declared using a string.  Gradle supports a few different ways of doing this along with methods for excluding transitive dependencies but I didn&#8217;t do that here. The pattern I&#8217;m following is &#8216;group:name:version&#8217;.</p>
<h3>example-core build.gradle</h3>
<p>The example-core project is going to be a simple java project with one main file that prints out &#8220;Hello World&#8221; (I know, I know). We&#8217;ll set this up so it can be run from the command line using gradle. We&#8217;ll also make it so we can create an archive for deployment, therefore everyone can enjoy our genius easily.</p>
<p>Here&#8217;s the build.gradle file found in example-core:</p>
<p><script src="https://gist.github.com/1514287.js?file=build.gradle"></script></p>
<p>Besides the code for the HelloWorld class this is all you need to set it up.  If you look at the top of the script you may notice the &#8216;apply plugin:&#8217; stanza.  This imports a plugin into this script and applies its conventions to the build.  In this case it also imports the java plugin as part of it.  You can apply as many plugins as you like and you can also use plugins that are imported from any URL (file, http, etc.), the application plugin is built into gradle by default.</p>
<p>I then set the version of this module. The group is inherited from the root project so we don&#8217;t need to set it here also, in fact the version was too but I overrode it.</p>
<p>For configurations I merely extended the compile and compileTest configurations to include the ones we set up in example-parent.  You may be asking yourself where compileTest and compile came from.  Well, those were brought in via the apply plugin statement. They are standard configurations used by the java plugin.</p>
<p>For this example I don&#8217;t require any additional dependencies so I left it empty for display purposes. In real use you would omit it all together.</p>
<p>Finally, I set the mainClassName property to the fully qualified name of the class that I want to be executed when this application is run. This property was added by the application plugin.</p>
<p><strong>Performing a Build</strong></p>
<p>Now we are ready to perform a build.  I&#8217;ve skipped the part were we actually write the code but you can get it at github (<a href="https://github.com/jhollandus/opiblog">https://github.com/jhollandus/opiblog</a>), look at the <a href="https://github.com/jhollandus/opiblog/zipball/p1">p1 tag</a> for this post.</p>
<p>First, open a command shell (cmd, bash, etc.) and change to the example-core directory.  From there execute this command:</p>
<pre>gradle build</pre>
<p>You should see gradle startup and then echo out the different parts of the build lifecycle it&#8217;s going through.  In this case we don&#8217;t have any unit tests so that&#8217;ll go quickly but the java plugin brings in an entire build cycle that includes a test phase. The output should resemble this:</p>
<pre style="background-color: #DCF3DC; padding: 0.5em; overflow: auto;border: 1px solid black;">
jholland-mac:example-core jholland$ gradle build
:example-core:compileJava
Download http://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.4/slf4j-api-1.6.4.pom
Download http://repo1.maven.org/maven2/org/slf4j/slf4j-parent/1.6.4/slf4j-parent-1.6.4.pom
Download http://repo1.maven.org/maven2/org/slf4j/slf4j-log4j12/1.6.4/slf4j-log4j12-1.6.4.pom
Download http://repo1.maven.org/maven2/log4j/log4j/1.2.14/log4j-1.2.14.pom
Download http://repo1.maven.org/maven2/log4j/log4j/1.2.16/log4j-1.2.16.pom
Download http://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.4/slf4j-api-1.6.4.jar
Download http://repo1.maven.org/maven2/org/slf4j/slf4j-log4j12/1.6.4/slf4j-log4j12-1.6.4.jar
Download http://repo1.maven.org/maven2/log4j/log4j/1.2.16/log4j-1.2.16.jar
:example-core:processResources
:example-core:classes
:example-core:jar
:example-core:assemble
:example-core:compileTestJava UP-TO-DATE
:example-core:processTestResources UP-TO-DATE
:example-core:testClasses UP-TO-DATE
:example-core:test
Download http://repo1.maven.org/maven2/junit/junit/4.8.2/junit-4.8.2.pom
Download http://repo1.maven.org/maven2/junit/junit/4.8.2/junit-4.8.2.jar
:example-core:check
:example-core:build

BUILD SUCCESSFUL

Total time: 5.031 secs
jholland-mac:example-core jholland$
</pre>
<p>As you can see Gradle downloaded the necessary dependencies and then compiled the code.  If you build again you&#8217;ll find that it won&#8217;t download the dependencies again and it won&#8217;t recompile your code. Gradle fully supports incremental builds and will only process files that have changed.</p>
<p>Now if you run &#8216;gradle run&#8217; it will execute our main class.  You should see the following output, note that the logging is currently also going to stdout.</p>
<pre style="background-color: #DCF3DC; padding: 0.5em;border: 1px solid black;">
jholland-mac:example-core jholland$ gradle run
:example-core:compileJava UP-TO-DATE
:example-core:processResources UP-TO-DATE
:example-core:classes UP-TO-DATE
:example-core:run
21:54:47,089        DEBUG HelloWorld:10 - Executing...
Hello World

BUILD SUCCESSFUL

Total time: 2.736 secs
jholland-mac:example-core jholland$
</pre>
<p>Finally if you run &#8216;gradle distZip&#8217; Gradle will produce a deployable zip file that you can use to execute the program. You can find the zip archive example-core-1.0-SNAPSHOT.zip in the build/distributions directory.  The distZip and run tasks are a part of the application plugin.</p>
<p>And that about all for now.  In the next post I&#8217;ll create an additional module to show how multi module builds work. In the meantime check out the Gradle documentation online at <a href="http://gradle.org/documentation">http://gradle.org/documentation</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/26/building-with-gradle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Spring @StrictDateTimeFormat Annotation</title>
		<link>http://www.objectpartners.com/2012/01/19/creating-a-spring-strictdatetimeformat-annotation/</link>
		<comments>http://www.objectpartners.com/2012/01/19/creating-a-spring-strictdatetimeformat-annotation/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 15:40:21 +0000</pubDate>
		<dc:creator>Jeff Sheets</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Annotations]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4447</guid>
		<description><![CDATA[Spring Formatters and Converters make it easy to annotate fields for conversion from Objects to Strings, and are especially useful in web apps. But there is no easy or straightforward way to strictly validate the String before parsing into an object, without creating a custom Formatter. Here is a reusable solution that uses a RegexParserDecorator [...]]]></description>
			<content:encoded><![CDATA[<p>Spring Formatters and Converters make it easy to annotate fields for conversion from Objects to Strings, and are especially useful in web apps. But there is no easy or straightforward way to strictly validate the String before parsing into an object, without creating a custom Formatter. Here is a reusable solution that uses a RegexParserDecorator to decorate any Spring Formatter to apply a regex pattern, in turn creating a @StrictDateTimeFormat annotation as an example implementation.</p>
<p><strong>A little background</strong>: Spring 3.0 brought the <a href="http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/spring-framework-reference.html#format-annotations-api">Converter and Formatter framework</a> with a concise <a href="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/format/annotation/DateTimeFormat.html">@DateTimeFormat annotation</a>, simplifying the Date to Object conversion that previously took custom binders or other wiring code. With @DateTimeFormat you can easily supply a String pattern used to parse and print a Date (or joda DateTime) object. However, the annotation does not strictly validate the String before converting to a Date. For instance, supplying a MM/dd/yyyy pattern does NOT enforce a 4 digit year. Instead a 2 digit year will be accepted and parsed using the SimpleDateFormat rules. Similar loose checking goes for 1 digit days and months, and also the slash character used as a separator.  It would be easy to just throw the <a href="http://docs.oracle.com/javaee/6/api/javax/validation/constraints/Pattern.html">@Pattern tag</a> onto your Date field except that @Pattern is <a href="http://docs.jboss.org/hibernate/validator/4.2/reference/en-US/html/validator-usingvalidator.html#validator-defineconstraints-builtin">only allowed on String fields</a>. Combining @Pattern and @DateTimeFormat is what drove the creation of @StrictDateTimeFormat:</p>
<pre><code>
//sample usage using defaults for regex and pattern
@StrictDateTimeFormat
private DateTime birthday;</code></pre>
<p>Read more below for a discussion and snippets of code, and the entire codeset with comments is available on <a href="https://github.com/jeffsheets/StrictDateTimeFormat">github</a>.<br />
<span id="more-4447"></span><br />
<strong>The RegexParserDecorator:</strong> The first step is to create a Regex Parser class that will apply a regex pattern to validate a String for us. Creating this as a Decorator gives the added benefit that you can easily wrap any Spring Formatter to apply Regex patterns. The constructor takes a Parser to wrap and a regex to apply; and the parse method first validates against the regex before passing onto the decorated Parser:</p>
<pre><code>
public RegexParserDecorator(Parser parser, String regex) {
	this.parser = parser;
	this.regexPattern = Pattern.compile(regex);
}
public T parse(String text, Locale locale) throws ParseException {
	if (!regexPattern.matcher(text).matches()) {
		throw new IllegalArgumentException("Text does not match regex: " + text);
	}
	return parser.parse(text, locale);
}
</code></pre>
<p><strong>The @StrictDateTimeFormat Annotation: </strong>Next step is to setup the annotation interface class. It is very similar to DateTimeFormat but adds the field to hold a regex. The default regex allows 1 or 2 digit days and months, requires a forward slash as the separator, and enforces a 4 digit year. This can be easily overriden when applying the annotation to a field by supplying your own (regex=&#8221;", pattern=&#8221;") extension. A pattern is still required so make sure your pattern and regex are paired appropriately.</p>
<pre><code>
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface StrictDateTimeFormat {
    public static final String REGEX_DEFAULT = "^(0?[1-9]|1[012])/(0?[1-9]|[12][0-9]|3[01])/\\d\\d\\d\\d$";
    public static final String PATTERN_DEFAULT = "MM/dd/yyyy";
    String regex() default REGEX_DEFAULT;
    String pattern() default PATTERN_DEFAULT;
}
</code></pre>
<p>Spring then requires a StrictDateTimeFormatAnnotationFormatterFactory to wire the annotation with the parser. Nothing fancy here as it borrows heavily upon Spring&#8217;s own JodaDateTimeFormatAnnotationFormatterFactory. The getParser method applies our regex to the DateTimeFormat functionality:</p>
<pre><code>
public class StrictDateTimeFormatAnnotationFormatterFactory implements
		AnnotationFormatterFactory {
...
	public Parser getParser(StrictDateTimeFormat annotation, Class<!--?--> fieldType) {
		DateTimeParser parser = new DateTimeParser(forPattern(annotation.pattern()));
		return new RegexParserDecorator(parser, annotation.regex());
	}
	private DateTimeFormatter forPattern(String pattern) {
		return org.joda.time.format.DateTimeFormat.forPattern(pattern);
	}
...
</code></pre>
<p><strong>Hooking it all together: </strong> Here is the snippet from my applicationConfig.xml showing how the annotation is registered into Spring:</p>
<pre><code>
&lt;mvc:annotation-driven conversion-service="myConversionService" /&gt;
&lt;bean id="myConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"&gt;
	&lt;property name="formatters"&gt;
		&lt;list&gt;
			&lt;bean class="jeffsheets.util.format.StrictDateTimeFormatAnnotationFormatterFactory" /&gt;
		&lt;/list&gt;
	&lt;/property&gt;
&lt;/bean&gt;
</code></pre>
<p>Hopefully this information is helpful in creating a reusable regex validating DateTime formatter for use in your own web application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/19/creating-a-spring-strictdatetimeformat-annotation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Presentation: Grails 2.0 &#8211; what to be excited about</title>
		<link>http://www.objectpartners.com/2012/01/17/presentation-grails-2-0-what-to-be-excited-about/</link>
		<comments>http://www.objectpartners.com/2012/01/17/presentation-grails-2-0-what-to-be-excited-about/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 15:00:11 +0000</pubDate>
		<dc:creator>Ehren Seim</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Podcasts]]></category>
		<category><![CDATA[benefits of grails 2.0]]></category>
		<category><![CDATA[changes in grails 2.0]]></category>
		<category><![CDATA[grails 2.0]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4714</guid>
		<description><![CDATA[Download Full Presentation Grails 2.0 is here and full of a bunch of exciting, fun stuff. Check out Sr. Consultant Zan Thrash talk about what you&#8217;ll see in Grails 2.0. Preview]]></description>
			<content:encoded><![CDATA[<p style="padding-top: 1em;">
<a href="http://www.mediafire.com/file/gdbqo8ae5ut6y3e/Grails2TechTalk.mov">Download Full Presentation</a>
</p>
<p style="padding-top: 1em;">
<div class="description">
Grails 2.0 is here and full of a bunch of exciting, fun stuff. Check out Sr. Consultant Zan Thrash talk about what you&#8217;ll see in Grails 2.0.
</div>
</p>
<p style="padding-top: 1em;">
<b>Preview</b>
</p>
<p style="padding-top: 1em;">
<iframe src="http://player.vimeo.com/video/35162147?portrait=0" width="483" height="362" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/17/presentation-grails-2-0-what-to-be-excited-about/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
<enclosure url="http://www.mediafire.com/file/gdbqo8ae5ut6y3e/Grails2TechTalk.mov" length="0" type="video/quicktime" />
		</item>
		<item>
		<title>Introduction to Servlet 3.0</title>
		<link>http://www.objectpartners.com/2012/01/16/introduction-to-servlet-3-0/</link>
		<comments>http://www.objectpartners.com/2012/01/16/introduction-to-servlet-3-0/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 16:39:44 +0000</pubDate>
		<dc:creator>jwarren</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Annotations]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[Listener]]></category>
		<category><![CDATA[Servlet]]></category>
		<category><![CDATA[Servlet 3.0]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4230</guid>
		<description><![CDATA[Earlier in 2011 the Apache group released Tomcat v7 on the waiting Servlet world. With this came featured support for Servlet 3.0. In some discussions it seems that Servlet 3.0 was supposedly supported by later versions of Tomcat v6, but I can't find anything more than a few scattered mentions; mostly wishful thinking, it seems. With Tomcat v7, we can now get Servlet 3.0 support! It also supports JSP v2.2 and EL v2.2, but for now I just want to poke at a few niceties provided with Servlet 3.0.]]></description>
			<content:encoded><![CDATA[<p>Earlier in 2011 the Apache group released Tomcat v7 on the waiting Servlet world. With this came featured support for Servlet 3.0. In some discussions it seems that Servlet 3.0 was supposedly supported by later versions of Tomcat v6, but I can&#8217;t find anything more than a few scattered mentions; mostly wishful thinking, it seems. With Tomcat v7, we can now get Servlet 3.0 support! It also supports JSP v2.2 and EL v2.2, but for now I just want to poke at a few niceties provided with Servlet 3.0.</p>
<h1>Annotations</h1>
<p>One very nice thing Servlet 3.0 brings us is a set of annotations to declare Filters and Servlets and Listeners. With these annotations, the configuration of applications is removed from the web.xml file and put into the application&#8217;s JARs and WEB-INF/classes.  This is an exciting feature because it also allows you to package your Servlets,  Filters, and Listeners into JAR files and include them in your web application simply by including the JAR file in the WEB-INF/lib folder of the application. Packaging and fragmenting an application is a topic for another day; let&#8217;s just focus on the annotations for the moment.</p>
<p>For those familiar with annotated frameworks such as Spring, it shouldn&#8217;t be too difficult to see the benefit of annotating code instead of adding configuration to the web.xml file. There&#8217;s the easy spot of &#8220;ease,&#8221; as it simply doesn&#8217;t need to be done. There&#8217;s a simple case for &#8220;error-proofing&#8221; as the annotation should be close enough to the code that it alleviates some of those errors.</p>
<h2>Filters</h2>
<p>Typically Filters are declared in the web.xml file in the following fashion:</p>
<pre>&lt;filter&gt;
  &lt;filter-name&gt;site-filter&lt;/filter-name&gt;
  &lt;filter-class&gt;foo.SiteFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
  &lt;filter-name&gt;site-filter&lt;/filter-name&gt;
  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;</pre>
<p>It&#8217;s a bit of XML just to relate a URL pattern (or few) to a class. Of course, additional information can be provided, including initialization parameters for the filter class. The filter class needs to then implement the javax.servlet.Filter interface, and contain a few methods to satisfy the Filter interface. This doesn&#8217;t change much in the Servlet 3.0 annotation scheme.</p>
<p>To use a Servlet 3.0 annotated filter, the class must still implement the Filter interface and contain the methods to satisfy the interface, but rather than all of that XML configuration, the annotation @WebFilter() can be added to the class definition, and its parameters added as attributes to the Filter. Here&#8217;s what it takes to replace that block of XML:</p>
<pre>@WebFilter( "/*" )
public class SiteFilter implements Filter {
  @Override
  public void destroy() {
  }
  @Override
  public void doFilter(final ServletRequest servletRequest,
                       final ServletResponse servletResponse,
                       final FilterChain filterChain)
         throws IOException, ServletException {
    // Whatever you need to do
    filterChain.doFilter(servletRequest, servletResponse);
  }
  @Override
  public void init(final FilterConfig filterConfig)
         throws ServletException {
  }
}</pre>
<p>Of course, as with the XML, additional values can be applied.</p>
<pre>@WebFilter(urlPatterns = { "/specific","/url","/patterns.ext" },
           initParams={@WebInitParam(name="something",value="cool")})</pre>
<p>The sample above allows our Filter only to match three specific URL patterns (since there&#8217;s no wildcard), and adds a cool value to the initialization values.</p>
<h3>Including Other Filters</h3>
<p>This can also be applied to older Filters that are not annotated. For example, I frequently use the Tuckey <a href="http://www.tuckey.org/urlrewrite/" target="_blank">UrlRewriteFilter </a>to ensure my application doesn&#8217;t throw itself for a loop by adding the session ID to the returned URL. It&#8217;s a simple Filter, expressed in some XML included with the application (taken from their examples):</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;!DOCTYPE urlrewrite&gt;
&lt;!-- PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
"http://tuckey.org/res/dtds/urlrewrite3.2.dtd"--&gt;
&lt;urlrewrite&gt;
  &lt;outbound-rule encodefirst="true"&gt;
    &lt;name&gt;Strip URL Session ID's&lt;/name&gt;
    &lt;from&gt;^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$&lt;/from&gt;
    &lt;to&gt;$1$2$3&lt;/to&gt;
  &lt;/outbound-rule&gt;
&lt;/urlrewrite&gt;</pre>
<p>This strips the jsessionid parameter from any outbound data returned to the browser; this stops the URL from changing to /somepath.ext?jsessionid=breakmenow which can cause relative URLs in the application to end up wrong, like /somepath.ext?jsessionid=breakmenow/images/reallywanted.jpg. To implement this the old way, you&#8217;d specify the Filter in the web.xml, as the following (from their documentation) demonstrates:</p>
<pre>&lt;filter&gt;
&lt;filter-name&gt;UrlRewriteFilter&lt;/filter-name&gt;
  &lt;filter-class&gt;org.tuckey.web.filters.urlrewrite.UrlRewriteFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
  &lt;filter-name&gt;UrlRewriteFilter&lt;/filter-name&gt;
  &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
  &lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;
&lt;/filter-mapping&gt;</pre>
<p>To implement this annotation-unaware Filter into your annotated application, though, simply make a Filter that overrides the UrlRewriteFilter, and pass it the URLs to filter:</p>
<pre>@WebFilter(urlPatterns = { "/*" },
           dispatcherTypes = { DispatcherType.REQUEST, DispatcherType.FORWARD })
public class RewriteFilter extends UrlRewriteFilter {
}</pre>
<p>No other content in the class is required, and the now annotated Filter is added without any inclusion in the web.xml file.</p>
<h2>Listener</h2>
<p>Listeners are defined much the same way. As before, the old way of defining a Listener was to declare it in the web.xml file</p>
<pre>&lt;listener&gt;
  &lt;listener-class&gt;foo.SiteListener&lt;/listener-class&gt;
&lt;/listener&gt;</pre>
<p>The listeners define classes that the web app container will find and start. As before, the class must implement an appropriate interface; one of the javax.servlet.Servlet*Listeners. And, of course, it must implement the methods to satisfy the interface.</p>
<p>To use an annotated Listener, implement the desired Listener, satisfy it with the required methods, and annotate it with the @WebListener annotation.</p>
<pre>@WebListener()
public class SiteListener implements ServletRequestListener {
  @Override
  public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
  }
  @Override
  public void requestInitialized(ServletRequestEvent servletRequestEvent) {
  }
}</pre>
<p>The annotation doesn&#8217;t require any parameters. The only parameter it allows is an optional description of the Listener.</p>
<h3>Including Other Listeners</h3>
<p>As with Filters, it&#8217;s easy to include Listeners that aren&#8217;t annotated. For example, to include <a href="http://tiles.apache.org/">Apache Tiles</a> in your web.xml, you can define the Listener using the XML (from their documentation):</p>
<pre>&lt;listener&gt;
  &lt;listener-class&gt;org.apache.tiles.web.startup.simple.SimpleTilesListener&lt;/listener-class&gt;
&lt;/listener&gt;</pre>
<p>Or using annotations, simply extend the Tiles Listener you want to use, and annotate it appropriately.</p>
<pre>@WebListener
public class TilesListener extends SimpleTilesListener {
}</pre>
<p>This way you can contain the configuration entirely in software.</p>
<h3><span style="font-size: 20px;">Servlet</span></h3>
<p>Servlets are mapped much the same way Filters are mapped. Traditionally, the web.xml will define a Servlet and Servlet mappings to tie URLs to the correct Servlet.</p>
<pre>&lt;servlet&gt;
  &lt;servlet-name&gt;SiteServlet&lt;/servlet-name&gt;
  &lt;servlet-class&gt;foo.SiteServlet&lt;/servlet-class&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;SiteServlet&lt;/servlet-name&gt;
  &lt;url-pattern&gt;/mapping&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
<p>The Servlet then needs to extend the class javax.servlet.http.HttpServlet. No methods are required, but generally either or both of the doGet() or doPost() methods are implemented to handle the request action.</p>
<p>To use the Servlet 3.0 annotation for a Servlet, the HttpServlet class must still be implemented, and the annotation @WebServlet needs to be applied. The @WebServlet annotation requires only one attribute as it needs to know at least one URL to which the Servlet will be mapped.</p>
<pre>@WebServlet("/mapping")
public class SiteServlet extends HttpServlet {
  @Override
  protected void doPost(final HttpServletRequest httpServletRequest,
                        final HttpServletResponse httpServletResponse)
             throws ServletException, IOException {
  // Do your stuff
  }
}</pre>
<p>Of course, mutliple URLs can be added, as with the Filter, by specifying the urlPatterns parameter.</p>
<h3>Using Other Servlets</h3>
<p>With many frameworks, like Spring MVC or Apache Struts, there&#8217;s only one Servlet. That Servlet handles all of the processing of requests, routing them to the appropriate Action or Controller as necessary. As with the Filter and Listener annotations, a simple annotation can bring that third-party Servlet into the application with @WebServlet annotations. From the Spring <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-servlet" target="_blank">documentation</a>, here&#8217;s how to set up a basic DispatcherServlet in the web.xml file.</p>
<pre>&lt;servlet&gt;
  &lt;servlet-name&gt;example&lt;/servlet-name&gt;
  &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class&gt;
  &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
  &lt;servlet-name&gt;example&lt;/servlet-name&gt;
  &lt;url-pattern&gt;*.form&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
<p>Here&#8217;s how to do the same using Servlet 3.0 annotations.</p>
<pre>@WebServlet(urlPatterns={"/*.form"}, loadOnStartup=1)
public class SpringDispatcherServlet extends DispatcherServlet {
}</pre>
<p>With this, the Spring DispatcherServlet is mapped to accept all URLs ending in .form, and it will be loaded when the application starts (instead of waiting for the first request). As with @WebFilter annotations, the @WebServlet also accepts init parameters, so those can also be added to help configure the application.</p>
<h3>Some Limitations</h3>
<p>One thing that some of the other frameworks like Spring bring is an ability to map the URL to methods with their annotations. While Servlet 3.0 annotations allow mapping more than one URL to a Servlet class, it is still up to the developer to decipher the URL in the Servlet, as necessary. This is no different than &#8220;usual&#8221; Servlet development where more than one URL is mapped to a Servlet; inside the Servlet the request path or URI or other mechanism can be used to determine by which the visitor arrived to the Servlet.</p>
<p>Additionally, Servlet 3.0 doesn&#8217;t bring any tools to map elements such as GET or POST parameters to method parameters. The same Servlet digestion of parameters occurs, and they&#8217;re all Strings until converted. It&#8217;s up to the developer to handle all of the parameter transformation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/16/introduction-to-servlet-3-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generating Excel from Grails</title>
		<link>http://www.objectpartners.com/2012/01/12/generating-excel-from-grails/</link>
		<comments>http://www.objectpartners.com/2012/01/12/generating-excel-from-grails/#comments</comments>
		<pubDate>Thu, 12 Jan 2012 16:16:26 +0000</pubDate>
		<dc:creator>sjurgemeyer</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Excel]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JXL]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4620</guid>
		<description><![CDATA[Most developers do their best to avoid working in Excel, but it is often necessary to produce reports or other output in Excel format.  Often times we resort to simple CSV files, or raw data put into an Excel format.  While this handles most basic cases, it&#8217;s not always enough.   If you want to [...]]]></description>
			<content:encoded><![CDATA[<p>Most developers do their best to avoid working in Excel, but it is often necessary to produce reports or other output in Excel format.  Often times we resort to simple CSV files, or raw data put into an Excel format.  While this handles most basic cases, it&#8217;s not always enough.   If you want to have formatting, formulas, merging etc, you are going to need to use an Excel specific library.</p>
<p>There are two main libraries for creating Excel documents from Java/Groovy; POI and JXL.  After some research, I came to the conclusion that JXL is more up-to-date and powerful.  It is a Java library though.  As such, it is strongly typed with a lot of extra syntax that those of us developing in Groovy like to avoid.  To get around this, I created the <a href="http://grails.org/plugin/jxl">Grails JXL plugin</a>.</p>
<p>The plugin is a wrapper for the library, but it also adds some nice builder-like syntax to create Excel documents.  For example, to create a workbook with a single worksheet and a few cells you can write:</p>
<pre>workbook('/path/to/test.xls') {
    sheet('SheetName') {
        cell(0,0,'Column 1').bold().center()
        cell(1,0,'Column 2').bold().center()
        cell(0,1,'Value 1').left()
        cell(1,1,'Value 2').left()
    }
}</pre>
<p>Or if you prefer, you can add the data as a map</p>
<pre>workbook('/path/to/test.xls') {
    sheet('SheetName') {
        addData([
            ['Column 1','Column 2'],
            ['Value 1','Value 2']
       ])
    }
    (0..1).each { cell(it,0).bold().center() } 
    (0..1).each { cell(it,1).left() }
}</pre>
<p>To get this builder syntax, you simply have to use the Mixin grails.plugin.jxl.ExcelBuilder.</p>
<pre>    @Mixin(ExcelBuilder)
    class MyBuilder {</pre>
<p>Notice that columns and rows are 0 indexed, and that the <code>cell</code> method can be used to set the cell value when one is provided, or get the current cell when no value is provided.  In either case you can use provided methods to do formatting.</p>
<p>The plugin provides many built in methods for formatting, such as <code>bold(), italic(), thinBorder(), dottedBorder()</code> etc.  It also give access to all of the JXL functionality, by allowing you to set properties of WritableFont and WritableFormat directly on the cell, such as</p>
<pre>    cell(0,0,"foo").pointSize = 16</pre>
<p>The plugin also allows you to create Excel formulas, as in</p>
<pre>    cell(3,6, formula.sum(formula.range(3,0,3,5)))</pre>
<p>which generates a cell with the formula =SUM(A4:F4).  The formula object supplies a range function to create the Excel formatted range.  All other functions dynamically create the Excel function with the same name; in this case sum.</p>
<p>The Grails JXL plugin takes advantage of a great library and Groovy&#8217;s dynamic nature to give a more convenient way to generate formatted Excel documents.  Feedback is very welcome, as this plugin is still in it&#8217;s early stages.  For more detailed information, check out the wiki on <a href="https://github.com/sjurgemeyer/grails-jxl-plugin">github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/12/generating-excel-from-grails/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Filtering Log Messages from Abstract Classes</title>
		<link>http://www.objectpartners.com/2012/01/09/filtering-log-messages-from-abstract-classes/</link>
		<comments>http://www.objectpartners.com/2012/01/09/filtering-log-messages-from-abstract-classes/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 15:36:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[abstract]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[log4j]]></category>
		<category><![CDATA[logback]]></category>
		<category><![CDATA[slf4j]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4464</guid>
		<description><![CDATA[For the past year I&#8217;ve been seeing messages like this in a little project I&#8217;d been working on: [Dec-15 21:26:10.777][DEBUG][http-8080-2] [org.springframework.security.web. authentication.preauth.AbstractPreAuthenticatedProcessingFilter :doAuthenticate] No pre-authenticated principal found in request Pretty innocuous, but it turns out that this particular Spring Security filter spits out a lot of messages at the DEBUG level &#8211; so many, in [...]]]></description>
			<content:encoded><![CDATA[<p>For the past year I&#8217;ve been seeing messages like this in a little project I&#8217;d been working on:</p>
<pre>[Dec-15 21:26:10.777][DEBUG][http-8080-2] [org.springframework.security.web.
authentication.preauth.AbstractPreAuthenticatedProcessingFilter
:doAuthenticate] No pre-authenticated principal found in request</pre>
<p>Pretty innocuous, but it turns out that this particular <a href="http://static.springsource.org/spring-security/site/">Spring Security</a> filter spits out a lot of messages at the <code>DEBUG</code> level &#8211; so many, in fact, that it made it difficult to find debugging messages that I was actually interested in.  I had configured <a href="http://logging.apache.org/log4j/1.2/">Log4J</a> to record <code>org.springframework.security</code> log events at the <code>WARN</code> level or higher, and had spent a couple of hours scratching my head, trying to figure out why these messages were still being logged.</p>
<p>I recently revisited the logging infrastructure in this project, switching out Log4J in favor of <a href="http://slf4j.org/">SLF4J</a> and <a href="http://logback.qos.ch/">Logback</a>.  I eliminated all references to commons-logging using the SLF4J JCL bridge and migrated my log4j.xml config to a logback.xml config, yet the debug messages from Spring Security still continued to be emitted.  After a few hours of debugging my way through the depths of the logging systems and <a href="http://stackoverflow.com/questions/3914124/how-to-initialize-slf4j-using-log4j-logger-properly-in-abstract-classes-for">this stackoverflow.com post</a>, I figured out what the problem was: <strong>the name of the logger used did not match the classname being emitted by the log message.</strong></p>
<p>Consider this code:</p>
<pre>public abstract class A {
    private static final Logger LOG = LoggerFactory.getLogger(getClass());
    public void performAbstractOperation()
        { LOG.debug("Performing abstract operation"); }
}</pre>
<pre>public class B extends A {
    private static final Logger LOG = LoggerFactory.getLogger(B.class);
    public void performConcreteOperation()
        { LOG.debug("Performing concrete operation"); }
}</pre>
<p>If the logging facility is set up to report the class name that issues the logging event and is configured to emit logging events from class A at <code>WARN</code> level or higher and from class B at <code>DEBUG</code> level or higher, the LOG.debug message from class A (&#8220;Performing abstract operation&#8221;) will still show up in the logs when your code runs (and will show up as being emitted by class A!), even though it appears that the logging facility is configured to filter out that logging event.</p>
<p>This happens because of how Log4J and Logback implement their loggers.  Each logger has a name associated with it.  This name is technically any arbitrary string, but is usually a fully-qualified Java package or class &#8211; for example, <code>org.springframework.security</code> or <code>com.mycompany.MyClass</code>.  (Using fully-qualified Java package names or class names allows logging configurations to manage entire hierarchies of classes with a single logger entry.)  These loggers are fetched by name using the <code>LoggerFactory.getLogger()</code> facility (for SLF4J/Logback &#8211; Log4J uses <code>LogFactory.getLog()</code>), passing the object&#8217;s <code>Class</code> object as an argument.  The named logger that gets fetched is named identically to the fully-qualified class name.  In the example above, class B gets the logger named &#8220;B&#8221; &#8211; but class A also gets the logger named &#8220;B&#8221;, by virtue of using <code>getClass</code> in the call to <code>getLogger</code> (because class &#8220;A&#8221; is abstract, any instantiated class would have to be of type &#8220;B&#8221;, which is what <code>getClass()</code> returns).  Because they both get the logger named &#8220;B&#8221; and &#8220;B&#8221; is configured to emit <code>DEBUG</code> messages or higher, the logging events from both &#8220;A&#8221; and &#8220;B&#8221; are recorded.</p>
<p>By default, the logger name is not emitted into the log files, but the class name is, so it appears that unwanted logging messages aren&#8217;t being properly filtered by the logging facility.  However, both Log4J and Logback can use &#8220;%c&#8221; as a pattern in their logging configurations to emit the logger name used by a logging event.  This makes it very easy to track down and eliminate any pesky debugging messages from abstract classes (like in the example above.)</p>
<p>Because both &#8220;A&#8221; and &#8220;B&#8221; use the same name, it is impossible to filter the <code>DEBUG</code> event from &#8220;A&#8221; while still seeing the <code>DEBUG</code> event from &#8220;B&#8221;.  In order to fix this, pass a unique name (as a <code>String</code>) to <code>LoggerFactory.getLogger()</code> in either the abstract class or the derived class.  This name will become the name of the logger for that class, while the other class will retain the fully-qualified name of the derived class for the name of its logger.  The logging facility can then be configured to allow logging events at one level for the logger with the unique name and to allow logging events at a different level for the logger with the name of the derived class.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/09/filtering-log-messages-from-abstract-classes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSTL Core Set Tag Gotcha</title>
		<link>http://www.objectpartners.com/2012/01/03/jstl-core-set-tag-gotcha/</link>
		<comments>http://www.objectpartners.com/2012/01/03/jstl-core-set-tag-gotcha/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 14:36:11 +0000</pubDate>
		<dc:creator>jwarren</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[JSP]]></category>
		<category><![CDATA[JSTL]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4419</guid>
		<description><![CDATA[JSTL 1.2 Core Set tag removes attributes from other scopes when the value is null and the names overlap!]]></description>
			<content:encoded><![CDATA[<p>Migrating a JSP-heavy project from JSTL 1.0 to 1.2, some odd behavior broke at least one bit of JSP logic. After much debugging, it was determined that the problem lie with the JSTL Core taglib, specifically in the Set tag.</p>
<p>In our case, the tag was being used to set an attribute to the value of another attribute&#8217;s inner property, as the following shows:</p>
<pre style="padding-left: 30px;">&lt;c:set var="something"
    value="${somethingElse.property}"/&gt;</pre>
<p>Even more, the same attribute ame was being used in different JSPs, connected by including one in another, although storing the attribute in different scopes, as the following shows:</p>
<pre style="padding-left: 30px;">&lt;c:set var="something"
    value="${somethingElse.property}" scope="request" /&gt;
&lt;c:set var="something"
    value="${anotherElse.property}" /&gt;</pre>
<p>In this case, the <em>including</em> page contained the first line, the request-scope set value. The <em>included</em> file contained the second, implicit scope value. The page was included with the request-time &lt;c:import url=&#8221;included.jsp&#8221;/&gt;, which &#8220;calls&#8221; the included page. The included page gets its own page context, but shares the request and session. When things worked well, the request value was unmodified, and &#8220;returning&#8221; from the included page left the page attribute behind. The discovered problem occurred when the value of the property resolved to NULL. In this case, not only was the page attribute &#8220;unset,&#8221; but it happened that the request attribute was also lost.</p>
<p>It was unsettling to find that what seemed to be a default page context action would affect the other scopes, but it turns out to be the case!</p>
<p>The following JSP shows this with a simple example. A few values are set, just to show what&#8217;s happening, and then the attributes are modified to show the results.</p>
<pre style="padding-left: 30px;">&lt;%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%&gt;
&lt;c:set var="something"
    value="Saved in Session" scope="session" /&gt;
&lt;c:set var="something"
     value="Saved in Request" scope="request" /&gt;
&lt;c:set var="something"
     value="Saved in Page" scope="page" /&gt;
&lt;html&gt;
&lt;head&gt;
&lt;style type="text/css"&gt;
.value {
color: green;
}
&lt;/style&gt;
&lt;title&gt;Test&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;
Session:
&lt;span class="value"&gt;&lt;%=session.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;Request:
&lt;span class="value"&gt;&lt;%=request.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;Page:
&lt;span class="value"&gt;&lt;%=pageContext.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;EL: &lt;span class="value"&gt;${something}&lt;/span&gt;
&lt;/p&gt;
&lt;c:set var="something" value="${nothing}" scope="page" /&gt;
&lt;p&gt;
Session:
&lt;span class="value"&gt;&lt;%=session.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;Request:
&lt;span class="value"&gt;&lt;%=request.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;Page:
&lt;span class="value"&gt;&lt;%=pageContext.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;EL: &lt;span class="value"&gt;${something}&lt;/span&gt;
&lt;/p&gt;
&lt;c:set var="something" value="${nothing}" /&gt;
&lt;p&gt;
Session:
&lt;span class="value"&gt;&lt;%=session.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;Request:
&lt;span class="value"&gt;&lt;%=request.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;Page:
&lt;span class="value"&gt;&lt;%=pageContext.getAttribute("something")%&gt;&lt;/span&gt;
&lt;br /&gt;EL: &lt;span class="value"&gt;${something}&lt;/span&gt;
&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>The actions are pretty simple.</p>
<ul>
<li>The first block shows all of the values as initially set. Since the page attribute is set, the EL resolves to the page-scoped value.</li>
<li>The page-scope value is set to something that resolves to NULL (note this doesn&#8217;t set the value to NULL, but removes the value from the attributes Map, which will resolve to NULL in future uses) with an explicit scope definition. This correctly clears the page attribute, but leaves the other alone, as is demonstrated by the EL evaluating to the request-scoped value.</li>
<li>The final block sets the attribute with an implicit scope definition; the documentation says this will default to the page scope (which it does), but what the documentation fails to note is that <strong>the other scopes are also removed</strong>! This is demonstrated by all of the &#8220;null&#8221; entries, and the empty EL (EL doesn&#8217;t show NULL values).</li>
</ul>
<p>Here&#8217;s what the output looks like:</p>
<pre style="padding-left: 30px;">Session: <span style="color: green;">Saved in Session</span>
Request: <span style="color: green;">Saved in Request</span>
Page: <span style="color: green;">Saved in Page</span>
EL: <span style="color: green;">Saved in Page</span>

Session: <span style="color: green;">Saved in Session</span>
Request: <span style="color: green;">Saved in Request</span>
Page: <span style="color: green;">null</span>
EL: <span style="color: green;">Saved in Request</span>

Session: <span style="color: green;">null</span>
Request: <span style="color: green;">null</span>
Page: <span style="color: green;">null</span>
EL:</pre>
<p>This &#8220;undocumented feature&#8221; is found in the implementation of the org.apache.taglibs.standard.tag.common.core.SetSupport.doEndTag() which has the following bit of close in it:</p>
<pre style="padding-left: 30px;">if (scopeSpecified)
    pageContext.removeAttribute(var, scope);
else
    pageContext.removeAttribute(var);</pre>
<p>It would seem that it should be the case that if the scope isn&#8217;t specified that the page scope would be used, as that is the default according to the documentation. It isn&#8217;t the case, though, so when not specified the attribute looks to be entirely removed. Checking deeper, at least in the Tomcat source, the pageContext.removeAttribute(var) ends up in the JSTL org.apache.jasper.runtime.PageContextImpl which finally results in executing the following:</p>
<pre style="padding-left: 30px;">private void doRemoveAttribute(String name) {
    removeAttribute(name, PAGE_SCOPE);
    removeAttribute(name, REQUEST_SCOPE);
    if( session != null ) {
        try {
            removeAttribute(name, SESSION_SCOPE);
        } catch(IllegalStateException ise) {
            // Session has been invalidated.
            // Ignore and fall throw to application scope.
        }
    }
    removeAttribute(name, APPLICATION_SCOPE);
}</pre>
<p>As we can see, it removes the attributes from all of the scopes, even the application (the Servlet&#8217;s Context) scope, which we didn&#8217;t test! As disconcerting as this is, the solution is trivial to implement: explicitly name the page scope where the attribute may collide and where the value may evaluate to NULL. As long as both of those don&#8217;t happen, the problem doesn&#8217;t occur. If they do both happen, though, no matter where the &lt;c:set&gt; is encountered, the request and session attributes are lost.</p>
<p>This has been tested on Tomcat v6, v7, and Weblogic v11.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2012/01/03/jstl-core-set-tag-gotcha/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On The Trail of a JVM Bug</title>
		<link>http://www.objectpartners.com/2011/12/29/on-the-trail-of-a-jvm-bug/</link>
		<comments>http://www.objectpartners.com/2011/12/29/on-the-trail-of-a-jvm-bug/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 15:19:17 +0000</pubDate>
		<dc:creator>jmcclure</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[jvm]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4162</guid>
		<description><![CDATA[I recently had the opportunity to track a bug past my application code into the JVM and beyond. I learned a few things along the way. I found a bug in an application I was working on that I narrowed down to a concurrency issue. Threads were deadlocked somewhere. I couldn&#8217;t figure it out in [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had the opportunity to track a bug past my application code into the JVM and beyond. I learned a few things along the way.</p>
<p>I found a bug in an application I was working on that I narrowed down to a concurrency issue. Threads were deadlocked somewhere. I couldn&#8217;t figure it out in the application so I wrote the most minimal app I could that reproduced the problem. Here&#8217;s that code (I removed various System.out&#8230; calls for brevity):</p>
<pre>
public class Foo {

	private int counter;

	public static void main(String[] args) throws Exception {
		 new Foo().run();
	}

	public void run() throws Exception {

		Thread[] threads = new Thread[2];

		for (int i = 0; i < threads.length; i++) {
			threads[i] = new Thread() {
				public void run() {
					for (int i = 0; i < 1000000000; i++) {
						increment();
					}
				}
			};
		}

		for (Thread t : threads) {
			t.start();
		}

		for (Thread t : threads) {
			t.join();
		}
	}

	private synchronized void increment() {
		counter++;
	}
}
</pre>
<p>The code above deadlocks both created threads in the counting loop; zero CPU usage. I didn't see any reason that should happen so I sent the code sample to some coworkers. They didn't see a problem either. At this point I started trying to isolate environmental issues. I was running this hardware, OS, and JVM:</p>
<pre>
        MacBook Pro
        2.3GHz Intel Core i7
        8GB 1333MHz DDR3

        OS X 10.6.8 with 64 bit enabled

        Java version 1.6.0_29
        Java(TM) SE Runtime Environment (build 1.6.0_29-b11-402-10M3527)
        Java HotSpot(TM) 64-Bit Server VM (build 20.4-b02-402, mixed mode)
</pre>
<p>The deadlock didn't happen if I used a Lock instead of a synchronized method. It also didn't happen if I ran the JVM in 32 bit mode, only in 64 bit mode.</p>
<p>I started considering the possibility of a JVM issue. That's not a conclusion to jump to lightly so I sent the problem to a prominent Java expert who in turn involved two others. I haven't their permission to give their names. One of them was able to reproduce the issue running similar hardware.</p>
<p>Next we tried running on 2 other JVMs: openjdk version 1.7.0-ea and soylatte java version 1.6.0_03-p3. There was no deadlock on either of these JVMs. It was starting to look a lot like a JVM problem.</p>
<p>Once we determined it wasn't a problem with the application code we ran the app until it deadlocked then forced a core dump. To force a core dump from the command line:</p>
<ol>
<li>ulimit -c unlimited - set this to allow core dumps</li>
<li>kill -SIGSEGV pid - send a segmentation fault signal to force the app to crash</li>
</ol>
<p>The core file is saved in /cores/core.pid. There is also a *.crash file saved in [user home]/Library/Logs/DiagnosticReports.</p>
<p>The crash file analysis showed this info for the 2 threads:</p>
<pre>
Thread 24:  Java: Thread-1
0   libSystem.B.dylib             0x00007fff89f88d7a mach_msg_trap + 10
1   libSystem.B.dylib             0x00007fff89f893ed mach_msg + 59
2   libclient64.dylib             0x000000010100d903 jio_snprintf + 37641
...

Thread 25:  Java: Thread-2
0   libSystem.B.dylib             0x00007fff89f88d7a mach_msg_trap + 10
1   libSystem.B.dylib             0x00007fff89f893ed mach_msg + 59
2   libclient64.dylib             0x000000010100db03 jio_snprintf + 38153
...
</pre>
<p>They are both waiting on a message from the kernel. It appears to be an issue with the kernel not delivering the message instead of a JVM problem but we aren't ready to declare any definite answer yet. The next step is the core dump analysis. Wherever this leads or whether we definitively identify the problem, its been an interesting experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2011/12/29/on-the-trail-of-a-jvm-bug/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>SplitView for JQuery Mobile</title>
		<link>http://www.objectpartners.com/2011/12/22/splitview-for-jquery-mobile/</link>
		<comments>http://www.objectpartners.com/2011/12/22/splitview-for-jquery-mobile/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 16:15:07 +0000</pubDate>
		<dc:creator>zlendon</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Jquery]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[SplitView]]></category>

		<guid isPermaLink="false">http://www.objectpartners.com/?p=4240</guid>
		<description><![CDATA[If you’ve worked with an iPad for any significant period of time, odds are you’ve run across one of its main user interfaces, ‘Split View’, which is a type of master-detail interface. An example version of this interface on an iPad is shown below: In a master-detail interface, the left side of the screen displays [...]]]></description>
			<content:encoded><![CDATA[<p>If you’ve worked with an iPad for any significant period of time, odds are you’ve run across one of its main user interfaces, ‘Split View’, which is a type of master-detail interface.  An example version of this interface on an iPad is shown below:</p>
<p><img src="http://i40.tinypic.com/wiljr6.jpg" alt="Split View IPad"/></p>
<p>In a master-detail interface, the left side of the screen displays a list of selectable items while the right side displays the details of the item selected.  In actuality, implementations of this type of interface are commonplace in both web and native applications.  That being said, in this post, I want to talk a bit about the core building blocks used in the building of this type of interface for a less common use case, mobile web applications, specifically by leveraging <a href="http://jquerymobile.com/">JQuery Mobile</a>.</p>
<p>Developers who have worked with web applications for any significant period of time have likely used or dabbled with JQuery and will thus find many familiarities in <a href="http://jquerymobile.com/">JQuery Mobile</a>, JQuery’s mobile offering, which just this past month released version 1.0 of its mobile framework.  Just like with the JQuery infrastructure, <a href="http://jquerymobile.com/">JQuery Mobile</a> has a plugin ecosystem, and one of the more promising plugins is the <a href="http://asyraf9.github.com/jquery-mobile/#context">‘SplitView’</a> plugin, providing an HTML5 version of the <a href="http://asyraf9.github.com/jquery-mobile/#context">‘Split View’</a> interface.  The code for this plugin is contained within the ‘experiments/splitview’ fork of <a href="http://jquerymobile.com/">JQuery Mobile</a> found <a href="https://github.com/asyraf9/jquery-mobile/">here</a>.  When looking for split view support within <a href="http://jquerymobile.com/">JQuery Mobile</a>, and specifically looking for the best replication of a UI similar to the one used on the <a href="http://jquerymobile.com/">JQuery Mobile</a> documentation site, the ‘SplitView’ plugin seems to be the best current option.  As is noted in the plugin’s documentation, the core <a href="http://jquerymobile.com/">JQuery Mobile</a> team assisted in the development of the splitview plugin, helping lend credence to its value.  Studying the structure of the plugin’s demo and the structure of the <a href="http://jquerymobile.com/">JQuery Mobile</a> <a href="http://jquerymobile.com/demos/1.0/">demos</a> site, one can see that both <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> implementations share much in common.</p>
<p>As the plugin’s documentation notes, it works with any device’s browser – desktop, tables, and mobile phones.   Some of the nice features which I think help give it a leg-up on other solutions include support for landscape and portrait orientations, and use of <a href="http://jquerymobile.com/">JQuery Mobile</a> experimental ‘momentum’ scrolling (contained separately in the same ‘experiments’ folder of the <a href="http://jquerymobile.com/">JQuery Mobile</a> fork referenced below).  </p>
<p>In my opinion, the best way to get going with the code is to work with it locally, so I recommend cloning the forked <a href="http://jquerymobile.com/">JQuery Mobile</a> repository.  Simply ensure that you have git installed locally (good, simple instructions for installing git for various OS’s can be found <a href="http://book.git-scm.com/2_installing_git.html">here</a>) and clone the fork repository, via:</p>
<p>git clone https://github.com/asyraf9/jquery-mobile.git</p>
<p>The index.html page under the aforementioned experiments/splitview fork is unfortunately not quite up to par. Not only does it not use the latest JQuery libraries (mobile and core), it’s layout does not match the expected split-view look found on <a href="http://asyraf9.github.com/jquery-mobile/#context">the splitview plugin site</a>.  To fix this, the simplest approach I found was to copy the ‘body’ section of the html source from the plugin&#8217;s site into your local version and additionally referencing locally the same versions of <a href="http://jquerymobile.com/">JQuery Mobile</a> CSS and JS files that that site references (by pulling down said files).   I personally had limited success with the absolute latest CSS and JS <a href="http://jquerymobile.com/">JQuery Mobile</a> files, so unless you need those features, for testing at least it might be simplest to use the same version as those that are proven to work best.</p>
<p>After making these local changes to ensure a working local copy, one is encouraged to look a bit deeper at many of the key components and concepts used in building the pages that make up a <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a>-based interface.   Here’s a roadmap for you:</p>
<p><b>The Left Panel:</b><br />
A snapshot of the html for a slimmed down left panel of a master-detail interface, taken from the <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> plugin site, is shown below (*if you do not see a code snippet here please reload the page, as the Gist script does not always immediately load unfortunately):</p>
<p><script src="https://gist.github.com/1441450.js?file=gistfile1.txt"></script></p>
<p>which visually looks like:</p>
<p><img src="http://i44.tinypic.com/119yp8n.png" alt="left panel ipad"/></p>
<p>You’ll notice that the top-level div:</p>
<p><script src="https://gist.github.com/1441445.js?file=gistfile1.txt"></script></p>
<p>has the inline css style:</p>
<p>Width: 25%; min-width: 250px</p>
<p>This does exactly what you might imagine – it confines the panel to 25% of the screen, with a min-width of 250px.  But how does the ‘left’ panel stay on the left of the page?  Of course, it’s the ui-panel-left –changing it to right indeed moves the panel to the right of the page.  And the ui-border-right creates the bold line that acts to ‘split’ the left panel from the rest of the page.</p>
<p>Nested under the top level div can be any set of elements, but with a <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> one would expect some combination of lists and headers, and our expectations are met here with a header div and a content div, which contains the separate list elements.  As will be discussed in a moment, these sections contain data-roles that we would expect as well – “header”, “content”, and “listview”.  On that note…</p>
<p>One of the more powerful concepts in HTML5 is the use of custom data attributes, and <a href="http://jquerymobile.com/">JQuery Mobile</a> – and as an extension, <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a>, makes strong use of them.  With custom data attributes, elements contain attribute names with a prefix of ‘data-‘, which themselves contain values that get leveraged by application code – namely javascript, for creating a richer UX experience.</p>
<p>Below is a breakdown of some of the custom data attributes used in the sample left-panel:</p>
<p><b>Data-hash</b> -> Possible values: true, false, crumbs.   Defines whether a panel’s page transition should be tracked in history or not.  The ‘crumbs’ setting changes the panel’s back button into a button that points to the previous page and disable <a href="http://jquerymobile.com/">JQuery Mobile</a> from tracking the panel’s history</p>
<p><b>Data-id</b> -> Used by <a href="http://jquerymobile.com/">JQuery Mobile</a> framework to ensure global navigation elements stay in the sample place between transitions.  <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> uses ‘main’ as the ‘id’ of the right-hand panel and ‘menu’ as the ‘id’ of the left-hand panel. </p>
<p><b>Data-url</b> -> Used to identify a page – intended to be linked to by other components of other “pages”, which may or may not require a page load, depending on whether pages are pre-fetched, to reduce additional server calls (typically for static content)</p>
<p><b>Data-role</b> -> Arguably the most important part of a <a href="http://jquerymobile.com/">JQuery Mobile</a> application, it tells <a href="http://jquerymobile.com/">JQuery Mobile</a> how to render a particular piece of HTML content.  Example values include header, footer, page, and listview.   When set to ‘page’, everything with the ‘div’ with the page data-role will be treated as a separate page or screen.</p>
<p><b>Data-backbtn</b> -> Possible values: true, false:  When true generates the back button on every ‘page’ to let you get back to where you navigated from.</p>
<p><b>Data-icon</b> -> Adds an image to a button.  Example button code: <script src="https://gist.github.com/1441622.js?file=gistfile1.html"></script> and more are defined <a href="http://jquerymobile.com/test/docs/buttons/buttons-icons.html">here</a>. </p>
<p>Another significant item of note is that several elements from the example split-view components leverage the <a href="http://jquerymobile.com/test/docs/content/content-themes.html">data-theme</a> element.   Themes a-e are provided in <a href="http://jquerymobile.com/">JQuery Mobile</a>&#8216;s default styling, thus making f-z available to plugins and other developers.  It is standard practice to add ‘-x’ where x is the theme letter for classes that are themed implementations of JQuery stylings (i.e., ui-btn-up-b, ui-btn-up-c, etc).   .   The <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> demo site uses the ‘g’ theme.   One could take the example code snippets or the html from the entire split-view and change classes that end in –g and change it to a, b, c, etc. to see how other out-of-the-box themes impact the UI.  That being said, the ui-* classes you see in the <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> sample are from <a href="http://jqueryui.com/">JQuery UI</a>, which has custom styles defined for these elements in the various <a href="http://jquerymobile.com/">JQuery Mobile</a> css files linked to from the source code. </p>
<p><b>Right Panel:</b><br />
The right panels are really quite simple in their basic form – let’s take a look at an example page:</p>
<p><script src="https://gist.github.com/1441447.js?file=gistfile1.txt"></script></p>
<p>That’s it!  Note some of the corollary to components discussed from the left-panel.  The ‘bar’ div id for one &#8211; this gets linked to by one of our ‘list’ elements that make up the ‘listview’ from the left-panel.   The data-backbtn value of false will ensure that in the ‘header’ section of this page that a navigation element will not show to take the user back to the previous page they were viewing when they clicked a ‘bar’ listview link.  Finally, note the data-panel is defined as ‘main’, which defines where this new page should load (remember, ‘main’ was right hand panel, ‘menu’, left). </p>
<p><b>Transitions</b><br />
One other item to note is that several elements on the split view, including each list item on the left panel, and the ‘Main’ and ‘Demos’ buttons, leverage <a href="http://jquerymobile.com/">JQuery Mobile</a> data-transitions for object and page-change events.   A succinct discussion of how to define these transitions for <a href="http://jquerymobile.com/">JQuery Mobile</a> pages can be found <a href="http://jquerymobile.com/demos/1.0a4.1/docs/pages/docs-transitions.html">here</a>.  In short, adding a ‘data-transition’ element with 1 of the 6 currently supported transition names gives that element said transition.  So note that not only can one set what page they want to load in the ‘main’ panel, but they could (and often should) define how the transition to show that view would/should occur.</p>
<p><b>In Closing</b><br />
With more focus being given by organizations to “Mobile First” strategies, to “Responsive Design”, and HTML5 mobile web applications that work across devices, <a href="http://jquerymobile.com/">JQuery Mobile</a> <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> is a good tool to have in your arsenal to build what of late has been one of the main native tablet interfaces into your mobile web application.   I believe leveraging components from <a href="http://asyraf9.github.com/jquery-mobile/#context">SplitView</a> in JQuery Mobile’s own documentation site acts as a demonstration that the interface has value in mobile web applications, and can be performant and powerful.  Give it a try, and let me know what you think or what issues/questions you have in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.objectpartners.com/2011/12/22/splitview-for-jquery-mobile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

