Free Trade with Eclipse: An Introduction to the JFire Open-Source ERP Framework
Imagine several companies want to trade arbitrary products in a decentralised network, and you have to write the software. Not an easy task, if specialised GUI for different sectors must be integrated into one application. If you plan to use the Eclipse Rich Client Platform, it's worth having a look at the ERP framework JFire.
If you have already written a shop system or a similar project, you know that there are a lot of requirements that more or less common to all these systems. Thus, it would be desirable to have a platform, which fulfills many of these requirements and eases extensions into every direction. But what do these common requirements look like? Some of them can easily be formulated, such as the concepts of ‘customer’ or ‘order’. Others, however, are harder to find. For example, a price configuration can be highly varied as the case arises. Despite these variances, common ground emerges from generalisation and abstraction. JFire’s goal is to bundle solutions for these common requirements and to provide them as a modular ERP framework that is easily extensible. It aims to cover most usual cases and allows for extraordinary solutions by providing numerous interfaces and extension points.
Basic Set Up
In order to understand the structure of the client with its extension points, we first need to look at the big picture.
JFire's [1] server side is based on the Java 2 Platform Enterprise Edition (J2EE 1.4) and Java Data Objects (JDO 2.0). Due to this architecture, it's easy to extend the data model by Java inheritance without worrying about SQL. The communication between client and server or between two servers is handled comfortably by J2EE. This backend allows to easily implement interfaces to other systems or clients (for example, a Web shop).
At the moment, JFire contains an Eclipse-RCP-based client. It also includes five perspectives for system administration (users, access rights, and so on), product configuration, order processing, report design, and a 2D editor. Since most modules are split into a user and an administrator plug-in, an installation can be closely adjusted to the operator's needs. This does not only save time when updating, but helps to keep a normal user's GUI simple as well.
Elucidations
Extension Point: An extension point is a plug-in's interface description that allows other plug-ins to integrate additional functionality into the existing logic. The Eclipse RCP uses this mechanism, for example, to permit populating the main menu with own entries.
Extension: An extension is used to extend a previously defined extension point. You can declare an unlimited number of extensions for each extension point.
Jboss: JBoss [2] is a widely used open source J2EE server.
J2EE: J2EE [3] is the abbreviation for Java 2 Platform Enterprise Edition. This standard was developed by Sun in order to simplify the development of distributed applications.
JPOX: JPOX [4] is open source and was selected by Sun to be the reference implementation of JDO.
JDO: Java Data Objects [5] is a standard for data persistence developed by Sun. It allows for storing and retrieving Java objects to / from an arbitrary database. Currently, JDO is mostly used for object relational mapping, because relational databases are still most prevalent. However, persisting into object databases or even flatfiles using the same API is possible.
EJB: Enterprise Java Beans (EJB) are components managed by a J2EE server. They ease the development of distributed applications.
Separate Cooperation
In order to enable multiple companies to trade without disclosing confidentiality, JFire manages them as so-called Organisations in separate databases. The organisations can even be hosted on different J2EE servers. To communicate, they only need to be connected to a common network (for example, the Internet) and to be acquainted with one another. This potentiates users to set up a flexible infrastructure, which is extremely scalable and seldom requires expensive clustering.
Users, Access Rights, and Workstations
A J2EE server is already able to check access rights and, if necessary, to reject method calls. In order to use this functionality, JFire provides a JDO-based login module for JBoss. Other J2EE servers will be supported in the medium-term. See Figure 1.
Fig. 1: User management with personal data, user groups and access rights
The plug-in org.nightlabs.jfire.base.admin provides the perspective ‘System Administration’, in which you can edit users or user groups and assign access rights to them. Additionally, you can manage your workstations here. In the long run, the administrator will be able to configure which plug-ins shall be installed (and automatically updated) on which workstation. This feature is based on the Eclipse update system; however, it’s not completed yet.
Central Configuration
Every Eclipse user knows the dialog ‘Window’ / ‘Preferences...’. Certainly, the JFire configuration is accessible here, too. But instead of using the usual *.prefs files, it stores (almost) all settings in JDO objects on the server. Therefore, JFire contains a framework, linking the so-called configuration modules to users or workstations. This empowers the administrator to centrally control not only access rights, but all settings of the users in the perspective ‘System Administration’. She can even configure which settings a user can modify himself.
To register your own preferences pages for the JFire configuration, create an extension to org.eclipse.ui.preferencePages. However, you need to inherit AbstractUserConfigModulePreferencePage or AbstractWorkstationConfigModulePreferencePage from the package org.nightlabs.jfire.base.config.
Client/Server Compatibility by RemoteClassLoader
The JDO data model and the EJB interfaces must be accessible in the server as well as in the client. How can we avoid the resulting maintenance and deployment overhead? The JFire client uses a RemoteClassLoader that acquires classes and resources via J2EE at runtime. You only have to publish the resources on the server by means of an XML descriptor. This ensures that client and server operate on the same classes and thus reduces not only maintenance effort but also eradicates potential bugs.
Specialised Product Types
The attributes of miscellaneous product types offer significant differences. A car, for example, is characterised by performance and mileage, whereas those properties don't apply to a plane ticket at all. To represent all possible kinds of products, the base classes ProductType and Product are abstract and must be inherited for your own purposes.
The module JFireSimpleTrade serves as inspiration for new product types; it provides simple but versatile products that are labelled with a localisable name. The corresponding sales and administration GUI is contributed by the plug-ins org.nightlabs.jfire.simpletrade and org.nightlabs.jfire.simpletrade.admin.
Sophisticated Sales GUI
Although different product types mostly have little in common, it should be possible to book them in the same order. See Figure 2. However, no GUI element is able to generically display all products. Furthermore, especially the particular attributes of the respective products should be made available to the users. Thus, it must be possible to assign to each kind of product its own GUI element, which can be presented concisely in the same view. To achieve that goal, the plug-in org.nightlabs.jfire.trade defines a set of extension points. The most important ones are:
org.nightlabs.jfire.trade.articleAdderFactory: an ArticleAdder provides GUI (red arrow), which adds products to an order. JFire denotes the resulting order line as Article.
org.nightlabs.jfire.trade.articleEditFactory: an ArticleEdit serves to create GUI elements for displaying and editing order lines. Two ArticleEdits for different product types can be seen in the screenshot (yellow arrows).
org.nightlabs.jfire.trade.articleContainerAction: this extension point allows to register actions referring to the complete order (for example, print). Since orders as well as offers and invoices can be addressed, the term ArticleContainer is used. All those actions can be found in the context menu, the coolbar and the main menu (green arrows).
org.nightlabs.jfire.trade.articleEditAction: besides actions for the ArticleContainer there have to be Actions able to manipulate single items (e.g. release or delete). They are also accesible via context menu as well as cool bar and main menu (blue arrows).
Fig. 2: Perspective for purchase and sale
Wares for Money
The selected goods have to be paid sometime. For this purpose, there is a payment framework, which can be easily extended by backend as well as frontend modules. At first, JFire knows various modes of payment (class ModeOfPayment). Every one of them can contain multiple sub-modes called ModeOfPaymentFlavour (managed by a JDO class with the same name). An example could be ‘VISA’, ‘MasterCard’ or ‘American Express’ as sub-types for the mode of payment ‘Credit Card’. To interface with an external payment service, extend the classes org.nightlabs.jfire.accounting.pay.ServerPaymentProcessor or org.nightlabs.jfire.trade.transfer.pay.ClientPaymentProcessor. A ClientPaymentProcessor must be registered, using the extension point org.nightlabs.jfire.trade.clientPaymentProcessorFactory. It can handle payments either completely on the client side (for example, via an EC terminal) or confine itself to collect information for a backend payment. Therefore, it can add an unlimited number of pages to the payment wizard.
Fig. 3: Page 1 of the payment wizard
Analogical to the payment, there exists a delivery framework. On the client side, you need to use the extension point org.nightlabs.jfire.trade.clientDeliveryProcessorFactory. This way you could, for example, send a non-material product directly via e-mail.
Reports with BIRT
If you ever created reports, statistics or printer forms, you might have already heard about the Business Intelligence and Reporting Tools, or BIRT [6]. For a very long time, JasperReports was probably the best choice open-source reporting too. Since its release in November 2004, BIRT has come to be recognized as an interesting alternative. JFire opted for BIRT mainly because of the excellent Eclipse integration. It enriches the report engine by JDO and server-side JavaScript datasources. It not only uses BIRT for the creation of documents like invoices and delivery notes, but also provides an extended report design perspective, which empowers users to create their own reports and to store them on the server. See Figure 4.
Fig. 4: Report design perspective
Dynamic Wizard
A static wizard can quickly be implemented using org.eclipse.jface.wizard.Wizard and org.eclipse.jface.wizard.WizardPage. Even if you want to skip pages under certain conditions, you only need to override the method getNextPage(). But if you want to add and remove arbitrary pages while the wizard is visible, this approach becomes messy, very quickly. To avoid this and keep it concise, JFire breaks the workflow of all dynamic wizards (for example, the payment wizard) down into hops (class WizardHop). One hop represents a locally managed workflow part that supports runtime adding or removal of pages without knowing or even touching other hops. Because WizardHops can be nested, even complex wizards remain clear. A concrete example is the mentioned payment wizard. The user can distribute one payment to several modes of payment by simply reducing the amount in one page. This adds a new payment page with the remaining amount. Additionally, a mode of payment can require other wizard pages (for the credit card number, for example). Of course, all these pages need to be displayed in the correct order—org.nightlabs.base.wizard.WizardHopPage and org.nightlabs.base.wizard.WizardHop take care of this.
Exceptions and Other Errors
In case something goes wrong, most programs can send an error report to the developers. These reports are extremely useful, especially when the malfunction rarely occurs. So it's no wonder that JFire implements an application-wide exception handling framework. The plug-in org.nightlabs.base provides the extension point org.nightlabs.base.exceptionhandler, which facilitates the registration of handlers for classes extending Throwable. There is a default handler which sends an error report over a configurable backend. Hence, interfaces to bug-tracking systems are easy to be implemented. So far, however, only an e-mail implementation exists. Unfortunately, it's not yet possible to catch all exceptions, because Eclipse has some internal error handlers that do not yet allow the interception.
A Picture is Worth a Thousand Words
In order to sell a product, you often need a graphical view. For example, when buying a car's spare part, an interactive construction plan might be very helpful. To prevent the picture from becoming blurry when zooming, and to ease linking between logical and graphical objects, it makes sense to use a vector data model. Definitely, you need an editor that can create and modify this model. JFire contains a GEF-based 2D editor with standard tools like select, rectangle, polygon, ellipse and image. You can easily addyour own tools—in the screenshot shown in Figure 5, the ‘Section Tools’ (green arrow) are extensions provided by the JFire-based Ipanema Seating Plan Editor.
Although the editor uses GEF, all objects can be drawn by Swing, too. This makes coding an applet for a web page easier.
GEF is a slightly oversized for a simple sales-view, where most of its features are not needed; instead, a high priority is set on performance. That's why JFire contains a narrow viewer with small footprint. It can register listeners that are triggered, whenever a graphical object is selected.
Fig. 5: Seating plan editor based on JFire 2D editor
JFire in Practice
Now that the basic set-up and a few details have been made clear, it will be interesting to see how JFire can be used in practice.
Besides the module JFireSimpleTrade—which is not only a sample-implementation, but also aims at covering many of the lesser complex application areas—the development at the proprietary software Ipanema 2 is in full activity. It is a JFire-based ticket distribution system that empowers theatres and cinemas, as well as concert, sport event and other organisers to sell their tickets over various channels of distribution (for example, box offices, call centers, and web shops). Ipanema 2 taps the full potential of JFire and makes it possible to create an extremely scalable distribution network, in which every business partner can (re)sell tickets for all events of all other participants.
Because JFire is Free Software, everyone is free to create sectoral solutions and either create independent distribution networks or to join an existing one. Some extension points already exist for interfacing to other systems in order to make heterogeneous trading platforms feasible.
Free Software in Development
JFire is still in the "pre-alpha" stage. But for someone intending to create another complex solution on it, now might be the perfect time to start. The community is happy to have newcomers.
Fig. 6: Developer community
Resources & References
http://www.jfire.org
http://www.jboss.com
http://java.sun.com/javaee
http://www.jpox.org
http://java.sun.com/products/jdo
http://www.eclipse.org/birt
http://xdoclet.sf.net
About the Author
Marco Schulze is CEO of NightLabs Ltd. and deals with ticket distribution and other trading systems for more than 10 years. Additionally, he's committer at JPOX and XDoclet.