<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Musings about technology, computers, and software. tek271.com</description><title>Abdul Habra's Blog</title><generator>Tumblr (3.0; @ahabra)</generator><link>http://ahabra.tumblr.com/</link><item><title>Arabic Text Editor</title><description>&lt;p&gt;I just moved &amp;#8220;Arabic Text Editor&amp;#8221; to&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/software/other/arabic-text-editor"&gt;http://www.tek271.com/software/other/arabic-text-editor&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4195309003</link><guid>http://ahabra.tumblr.com/post/4195309003</guid><pubDate>Tue, 29 Mar 2011 19:38:00 -0400</pubDate></item><item><title>Spam Revenge</title><description>&lt;p&gt;I just moved Spam Revenge to&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/software/other/spam-revenge"&gt;http://www.tek271.com/software/other/spam-revenge&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4195241971</link><guid>http://ahabra.tumblr.com/post/4195241971</guid><pubDate>Tue, 29 Mar 2011 19:35:00 -0400</pubDate></item><item><title>NuExpert</title><description>&lt;p&gt;I just moved NuExpert to&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/software/other/nuexpert"&gt;http://www.tek271.com/software/other/nuexpert&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4195184999</link><guid>http://ahabra.tumblr.com/post/4195184999</guid><pubDate>Tue, 29 Mar 2011 19:33:00 -0400</pubDate></item><item><title>Tek271 Servlet Utilities</title><description>&lt;p&gt;I just moved Tek271 Servlet Utilities to&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/software/java/servlet-utilities"&gt;http://www.tek271.com/software/java/servlet-utilities&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4195113146</link><guid>http://ahabra.tumblr.com/post/4195113146</guid><pubDate>Tue, 29 Mar 2011 19:31:00 -0400</pubDate></item><item><title>Tek271 Template</title><description>&lt;p&gt;I just moved Tek271 Template to&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/software/java/text-template"&gt;http://www.tek271.com/software/java/text-template&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4195051076</link><guid>http://ahabra.tumblr.com/post/4195051076</guid><pubDate>Tue, 29 Mar 2011 19:28:00 -0400</pubDate></item><item><title>Tek271 GzipServletFilter</title><description>&lt;p&gt;I just moved Tek271 GzipServletFilter to&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/software/java/gzipservletfilter"&gt;http://www.tek271.com/software/java/gzipservletfilter&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4194978041</link><guid>http://ahabra.tumblr.com/post/4194978041</guid><pubDate>Tue, 29 Mar 2011 19:25:00 -0400</pubDate></item><item><title>Tek271 Memoizer</title><description>&lt;p&gt;&lt;a href="http://www.tek271.com/software/java/memoizer"&gt;http://www.tek271.com/software/java/memoizer&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4194762653</link><guid>http://ahabra.tumblr.com/post/4194762653</guid><pubDate>Tue, 29 Mar 2011 19:17:00 -0400</pubDate></item><item><title>TECUJ</title><description>&lt;p&gt;Moved TECUJ library to&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/software/java/tecuj-library"&gt;http://www.tek271.com/software/java/tecuj-library&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4194674131</link><guid>http://ahabra.tumblr.com/post/4194674131</guid><pubDate>Tue, 29 Mar 2011 19:14:00 -0400</pubDate></item><item><title>Neural Networks - An Introduction</title><description>&lt;p&gt;Moved this paper to the new Google Apps site on 2011.03.29&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.tek271.com/documents/others/into-to-neural-networks"&gt;http://www.tek271.com/documents/others/into-to-neural-networks&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4193174811</link><guid>http://ahabra.tumblr.com/post/4193174811</guid><pubDate>Tue, 29 Mar 2011 18:15:00 -0400</pubDate></item><item><title>Reverse Proxy Server</title><description>&lt;p&gt;Information moved to &lt;a href="http://www.tek271.com/software/java/reverse-proxy-server"&gt;http://www.tek271.com/software/java/reverse-proxy-server&lt;/a&gt;&lt;/p&gt;</description><link>http://ahabra.tumblr.com/post/4101769268</link><guid>http://ahabra.tumblr.com/post/4101769268</guid><pubDate>Sat, 26 Mar 2011 01:34:00 -0400</pubDate><category>Reverse Proxy</category><category>Server</category><category>Java</category><category>Open Source</category></item><item><title>Guava At Cinjug</title><description>&lt;p&gt;I presented &lt;a title="Google Guava" href="http://code.google.com/p/guava-libraries/"&gt;Google Guava&lt;/a&gt; at Cincinnati Java User Group (&lt;a title="Cincinnati Java User Group" href="http://www.cinjug.org/"&gt;CinJug&lt;/a&gt;) on 2011.01.27.&lt;/p&gt;
&lt;p&gt;Here are links to the material presented:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;&lt;a title="Guava Presentation" href="http://uploadrobots.com/pyKBAm"&gt;Presentation&lt;/a&gt; as PDF&lt;/li&gt;
&lt;li&gt;&lt;a title="Guava Code" href="http://uploadrobots.com/K5H5Pj"&gt;Sample Java code&lt;/a&gt; as an Eclipse project (zipped)&lt;/li&gt;
&lt;/ol&gt;&lt;ol&gt;&lt;/ol&gt;</description><link>http://ahabra.tumblr.com/post/3013817171</link><guid>http://ahabra.tumblr.com/post/3013817171</guid><pubDate>Sun, 30 Jan 2011 11:52:00 -0500</pubDate><category>google guava</category><category>cinjug</category><category>java</category></item><item><title>Build CRUD Apps With Play Framework</title><description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Play (&lt;a title="Play Home Page" href="http://www.playframework.org/"&gt;playframework.org&lt;/a&gt;) is a Java framework that makes it very easy to build web applications. Here I show how to build a CRUD web app in a way that reminds me of &lt;a title="Ruby on Rails" href="http://www.rubyonrails.org/"&gt;RoR &lt;/a&gt;or &lt;a title="Grails" href="http://www.grails.org/"&gt;Grails&lt;/a&gt;. You only need to know Java to follow this example. Play&amp;#8217;s website contains excellent &lt;a title="Play Documentation" href="http://www.playframework.org/documentation/1.0.2.1/home"&gt;documentation&lt;/a&gt; and I will not repeat them here.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Some of the material here was presented at &lt;a title="CoJug" href="http://cojug.org/"&gt;CoJug&lt;/a&gt; on 2010.06.08. The CoJug presentation contained more than what is provided here, and was presented by &lt;em&gt;Nilanjan Raychaudhuri&lt;/em&gt; and myself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Java 1.5 or higher installed.&lt;/li&gt;
&lt;li&gt;Play installed, remember to add Play&amp;#8217;s location to the path.&lt;/li&gt;
&lt;li&gt;Eclipse 3.5 installed. (This is a personal choice, you may use any IDE or text editor).&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;This will be a simple CRUD application which manages the following entities:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;A group of companies.&lt;/li&gt;
&lt;li&gt;Each Company can have 0 or more Department.&lt;/li&gt;
&lt;li&gt;Each Department can have 0 or more Employee.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Create App&amp;#8217;s Skeleton&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;From the command line, navigate to the directory which will contain the new application.&lt;/li&gt;
&lt;li&gt;Run this command: &lt;code&gt;play new corporations&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;You will be prompted to enter the application&amp;#8217;s name, enter &lt;code&gt;Corporations&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The above will create an empty Play application in the &lt;code&gt;corporations&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;To try what you created, run this command:&lt;br/&gt;&lt;br/&gt;  &lt;code&gt;cd corporations&lt;br/&gt; &lt;/code&gt;&lt;code&gt;play run&lt;br/&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;In your web browser, go to &lt;a target="_blank" href="http://localhost:9000/"&gt;http://localhost:9000/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;You should get a page titled &amp;#8220;Your application is ready&amp;#160;!&amp;#8221;&lt;/li&gt;
&lt;li&gt;This proves that Play is running and that you application has started.&lt;/li&gt;
&lt;/ol&gt;&lt;!-- more --&gt;&lt;p&gt;&lt;strong&gt;Configure The App&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Terminate the Play running app at the command line: Ctrl-C&lt;/li&gt;
&lt;li&gt;We are going to use Eclipse for developing this app, so from the command line, enter: &lt;code&gt;play eclipsify&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The eclipsify command creates Eclipse artifacts like .settings and .project&lt;/li&gt;
&lt;li&gt;Run Eclipse &lt;/li&gt;
&lt;li&gt;Import this project: File/Import/General/Existing projects into Workspace&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;code&gt;corporations&lt;/code&gt; directory which you created earlier.&lt;/li&gt;
&lt;li&gt;Finish importing the project.&lt;/li&gt;
&lt;li&gt;In my Eclipse&amp;#8217;s instance, I got several errors after the import, the errors where complaining about different version of Java being used. I changed the project&amp;#8217;s properties/Java compiler to JDK 1.5, and that resolved the problem.&lt;/li&gt;
&lt;li&gt;Open the file conf/application.conf and enable the line&lt;br/&gt;&lt;br/&gt;&lt;code&gt;db=mem&lt;/code&gt; &lt;br/&gt;&lt;br/&gt;which will run HSQL in memory (&lt;em&gt;this is only a demo, but if you look in the file you could see how to connect to a real database&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Still in conf/application.conf, find the section titled &amp;#8220;Additional modules&amp;#8221; and either enable or add the following line:&lt;br/&gt;&lt;br/&gt;&lt;code&gt;module.crud=${play.path}/modules/crud&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;Which will tell Play to include default CRUD scaffolding.&lt;/li&gt;
&lt;li&gt;Open the file conf/routes and add this line&lt;br/&gt;&lt;br/&gt;&lt;code&gt;*      /admin              module:crud&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;which will route all CRUD operations to /admin&lt;/li&gt;
&lt;li&gt;Go to the command line (in the corporations directory) and run &amp;#8220;&lt;code&gt;play eclipsify&lt;/code&gt;&amp;#8221; again.&lt;/li&gt;
&lt;li&gt;Refresh the eclipse project (F5), (&lt;em&gt;you may have to reset the Java Compiler to 1.5 again&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;From the command line, do &amp;#8220;&lt;code&gt;play run&lt;/code&gt;&amp;#8221; again, then check in the browser. The app should run as we had it before, no changes yet.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Create Employee Model and Controller&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Keep Play running at the command line.&lt;/p&gt;
&lt;p&gt;In Eclipse, navigate to app/models the create a new class Employee:&lt;/p&gt;
&lt;pre&gt;package models;&lt;br/&gt;import java.util.Date;&lt;br/&gt;import javax.persistence.*;&lt;br/&gt;import play.db.jpa.Model;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;@Entity&lt;/strong&gt;&lt;br/&gt;public class Employee extends &lt;strong&gt;Model&lt;/strong&gt; {&lt;br/&gt;  public String fullName;&lt;br/&gt;  public Integer salary;&lt;br/&gt;  public Date dateOfHire;&lt;br/&gt;}&lt;/pre&gt;
&lt;p&gt;Navigate to app/controllers and create a new class Employees:&lt;/p&gt;
&lt;pre&gt;package controllers;&lt;br/&gt;public class Employees extends CRUD { // an empty class&lt;br/&gt;}&lt;/pre&gt;
&lt;p&gt;Make sure to save the files, and that Play is still running at the command line. In your web browser, go to &lt;a target="_blank" href="http://localhost:9000/admin"&gt;http://localhost:9000/&lt;strong&gt;admin&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You should see this page:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l3oo72vB4c1qbj7ns.png"/&gt;&lt;/p&gt;
&lt;p&gt;Try To Add an employee and see what happens.&lt;/p&gt;
&lt;p&gt;Notice how Play&amp;#8217;s convention for the controller&amp;#8217;s name is just to add &amp;#8220;s&amp;#8221; at the end of the model class name. (model=Employee, controller=Employees). This is the default convention which can be changed as will be shown when we do the Company controller.&lt;/p&gt;
&lt;p&gt;Notice also that our choice for the Employee class to be in the models package directly is only for simplicity. It can be in any sub-package under models. The same is true for the Employees class and controllers package.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create Department Model and Controller&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In Eclipse, navigate to app/models the create a new class Department:&lt;/p&gt;
&lt;pre&gt;package models;&lt;br/&gt;import javax.persistence.*;&lt;br/&gt;import play.db.jpa.Model;&lt;br/&gt;&lt;br/&gt;@Entity&lt;br/&gt;public class Department extends Model {&lt;br/&gt;  public String name;&lt;br/&gt;  public String description; &lt;br/&gt;}&lt;/pre&gt;
&lt;p&gt;Navigate to app/controllers and create a new class Departments:&lt;/p&gt;
&lt;pre&gt;package controllers;&lt;br/&gt;&lt;br/&gt;public class Departments extends CRUD {}&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;Make sure to save the files, and that Play is still running at the command line. In your web browser, go to http://localhost:9000/admin&lt;/p&gt;
&lt;p&gt;You should see the same &lt;em&gt;Administration&lt;/em&gt; page as above but now it contains both &lt;em&gt;Departments&lt;/em&gt; and &lt;em&gt;Employees&lt;/em&gt; object types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Relationship Between Employee and Department&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So far when you add an employee, you cannot specify what department the employee belongs to. Let&amp;#8217;s fix that. In the Employee class add the following:&lt;/p&gt;
&lt;pre&gt;  @ManyToOne&lt;br/&gt;  public Department department;&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;@ManyToOne&lt;/code&gt; is a JPA annotation (in javax.persistence) which says that many Employees can belong to one Department.&lt;/p&gt;
&lt;p&gt;Save your work in Eclipse, then try to add a new Employee in the browser. You should see a new field titled &amp;#8220;department&amp;#8221; with a combo box list of options. If the department list is empty, then add a department, then try to add an employee again, you will see the added department in the list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create Company Model and Controller&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Create the Company class in the models package:&lt;/p&gt;
&lt;pre&gt;package models;&lt;br/&gt;import javax.persistence.Entity;&lt;br/&gt;import play.db.jpa.Model;&lt;br/&gt;&lt;br/&gt;@Entity&lt;br/&gt;public class Company extends Model {&lt;br/&gt;  public String name;&lt;br/&gt;  public String address;&lt;br/&gt;  public boolean isPublic;&lt;br/&gt;}&lt;/pre&gt;
&lt;p&gt;Next we want to create the controller for the Company model. The naming convention is to add &amp;#8220;s&amp;#8221; at the end of the model&amp;#8217;s name to create a controller. However, Companys does not spell right in English. The correct English spelling is Companies, so let&amp;#8217;s create this class in app/controllers:&lt;/p&gt;
&lt;pre&gt;package controllers;&lt;br/&gt;import models.Company;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;@CRUD.For(Company.class)&lt;br/&gt;&lt;/strong&gt;public class Companies extends CRUD {}&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;Notice how we use the &lt;code&gt;@CRUD.For&lt;/code&gt; annotation to indicate that this controller class is for the Company model object.&lt;/p&gt;
&lt;p&gt;To set the relationship between Department and Company, add the following to the Department model class:&lt;/p&gt;
&lt;pre&gt;  @ManyToOne&lt;br/&gt;  public Company company;&lt;br/&gt;&lt;/pre&gt;
&lt;p&gt;Which says that many departments can belong to one company.&lt;/p&gt;
&lt;p&gt;Save your work in Eclipse, then refresh the browser. Notice how companies is added to the list of object types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fixing Model Lists&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So far when you view the Companies list (for example) you see a list of Company[id] items. This is not too helpful, and the fix is very easy. Edit the model object and provide a toString() method that returns a more readable representation of the model object. For example, in the Company class, add the following:&lt;/p&gt;
&lt;pre&gt;  public String toString() {&lt;br/&gt;    return name;&lt;br/&gt;  }&lt;/pre&gt;
&lt;p&gt;Save and refresh the browser, you should see a more readable list of companies. You can use the same approach for Employee and Department.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Suppose you want to make the Employee&amp;#8217;s fullName required, and that it should not exceed 100 characters in length. Add the following annotations to the fullName declaration:&lt;/p&gt;
&lt;pre&gt;&lt;strong&gt;@Required @MaxSize(100)&lt;/strong&gt; public String fullName;&lt;/pre&gt;
&lt;p&gt;Both annotations are imported from &lt;code&gt;play.data.validation&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now if you try to add a new Employee, notice the comment under the fullName text field.  If you try to save an Employee without providing a fullName, you will get an error message.&lt;/p&gt;
&lt;p&gt;The are other interesting validation annotations like:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt; @Email&lt;/li&gt;
&lt;li&gt;@InFuture for future dates&lt;/li&gt;
&lt;li&gt;@InPast for past dates&lt;/li&gt;
&lt;li&gt;@Match for regular expressions matching&lt;/li&gt;
&lt;li&gt;@Max&lt;/li&gt;
&lt;li&gt;@Min&lt;/li&gt;
&lt;li&gt;@Range for a range of values&lt;/li&gt;
&lt;li&gt;@URL&lt;/li&gt;
&lt;li&gt;and others &amp;#8230;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Change Employee List View&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So far, when you view the Employee list, you will see a list of Employee names (assuming you added to toString() method). Suppose you want to change this view to see more details, like salary and dateOfHire. Again, Play provides a simple solution.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;At the command line, stop play: Ctrl-C&lt;/li&gt;
&lt;li&gt;Run this command&lt;br/&gt;&lt;br/&gt;&lt;code&gt;play crud:ov --template Employees/list&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;which will create the new file:&lt;code&gt; app/views/Employees/list.html&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run Play again&lt;br/&gt;&lt;br/&gt;&lt;code&gt;play run&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Refresh Eclipse (F5)&lt;/li&gt;
&lt;li&gt;In Eclipse, open the new file:&lt;code&gt; app/views/Employees/list.html&lt;/code&gt; &lt;br/&gt;This file shows the default display for a list of Employees. &lt;/li&gt;
&lt;li&gt;Look for the div with id=&amp;#8221;crudListTable&amp;#8221; and change the div&amp;#8217;s content to&lt;br/&gt;&lt;br/&gt;&lt;code&gt;#{crud.table fields:['fullName', 'dateOfHire', 'salary'] /}&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Save the file.&lt;/li&gt;
&lt;li&gt;In the browser, refresh the list of Employees and notice how it contains three columns now.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Change Labels of Fields&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Play uses the name of the field in the model object as the label for that field. To change that, open conf/messages file and add the following line:&lt;/p&gt;
&lt;pre&gt;fullName=Full Name&lt;/pre&gt;
&lt;p&gt;Save the file. Try to add a new Employee in the browser. Notice how the label for fullName has changed. You can do the same thing for any field name you choose.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This blog touched only one module (CRUD) of Play. Play contains many other modules which make the life of Java web programmer easier. Examples include:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Security.&lt;/li&gt;
&lt;li&gt;Spring, and Guice integration.&lt;/li&gt;
&lt;li&gt;GWT&lt;/li&gt;
&lt;li&gt;Scala and Akka integration.&lt;/li&gt;
&lt;li&gt;Maven dependency&lt;/li&gt;
&lt;li&gt;&amp;#8230;&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The main advantages of Play as I see it are:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The quick development feedback cycle: code-save-browserRefresh. Play has removed the need to compile/deploy as used in typical Java web frameworks.&lt;/li&gt;
&lt;li&gt;Testability: I have not talked about testability here because I wanted to show CRUD support at its simplest, but Play has great testing support, which you can read about at &lt;a href="http://www.playframework.org/documentation/1.0.3/test"&gt;Play&amp;#8217;s test documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</description><link>http://ahabra.tumblr.com/post/675784000</link><guid>http://ahabra.tumblr.com/post/675784000</guid><pubDate>Thu, 17 Jun 2010 02:56:00 -0400</pubDate><category>CRUD</category><category>java</category><category>playframework</category></item><item><title>SUSHI and COUNTER</title><description>&lt;p&gt;My notes about COUNTER and SUSHI&lt;/p&gt;
&lt;p&gt;COUNTER: &lt;strong&gt;C&lt;/strong&gt;ounting &lt;strong&gt;O&lt;/strong&gt;nline &lt;strong&gt;U&lt;/strong&gt;sage of &lt;strong&gt;N&lt;/strong&gt;etworked &lt;strong&gt;E&lt;/strong&gt;lectronic &lt;strong&gt;R&lt;/strong&gt;esources.   &lt;a href="http://www.projectcounter.org"&gt;projectcounter.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;SUSHI: &lt;strong&gt;S&lt;/strong&gt;tandardized &lt;strong&gt;U&lt;/strong&gt;sage &lt;strong&gt;S&lt;/strong&gt;tatistics &lt;strong&gt;H&lt;/strong&gt;arvesting &lt;strong&gt;I&lt;/strong&gt;nitiative. &lt;a href="http://www.niso.org/workrooms/sushi/"&gt;&lt;a href="http://www.niso.org/workrooms/sushi/"&gt;www.niso.org/workrooms/sushi/&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;COUNTER is a standard used by libraries and publishers to report online usage statistics. The reports can be in CSV, spreadsheets, or XML. There are several types of reports; Journal, Database, and Consortium Reports. All reports are monthly.&lt;/p&gt;
&lt;p&gt;SUSHI is a Web Service (SOAP) standard which allows requesting a COUNTER report in XML format. The web service request specifies what COUNTER report is needed, while the response will contain (embedded) the report. See &lt;a title="SUSHI tutorial " target="_blank" href="http://docs.google.com/View?docid=d2dhjwd_140d923m7fh"&gt;SUSHI Tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The SUSHI web service should validate the request before responding. Validations could include:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;Client IP address. As a security measure.&lt;/li&gt;
&lt;li&gt;Customer ID.&lt;/li&gt;
&lt;li&gt;Report type.&lt;/li&gt;
&lt;li&gt;Date range.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;&lt;!-- more --&gt;&lt;strong&gt;Sample SUSHI Request&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;           (Items in &lt;strong&gt;bold&lt;/strong&gt; are required)&lt;strong&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" &lt;br/&gt;          xmlns:coun="http://www.niso.org/schemas/sushi/counter" &lt;br/&gt;          xmlns:sus="http://www.niso.org/schemas/sushi"&amp;gt;&lt;br/&gt;   &amp;lt;soapenv:Header/&amp;gt;&lt;br/&gt;   &amp;lt;soapenv:Body&amp;gt;&lt;br/&gt;      &amp;lt;coun:ReportRequest Created="?" ID="?"&amp;gt;&lt;br/&gt;         &amp;lt;sus:Requestor&amp;gt;&lt;br/&gt;&lt;em&gt;             &amp;lt;!-- ID contains the domain of service making request, e.g. &lt;a href="http://www.x.com"&gt;http://www.x.com&lt;/a&gt;&lt;br/&gt;                   It also can be used for authentication, e.g. userName/password&lt;br/&gt;               --&amp;gt;&lt;br/&gt;&lt;/em&gt;            &amp;lt;sus:&lt;strong&gt;ID&lt;/strong&gt;&amp;gt;demo&amp;lt;/sus:ID&amp;gt;&lt;br/&gt;            &amp;lt;sus:Name&amp;gt;?&amp;lt;/sus:Name&amp;gt;&lt;br/&gt;            &amp;lt;sus:Email&amp;gt;?&amp;lt;/sus:Email&amp;gt;&lt;br/&gt;         &amp;lt;/sus:Requestor&amp;gt;&lt;br/&gt;         &amp;lt;sus:CustomerReference&amp;gt;&lt;br/&gt;            &amp;lt;sus:&lt;strong&gt;ID&lt;/strong&gt;&amp;gt;demo&amp;lt;/sus:ID&amp;gt; &lt;em&gt; &amp;lt;!-- could be similar to Requestor ID -&amp;gt;&lt;/em&gt;&lt;br/&gt;            &amp;lt;!--Optional:--&amp;gt;&lt;br/&gt;            &amp;lt;sus:Name&amp;gt;?&amp;lt;/sus:Name&amp;gt;&lt;br/&gt;         &amp;lt;/sus:CustomerReference&amp;gt;&lt;br/&gt;         &amp;lt;sus:ReportDefinition &lt;strong&gt;Name&lt;/strong&gt;="JR1" &lt;strong&gt;Release&lt;/strong&gt;="3"&amp;gt; &lt;em&gt;&amp;lt;!-- release is version# --&amp;gt;&lt;/em&gt;&lt;br/&gt;            &amp;lt;sus:Filters&amp;gt;&lt;br/&gt;               &amp;lt;sus:UsageDateRange&amp;gt;&lt;br/&gt;                  &amp;lt;sus:&lt;strong&gt;Begin&lt;/strong&gt;&amp;gt;2009-01-06&amp;lt;/sus:Begin&amp;gt;&lt;br/&gt;                  &amp;lt;sus:&lt;strong&gt;End&lt;/strong&gt;&amp;gt;2009-01-06&amp;lt;/sus:End&amp;gt;&lt;br/&gt;               &amp;lt;/sus:UsageDateRange&amp;gt;&lt;br/&gt;            &amp;lt;/sus:Filters&amp;gt;&lt;br/&gt;         &amp;lt;/sus:ReportDefinition&amp;gt;&lt;br/&gt;      &amp;lt;/coun:ReportRequest&amp;gt;&lt;br/&gt;   &amp;lt;/soapenv:Body&amp;gt;&lt;br/&gt;&amp;lt;/soapenv:Envelope&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Sample SUSHI Response (Error)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&lt;br/&gt;       xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" &lt;br/&gt;       xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" &lt;br/&gt;       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&lt;br/&gt;       xmlns:xsd="http://www.w3.org/1999/XMLSchema" &amp;gt;&lt;br/&gt;   &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br/&gt;      &amp;lt;ReportResponse ID="demo"&lt;br/&gt;            xsi:schemaLocation="http://www.niso.org/schemas/sushi/counter &lt;br/&gt;                             &lt;a href="http://www.niso.org/schemas/sushi/counter_sushi3_0.xsd"&gt;http://www.niso.org/schemas/sushi/counter_sushi3_0.xsd&lt;/a&gt;" &lt;br/&gt;            Created="2010-06-02T19:40:14Z" &lt;br/&gt;            xmlns="http://www.niso.org/schemas/sushi/counter"&lt;br/&gt;            xmlns:s="http://www.niso.org/schemas/sushi"&lt;br/&gt;            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &amp;gt;&lt;br/&gt;         &amp;lt;s:Requestor&amp;gt;&lt;br/&gt;            &amp;lt;s:&lt;strong&gt;ID&lt;/strong&gt;&amp;gt;demo&amp;lt;/s:ID&amp;gt;&lt;br/&gt;            &amp;lt;s:Name&amp;gt;?&amp;lt;/s:Name&amp;gt;&lt;br/&gt;            &amp;lt;s:Email&amp;gt;?&amp;lt;/s:Email&amp;gt;&lt;br/&gt;         &amp;lt;/s:Requestor&amp;gt;&lt;br/&gt;         &amp;lt;s:CustomerReference&amp;gt;&lt;br/&gt;            &amp;lt;s:ID&amp;gt;?&amp;lt;/s:ID&amp;gt;&lt;br/&gt;            &amp;lt;s:Name&amp;gt;?&amp;lt;/s:Name&amp;gt;&lt;br/&gt;         &amp;lt;/s:CustomerReference&amp;gt;&lt;br/&gt;         &amp;lt;s:ReportDefinition &lt;strong&gt;Name&lt;/strong&gt;="JR1" &lt;strong&gt;Release&lt;/strong&gt;="3"&amp;gt;&lt;br/&gt;            &amp;lt;s:Filters&amp;gt;&lt;br/&gt;               &amp;lt;s:UsageDateRange&amp;gt;&lt;br/&gt;                  &amp;lt;s:&lt;strong&gt;Begin&lt;/strong&gt;&amp;gt;2008-01-01&amp;lt;/s:Begin&amp;gt;&lt;br/&gt;                  &amp;lt;s:&lt;strong&gt;End&lt;/strong&gt;&amp;gt;2008-03-01&amp;lt;/s:End&amp;gt;&lt;br/&gt;               &amp;lt;/s:UsageDateRange&amp;gt;&lt;br/&gt;            &amp;lt;/s:Filters&amp;gt;&lt;br/&gt;         &amp;lt;/s:ReportDefinition&amp;gt;&lt;br/&gt;         &amp;lt;Exception Created="2010-06-02T19:40:14Z" xmlns="http://www.niso.org/schemas/sushi"&amp;gt;&lt;br/&gt;            &amp;lt;Number&amp;gt;2010&amp;lt;/Number&amp;gt;&lt;br/&gt;            &amp;lt;Severity&amp;gt;Error&amp;lt;/Severity&amp;gt;&lt;br/&gt;            &amp;lt;Message&amp;gt;The Requestor ID (demo) has not been authorized to harvest usage for the institution.&amp;lt;/Message&amp;gt;&lt;br/&gt;         &amp;lt;/Exception&amp;gt;&lt;br/&gt;      &amp;lt;/ReportResponse&amp;gt;&lt;br/&gt;   &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br/&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Sample SUSHI Response (success)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&amp;lt;SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"&lt;br/&gt;       xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" &lt;br/&gt;       xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" &lt;br/&gt;       xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&lt;br/&gt;       xmlns:xsd="http://www.w3.org/1999/XMLSchema" &amp;gt;&lt;br/&gt;   &amp;lt;SOAP-ENV:Body&amp;gt;&lt;br/&gt;      &amp;lt;ReportResponse ID="demo" &lt;br/&gt;            xsi:schemaLocation="http://www.niso.org/schemas/sushi/counter &lt;br/&gt;                             &lt;a href="http://www.niso.org/schemas/sushi/counter_sushi3_0.xsd"&gt;http://www.niso.org/schemas/sushi/counter_sushi3_0.xsd&lt;/a&gt;" &lt;br/&gt;            Created="2010-06-02T20:57:05Z" &lt;br/&gt;            xmlns="http://www.niso.org/schemas/sushi/counter"&lt;br/&gt;            xmlns:s="http://www.niso.org/schemas/sushi"&lt;br/&gt;            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" &amp;gt;&lt;br/&gt;         &amp;lt;s:Requestor&amp;gt;&lt;br/&gt;            &amp;lt;s:&lt;strong&gt;ID&lt;/strong&gt;&amp;gt;demo&amp;lt;/s:ID&amp;gt;&lt;br/&gt;            &amp;lt;s:Name&amp;gt;?&amp;lt;/s:Name&amp;gt;&lt;br/&gt;            &amp;lt;s:Email&amp;gt;?&amp;lt;/s:Email&amp;gt;&lt;br/&gt;         &amp;lt;/s:Requestor&amp;gt;&lt;br/&gt;         &amp;lt;s:CustomerReference&amp;gt;&lt;br/&gt;            &amp;lt;s:ID&amp;gt;demo&amp;lt;/s:ID&amp;gt;&lt;br/&gt;            &amp;lt;s:Name&amp;gt;?&amp;lt;/s:Name&amp;gt;&lt;br/&gt;         &amp;lt;/s:CustomerReference&amp;gt;&lt;br/&gt;         &amp;lt;s:ReportDefinition &lt;strong&gt;Name&lt;/strong&gt;="JR1" &lt;strong&gt;Release&lt;/strong&gt;="3"&amp;gt;&lt;br/&gt;            &amp;lt;s:Filters&amp;gt;&lt;br/&gt;               &amp;lt;s:UsageDateRange&amp;gt;&lt;br/&gt;                  &amp;lt;s:&lt;strong&gt;Begin&lt;/strong&gt;&amp;gt;2009-01-06&amp;lt;/s:Begin&amp;gt;&lt;br/&gt;                  &amp;lt;s:&lt;strong&gt;End&lt;/strong&gt;&amp;gt;2009-01-06&amp;lt;/s:End&amp;gt;&lt;br/&gt;               &amp;lt;/s:UsageDateRange&amp;gt;&lt;br/&gt;            &amp;lt;/s:Filters&amp;gt;&lt;br/&gt;         &amp;lt;/s:ReportDefinition&amp;gt;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;         &amp;lt;!-- next is the COUNTER report --&amp;gt;&lt;/em&gt;&lt;br/&gt;         &amp;lt;Report&amp;gt;&lt;br/&gt;            &amp;lt;Report Created="2010-06-02T20:57:06Z" &lt;br/&gt;                 Title="Number of Successful Full-Text Article Requests by Month and Journal" &lt;br/&gt;                 ID="JR1:3" Version="3" &lt;br/&gt;                 xmlns="http://www.niso.org/schemas/counter"&amp;gt;&lt;br/&gt;               &amp;lt;Vendor&amp;gt;&lt;br/&gt;                  &amp;lt;Name&amp;gt;Project Euclid&amp;lt;/Name&amp;gt;&lt;br/&gt;                  &amp;lt;ID&amp;gt;37e194bf-898e-4884-aa14-5f73e4c14ae5&amp;lt;/ID&amp;gt;&lt;br/&gt;                  &amp;lt;Contact&amp;gt;&lt;br/&gt;                     &amp;lt;Contact&amp;gt;Project Euclid Support&amp;lt;/Contact&amp;gt;&lt;br/&gt;                     &amp;lt;E-mail&amp;gt;EUCLID-L@cornell.edu&amp;lt;/E-mail&amp;gt;&lt;br/&gt;                  &amp;lt;/Contact&amp;gt;&lt;br/&gt;                  &amp;lt;WebSiteUrl&amp;gt;http://www.projecteuclid.org&amp;lt;/WebSiteUrl&amp;gt;&lt;br/&gt;               &amp;lt;/Vendor&amp;gt;&lt;br/&gt;               &amp;lt;Customer&amp;gt;&lt;br/&gt;                  &amp;lt;Name&amp;gt;Demo Institution&amp;lt;/Name&amp;gt;&lt;br/&gt;                  &amp;lt;ID&amp;gt;demo&amp;lt;/ID&amp;gt;&lt;br/&gt;                  &amp;lt;WebSiteUrl/&amp;gt;&lt;br/&gt;&lt;br/&gt;                  &lt;em&gt;&amp;lt;!-- repeating ReportItems start next --&amp;gt;&lt;/em&gt;&lt;br/&gt;                  &amp;lt;ReportItems&amp;gt;&lt;br/&gt;                     &amp;lt;ItemIdentifier&amp;gt;&lt;br/&gt;                        &amp;lt;Type&amp;gt;ISSN&amp;lt;/Type&amp;gt;&lt;br/&gt;                        &amp;lt;Value&amp;gt;1085-3375&amp;lt;/Value&amp;gt;&lt;br/&gt;                     &amp;lt;/ItemIdentifier&amp;gt;&lt;br/&gt;                     &amp;lt;ItemPlatform&amp;gt;Project Euclid&amp;lt;/ItemPlatform&amp;gt;&lt;br/&gt;                     &amp;lt;ItemPublisher&amp;gt;Hindawi Publishing Corporation&amp;lt;/ItemPublisher&amp;gt;&lt;br/&gt;                     &amp;lt;ItemName&amp;gt;Abstract and Applied Analysis&amp;lt;/ItemName&amp;gt;&lt;br/&gt;                     &amp;lt;ItemDataType&amp;gt;Journal&amp;lt;/ItemDataType&amp;gt;&lt;br/&gt;                     &amp;lt;ItemPerformance&amp;gt;&lt;br/&gt;                        &amp;lt;Period&amp;gt;&lt;br/&gt;                           &amp;lt;Begin&amp;gt;2009-01-01&amp;lt;/Begin&amp;gt;&lt;br/&gt;                           &amp;lt;End&amp;gt;2009-01-31&amp;lt;/End&amp;gt;&lt;br/&gt;                        &amp;lt;/Period&amp;gt;&lt;br/&gt;                        &amp;lt;Category&amp;gt;Requests&amp;lt;/Category&amp;gt;&lt;br/&gt;                        &amp;lt;Instance&amp;gt;&lt;br/&gt;                           &amp;lt;MetricType&amp;gt;ft_total&amp;lt;/MetricType&amp;gt;&lt;br/&gt;                           &amp;lt;Count&amp;gt;586&amp;lt;/Count&amp;gt;&lt;br/&gt;                        &amp;lt;/Instance&amp;gt;&lt;br/&gt;                     &amp;lt;/ItemPerformance&amp;gt;&lt;br/&gt;                     &amp;lt;ItemPerformance&amp;gt;&lt;br/&gt;                        &amp;lt;Period&amp;gt;&lt;br/&gt;                           &amp;lt;Begin&amp;gt;2009-01-01&amp;lt;/Begin&amp;gt;&lt;br/&gt;                           &amp;lt;End&amp;gt;2009-01-31&amp;lt;/End&amp;gt;&lt;br/&gt;                        &amp;lt;/Period&amp;gt;&lt;br/&gt;                        &amp;lt;Category&amp;gt;Requests&amp;lt;/Category&amp;gt;&lt;br/&gt;                        &amp;lt;Instance&amp;gt;&lt;br/&gt;                           &amp;lt;MetricType&amp;gt;ft_pdf&amp;lt;/MetricType&amp;gt;&lt;br/&gt;                           &amp;lt;Count&amp;gt;586&amp;lt;/Count&amp;gt;&lt;br/&gt;                        &amp;lt;/Instance&amp;gt;&lt;br/&gt;                     &amp;lt;/ItemPerformance&amp;gt;&lt;br/&gt;                     &amp;lt;ItemPerformance&amp;gt;&lt;br/&gt;                        &amp;lt;Period&amp;gt;&lt;br/&gt;                           &amp;lt;Begin&amp;gt;2009-01-01&amp;lt;/Begin&amp;gt;&lt;br/&gt;                           &amp;lt;End&amp;gt;2009-01-31&amp;lt;/End&amp;gt;&lt;br/&gt;                        &amp;lt;/Period&amp;gt;&lt;br/&gt;                        &amp;lt;Category&amp;gt;Requests&amp;lt;/Category&amp;gt;&lt;br/&gt;                        &amp;lt;Instance&amp;gt;&lt;br/&gt;                           &amp;lt;MetricType&amp;gt;ft_html&amp;lt;/MetricType&amp;gt;&lt;br/&gt;                           &amp;lt;Count&amp;gt;0&amp;lt;/Count&amp;gt;&lt;br/&gt;                        &amp;lt;/Instance&amp;gt;&lt;br/&gt;                     &amp;lt;/ItemPerformance&amp;gt;&lt;br/&gt;                  &amp;lt;/ReportItems&amp;gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;                  &lt;em&gt;&amp;lt;!-- more ReportItems --&amp;gt;&lt;/em&gt;&lt;br/&gt;                  &lt;br/&gt;&lt;br/&gt;               &amp;lt;/Customer&amp;gt;&lt;br/&gt;            &amp;lt;/Report&amp;gt;&lt;br/&gt;         &amp;lt;/Report&amp;gt;&lt;br/&gt;&lt;br/&gt;      &amp;lt;/ReportResponse&amp;gt;&lt;br/&gt;   &amp;lt;/SOAP-ENV:Body&amp;gt;&lt;br/&gt;&amp;lt;/SOAP-ENV:Envelope&amp;gt;&lt;/pre&gt;</description><link>http://ahabra.tumblr.com/post/660598987</link><guid>http://ahabra.tumblr.com/post/660598987</guid><pubDate>Thu, 03 Jun 2010 14:01:00 -0400</pubDate></item></channel></rss>
