Hey Rick,
I am working on a new system and will give Crank a try for the crud
pieces. Thanks for making this available.
Andy
On Aug 10, 2007, at 2:02 AM, Rick Hightower wrote:
Please check out...
http://www.jroller.com/RickHigh/entry/crank_crud_intro
Crank is a framework for doing CRUD based applications very
quickly. It is a nascent framework, but it has made some recent
progress. Crank is based on ideas we explored with Presto and a
much earlier framework that I worked on at eBlox .
Scott Fauerbach, Chris Mathias and many others worked on Presto.
Scott Fauerbach and many others worked on the original framework
(which I believe we called CRUD which was Struts/EJB2 based circa
2001). Currently Paul Tabor, Chris Mathias, and many others are
working on Crank.
The major improvements from Presto and Crank is that Crank is
geared towards annotation driven development, Generics with less
AOP than Presto (but still some). There are 20 to 40 application
launched on top of Presto and a fulltime ArcMind guy maintaining it.
Out of the box with Crank you can easily create CRUD listings. For
example the following code would produce a CRUD listing that allows
all columns to be sorted and filtered:
"expListForm" rendered="#{controllerBean.showListing}">
"${paginators['Employee']}"
jsfCrudAdapter="${cruds['Employee']}"
propertyNames="firstName,lastName,active,dob,age,phone,email,departmen
t.name,description"
pageTitle="Employees"
parentForm="expListForm"
reRender="${reRender}"
crud="${cruds['Employee'].controller}"/>
The above produces the following listing (from the example crud
app, which you can download or get from SVN or read more about
and try out).
The listing has pagination, each column is filterable (dates,
strings, booleans, relationships). By filterable, I mean you can
click the inspection icon (magnifying glass) and enter in filters
for that column. You can apply as many filters and sorts (order
bys) as you need. You can clear filters and sorts as well. You can
sort more than one field.
There is no code you need to write. Underneath the covers, the
listing using our own Criteria API which has a translator that
translates that to JPA QL then uses are GenericDAO to retrieve the
results from the database. This is done without writing any
additional code. The idea is that if you have a model with JPA
annotations that works, then you should be able to easily create a
listing.
The forms management is nice in that it will automatically render
the right kind of input field. It will render file upload, date
input, one to many relationship selection (list box), booleans
(check box), strings (text input), large strings (text areas) and
more.
Let's say for example that you have an Employee object with JPA
annotations as follows:
@Entity
public class Employee implements Serializable {
@Id
@GeneratedValue( strategy = GenerationType.AUTO )
private Long id;
@Column( nullable = false, length = 32 )
private String firstName;
private String lastName;
@Column( length = 150 )
private String description;
private boolean active;
private int age;
private String email;
private String phone;
private Integer numberOfPromotions;
private EmployeeStatus status;
private Integer rank;
private Date dob;
@OneToMany( cascade = CascadeType.ALL )
private Set tasks;
@ManyToOne( )
private Department department;
private PersistedFile file;
public PersistedFile getFile() {
return file;
}
public void setFile( PersistedFile file ) {
this.file = file;
}
public void addTask( Task task ) {
this.tasks.add( task );
}
public void removeTask( Task task ) {
this.tasks.remove( task );
}
public Long getId() {
return id;
}
public void setId( Long id ) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
@Required
@ProperNoun
@Length( min = 2, max = 35 )
public void setFirstName( String firstName ) {
this.firstName = firstName;
}
public Department getDepartment() {
return department;
}
public void setDepartment( Department department ) {
System.out.println( "SET DEPARTMENT " + department );
this.department = department;
}
public boolean isActive() {
return active;
}
public void setActive( boolean active ) {
this.active = active;
}
public int getAge() {
return age;
}
@Required
@LongRange( min = 18L, max = 135L )
public void setAge( int age ) {
this.age = age;
}
public Integer getNumberOfPromotions() {
return numberOfPromotions;
}
public void setNumberOfPromotions( Integer numberOfPromotions ) {
this.numberOfPromotions = numberOfPromotions;
}
public String getLastName() {
return lastName;
}
@Required
@ProperNoun
@Length( min = 2, max = 35 )
public void setLastName( String lastName ) {
this.lastName = lastName;
}
public EmployeeStatus getStatus() {
return status;
}
public void setStatus( EmployeeStatus status ) {
this.status = status;
}
public Integer getRank() {
return rank;
}
public void setRank( Integer rank ) {
this.rank = rank;
}
public Date getDob() {
return dob;
}
public void setDob( Date dob ) {
this.dob = dob;
}
public Set getTasks() {
return tasks;
}
public void setTasks( Set tasks ) {
this.tasks = tasks;
}
public String getDescription() {
return description;
}
public void setDescription( String description ) {
this.description = description;
}
public String getEmail() {
return email;
}
@Email
public void setEmail( String email ) {
this.email = email;
}
public String getPhone() {
return phone;
}
@Phone
public void setPhone( String phone ) {
this.phone = phone;
}
}
We can easily render the above object in a form without writng a
lot of code. We can allow editing of the OneToMany relationship
(Employee->Tasks) and the ManyToOne relationship (Employee-
>Department) without much effort and practically no code. The idea
behind Crank Crud is reasonable behavior. Also we read and process
the meta-data stored in the JPA annotations, Java types, and
validation annotations to render the right kind of input fields and
validation.
Here is the page that renders a form to edit the Employee object
and its relationship.
"pagForm" prependId="false" enctype="multipart/form-data">
"${cruds['Employee'].controller}"
propertyNames="firstName,lastName,active,dob,age,phone,email,departmen
t,description,file">
var="taskDetailController" value="$
{employeeCrud.controller.children.tasks}" />
"${taskDetailController}"
propertyNames="name,startDate,endDate,complete"
relationshipCollection="#
{taskDetailController.model}"/>
The above renders this form:
There is quite a bit going on. The above allows you to edit first
name, last name, active, and dob (date of birth) using text input,
checkboxes and calendar widget with no effort. More amazingly, you
are able to change department which is a ManyToOne relationship
with no additonal code. Also a file input field is rendered for the
file property. Even more amazingly the above allows you to easily
render a master detail within the form (Employee has Tasks). I have
hoped I piqued your interests.
In addtion, to provide validation you can use validation. Notice
that the email and phone (as well as others properties) are
annotated with validation rules which get processed as runtime:
@Required
@ProperNoun
@Length( min = 2, max = 35 )
public void setLastName( String lastName ) {
this.lastName = lastName;
}
@Email
public void setEmail( String email ) {
this.email = email;
}
@Phone
public void setPhone( String phone ) {
this.phone = phone;
}
Here is an example of runtime processing (the example needs some
CSS love... sorry):
A couple of parting shots, Crank is a tiered framework much of the
code has nothing to do with JSF and can work easily with other
frameworks namely Spring MVC. We are using quite a bit of Crank
with a Spring MVC application. There is an example of integating
Crank Validation with Spring MVC and a Crank Crud Spring MVC
example is in the works (Chris Mathias).
The example Crank Crud is based on JSF, Ajax4JSF, Facelets, Spring,
and JPA (Hibernate based). The listings are Ajax enabled thanks to
Ajax4JSF.
So why am I writing this. Bragging? No... Well maybe. Do I want
feedback? Not really... although suggestions are welcome. Mainly I
am writing this becuase I am looking for help. Are there other
people out there who must use JSF or want to use JSF and also need
to create CRUD listings? Then please use Crank or better yet help
us improve it. I'd love to get a few more solid commiters. In
addition, I'd love to see Crank ported to other web frameworks
(Struts 2, better Spring MVC support) and GUI frameworks (Swing,
GWT). I am meeting tomorrow with Chris Mathias to discuss porting
the Crank CRUD portion to Spring MVC.
You can download Crank or get from SVN . More to come.... There
have been 1,000 downloads of Crank so far.
Why the name Crank?
I get asked this a lot. I picked the name Crank as in "Crank it
out" and the name has nothing to do with drugs. I get asked about
this a lot. To be clear: The framework is named Crank as in: "crank
out, to make or produce in a mass-production, effortless, or
mechanical way: She's able to crank out one (CRUD listing) after
another" and "crank up: to get started or ready", "to stimulate,
activate, or produce", and most importantly "to increase one's
efforts, output, etc.: Industry began to crank up after the new
(CRUD framework became our corporate standard)." http://
www.dictionary.com
Also, I thought it was cool that Crank, Struts and Spring was
something you find in a Ford Model T. Crank is the production line
way to create CRUD listings.
--
Andrew Barton
eBlox, Inc.
512.867.1001 x101
Check out the new Free Distributor Resource Center (including an
online directory of more than 1200
Suppliers)! http://www.distributorresourcecenter.com