Imagine Business Objects looking like ordinary Java Objects. They have setters and getters and your code calls those to do obvious things.
Now imagine these objects are self-aware of their validation requirements. They know they need a valid email address in that field, they know an amount cannot be less than 100 and so on. The calling code doesn't know about any of this, but it gets a runtime exception when the data is not valid.
Let's go a little further: You have an Order object with several Item objects attached. Each of those has an amount, the price of the item, and those need to be summed to a total in the Order. The Order knows this. When the calling code adds items or changes the amounts in the items it recalculates the total. It also does it if items are deleted, and it applies the freight and various discounts as well. Your calling code knows nothing of this. It just sees the amount changing.
The obvious way to do this is to code the business rules into the objects. We don't do that. In fact we don't directly code our business objects. We generate them with JAXB and we like to use the HyperJAB3 plugin to add persistence annotations, making them JPA compatible. And we also get JAXB to add the Madura hooks too.
We leave the rest up to Madura which uses the generated hooks to implement the business rules, and we interpret the term 'business rules' quite broadly. Here are some more examples of things we use them for. We do all these from the XSD file:
The business objects, generated from the XSD, look like anemic objects, and they are in the sense that they don't contain the business rules, just a few hooks and annotations. The validation engine (part of Madura Objects) uses those to enforce the rules. So we call this a delegating anemic model. The important point is that the business rules are below the application code which is unaware of them. Clearly you can have multiple applications, perhaps using different technologies, using these objects, each of which has no knowledge or interest in implementing the rules.
But there is more in the diagram: the RulesPlugin. This is Madura Rules. So far almost everything has involved just one field at a time. You can specify a field length etc for each field. But what if the business rules involves multiple fields?
Madura Rules is an optional plugin to Madura Objects. It handles more complex rules than what you can say in XSD syntax. The rules are specified in a RUL file and look a lot like Java code, deliberately so that Java programmers can write them easily. Here are some examples of what they can do:
Expression in the rules can be arbitrarily complex so the rules can get much more complicated than these. They implement various predefines functions to turn fields to required if they weren't already (or back to not-required) etc. There are also list processing functions to sum and count items in lists of objects (like the list of order items) attached to an object. You can add your of functions if you want to.
'Truth' is always maintained by the rules engine, so if you set a value which causes the rules to derive another value, and then change the original value back, then the derived value will be unwound automatically.
Using Madura Objects we mentioned using enums to generate a list of valid values for a dropdown field. Madura rules implements decision tables. These can be loaded with all valid combinations for several multi-choice fields. For example say you are specifying a pizza with a base, a topping and a size (small, medium, large). In a real pizza shop you would likely be able to order any combination of those. But what if some technical reason (or marketing reason) meant that the shop did not want to sell large seafood topping pizzas. Maybe they went through the topping too fast, or maybe they found the gluten-free base really tasted nasty with the seafood topping.
Wouldn't it be nice if when the customer picked seafood topping in their online ordering system the gluten-free base disappeared from the choices on the base field and the only choice on the size was small? Or if they pick one of the other fields first and it is not compatible with seafood that choice goes away. That way every pizza that gets through the order process is a valid pizza. The shop doesn't have to call back and explain that seafood and gluten-free taste bad etc. Madura Rules' decision tables handles this situation easily. It can load decision tables from various sources including XML documents, database queries or something you build yourself.
Using the power of the rules alone you can implement directed questioning. Say you have a formula: bmi = weight / (height * height) and you want to find the value for the bmi. The formula is implemented as a rule and all the fields are on the same object (to keep it simple). You can launch a directed questioning operation which is effectively asking for the bmi value. The rules engine knows that it needs to find a value for weight. Now it may already have a value, this might not be the first thing this user did and it may have been entered or pulled from a database. But it if does not have a value it will be prompted for. Same with height. But it is more interesting than that. The formula needs those values in metric and people don't always know their metric measures. So we might have other rules that deliver height converted from feet and inches, and weight converted from pounds. When the user is asked for metric height he can say 'don't know' and the rules will try and find the height by conversion, which will result in another prompt, actually two: one for feet and one for inches. Eventually it will have enough data to figure the bmi.
Notice what happened here:
The advantages of all this should be obvious but let's spell them out:
In addition we support configuring the application with Spring
The Madura suite consists of the following modules:
- Madura Objects allows you to build self-validating Java objects with dynamic metadata. This is the reason for the other projects so this is the flagship. It supports metadata, such as labels and has strong support for I18n. Madura Objects also allows you to plug in a rules engine, such as Madura Rules, to handle cross-field validation and dynamic metadata changes.
- Madura Rules is a plugin module for Madura Objects that extends it to perform cross field validation and dynamic adjustment of metadata using a simple rule-based approach.
- Madura Vaadin is for when you want to use Madura Objects with Vaadin. Vaadin is the slickest UI for web applications we have come across and, because it maps nicely to Java POJOs, it is a natural fit for Madura. The result of the mix, especially when combined with Madura Rules is a very sophisticated web application which is easy to maintain.
- Madura Workflow is a workflow system which allows processes to be hot-deployed, complete with dynamic forms, rules and web service messages. It works closely with Madura Objects and Madura Rules to deliver very clean, uncluttered processes. In includes a Vaadin based UI.
- Madura Perspectives uses Vaadin and Madura Bundles to deliver a frame application that accepts sub applications as dynamic plugins. The sub applications inherit the Vaadin theme selected by the framework as well as the permissions. Sub applications can be added, updates and removed without restarting the frame application. Sub applications can optionally be loosely coupled using a publish-and-subscribe pattern. This one is on-line and you should use the demo script in this document(PDF) to find your way around it.
- Address Book uses Vaadin and Madura Objects to deliver a JPA based address book application with popup editors etc.
- Rules Demo uses Vaadin and Madura Objects and Madura Rules to deliver a dynamic UI including the ability to configure a pizza. This one is on-line and you should use the demo script in the README to find your way around it.
- Mobile Demo provides a mobile interface to the Pizza Order application (Android only). You can build the app yourself or download it from here. See the README for demo details.
- Madura DateTime is an extensible way to configure holiday dates, including complex ones like Easter and a simple API to determine if a date is a holiday
- Madura Docs is useful if you produce documentation in bulk and need a simple, cheap (free!) way to manage it. It is more suitable for developers than for people who insist on a WISIWG interface. Its advantage is that it uses tools you already know well (if you are developer) like Git and XML. We use this for all our release notes and user guides. We store the source of those documents in the project itself and the build generates PDFs and publishes them as maven artifacts along with the jar files etc.
- MaduraBundles allows you to run several versions of components of your application at the same time. You can use OSGi instead of this, but there are some differences that make MaduraBundles simpler. For example it falls back to the main class loader by default if it can't find a class. It also has a nice self-registering mechanism for bundles. You can just copy a jar file into the right directory and it will become part of the (still running) application.
- weblogic-jndi-startup Unlike Tomcat, JBoss and Glassfish there is no way to define a custom JNDI object (eg a URL) in Weblogic. This provides a very simple way to do it. We use it to define a lookup to a Madura Bundle directory and/or an application configuration file that lives outside the war file.
- SchemaTranslatorMavenPlugin a maven plugin that generates a DDL file from JPA annotated classes.
- MaduraRulesMavenPlugin a maven plugin that 'compiles' Madura Rules. In practice this means it generates Java code from the rules definition.
- Madura Eclipse Plugin an Eclipse plugin to assist you with development of your workflow and rules definitions.
Every project has a PDF posted to Maven central along with Javadocs, binaries etc. So for more detailed information you should go there next. The Git repositories hold all the source, and they all build with Maven.
All of the modules are available as open source. All except Madura Rules carry an Apache 2.0 license which means you can use them anywhere you like without charge. Madura Rules carries an APGL license which means you can use it in any non commercial application without charge, but not in commercial applications. A commercially licensed copy of Madura Rules is available for a negotiable fee.
If you want to use the other Madura products commercially without Madura Rules there is no fee. You are also free to write your own rules (or other) plugin for Madura Objects.
All of these projects are written in Java. We use Eclipse as our development environment so they are all Eclipse projects as well as maven projects. The binaries, source and detailed docs are all uploaded to the Maven Central repository.