RIFE/Crud uses your bean classes as the source for the generation of CRUD administration web interfaces and optionally the corresponding database structure.
Let's look at a simple news item posting interface. This example has no associations or many-to-one mappings. If you're interested in those, the source archive of RIFE/Crud and eCalendar provide all the information you need
.
Declaring the bean
This is the bean implementation:
public class Newsitem
{
private int mId = -1;
private Date mMoment = new Date();
private byte[] mImage = null;
private String mTitle = null;
private String mBody = null;
private String mExcerpt = null;
private String mExtended = null;
private String mSource = null;
private boolean mDraft = false;
public void setId(int id) { mId = id; }
public int getId() { return mId; }
public void setMoment(Date moment) { mMoment = moment; }
public Date getMoment() { return mMoment; }
public void setTitle(String title) { mTitle = title; }
public String getTitle() { return mTitle; }
public void setBody(String body) { mBody = body; }
public String getBody() { return mBody; }
public void setExcerpt(String excerpt) { mExcerpt = excerpt; }
public String getExcerpt() { return mExcerpt; }
public void setExtended(String extended) { mExtended = extended; }
public String getExtended() { return mExtended; }
public void setImage(byte[] image) { mImage = image; }
public byte[] getImage() { return mImage; }
public void setSource(String source) { mSource = source; }
public String getSource() { return mSource; }
public void setDraft(boolean draft) { mDraft = draft; }
public boolean isDraft() { return mDraft; }
}
and we're adding constraints to its properties to add more behavior:
public class Newsitem extends MetaData
{
/* ... the member variables have not been repeated ... */
protected void activateMetaData()
{
addConstraint(new ConstrainedBean()
.defaultOrder("moment", ConstrainedBean.DESC)
.defaultOrder("title"));
addConstraint(new ConstrainedProperty("id")
.editable(false)
.identifier(true));
addConstraint(new ConstrainedProperty("moment")
.editable(false)
.listed(true)
.notNull(true)
.format(RifeConfig.Tools.getDefaultLongDateFormat()));
addConstraint(new ConstrainedProperty("image")
.notNull(true)
.file(true)
.listed(true)
.mimeType(MimeType.IMAGE_PNG)
.contentAttribute("width", 150));
addConstraint(new ConstrainedProperty("title")
.notNull(true)
.notEmpty(true)
.maxLength(100)
.listed(true));
addConstraint(new ConstrainedProperty("body")
.notNull(true)
.notEmpty(true)
.mimeType(MimeType.APPLICATION_XHTML)
.autoRetrieved(true)
.fragment(true));
addConstraint(new ConstrainedProperty("excerpt")
.mimeType(MimeType.APPLICATION_XHTML)
.autoRetrieved(true)
.fragment(true));
addConstraint(new ConstrainedProperty("extended")
.mimeType(MimeType.APPLICATION_XHTML)
.autoRetrieved(true)
.fragment(true));
addConstraint(new ConstrainedProperty("draft")
.notNull(true)
.defaultValue(false));
addConstraint(new ConstrainedProperty("source")
.url(true)
.maxLength(150));
}
/* ... the accessors have not been repeated ... */
}
Adding a participant to create the database structure
RIFE/Crud can automatically create the database structure that corresponds to the constraints that your declared. Note that this is not mandatory and that RIFE's persistence layer can map the properties to existing tables. Properties that have a mime-type are however stored in the content management framework, and that structure has to be present beforehand of course.
Example repository participants:
<rep>
<property name="datasource"><datasource><config param="DATASOURCE_NAME"/></datasource></property>
<participant param="rep/config.xml">ParticipantConfig</participant>
<participant param="rep/datasources.xml">ParticipantDatasources</participant>
<participant param="com.uwyn.rife.crud.samples.beans.Newsitem"
blocking="true">CreateCrudStructureParticipant</participant>
<participant param="sites/main.xml">ParticipantSite</participant>
</rep>
 | Beware of the order
The participant of a class with a many-to-one reference towards another class, has to added after the participant of the class it references. |
Generating the CRUD interface
To automatically generate the site-structure for the Newsitem CRUD operations, you only need to add this line to a site declaration:
<site>
<subsite id="NEWS" urlprefix="/news"
file="crud:com.uwyn.rife.crud.samples.beans.Newsitem"/>
</site>
Localization
By default, RIFE/Crud generates generic text placeholders that can easily be changed with java properties files. It looks for the properties file in a directory l10n/crud in your project's classpath. The properties files work in a cascading fashion:
product_title = RIFE Crud - Samples
product_name = RIFE Crud
menu_item-com.uwyn.rife.crud.samples.beans.Newsitem = news items
menu_item-com.uwyn.rife.crud.samples.beans.Newsitem-home = home
menu_item-com.uwyn.rife.crud.samples.beans.Newsitem-browse = browse
menu_item-com.uwyn.rife.crud.samples.beans.Newsitem-add = add
menu_item-com.uwyn.rife.crud.samples.beans.Newsitem-edit = edit
menu_item-com.uwyn.rife.crud.samples.beans.Newsitem-delete = delete
form_label-mandatory = mandatory
column_label-actions = actions
button_label-edit = Edit
button_label-delete = Delete
button_label-home = Home
button_label-cancel = Cancel
error_area_title = The following errors occured
error_mandatory = mandatory
error_wronglength = wrong length
error_notsame = not the same
error_invalid = invalid
error_unicity = already exists
error_unexpected = unexpected error
label-pages = Pages
window_title = RIFE Crud - Samples - Admin - News
page_title-home = Pick a menu item to perform an action
page_title-browse = Browse the available news items
page_title-add = Add a new news item
page_title-edit = Edit an existing news item
page_title-delete = Delete an existing news item
page_content-home = News items are posted on the front page and the news section of the site.
page_content-browse-none_available = There are no news items available.
page_content-add-success_header = Success!
page_content-add-success_message = The news item has been added successfully.
page_content-delete-success_header = Success!
page_content-delete-success_message = The news item has been deleted successfully.
page_content-edit-success_header = Success!
page_content-edit-success_message = The news item has been edited successfully.
button_label-add_first = Add the first news item
button_label-add_more = Add more news items
button_label-add = Add a new news item
button_label-browse = Browse the available news items
button_label-save = Save the news item
momentString = moment
image-legend = (width 150px)
body-help = <div class="form_help">You can enter the complete text of the news \
item here. Only valid XHTML is allowed.</div>
Resulting interface
This is all you need to do, the result is the following interface:
browse

addition

edition

deletion

More information
RIFE/Crud can be fully customized, you can find detailed documentation about how to do so in the customization page.
More information in our introduction and tutorial video
.