Features

Core

Prior to analyzing the framework core features it might be good to have a look at it's architecture.

DIF Architecture diagram

As you can see, there are several layers on the core, each one providing services to it's clients.

The first one is the ChAL. ChAL is an acronym for Channel Abstraction Layer. As the name implies it allows the application to be decoupled from it's transmission and presentation technologies. It gets the request in a channel-dependent format and performs a conversion to a normalized form. It does the same thing with the response, translating it from DIF's internal format to the appropriate channel form. This layer also collects information about the client and request parameters and attributes.

The ChAL is one of the framework hot spots, meaning that it can be extended to make the framework support other channels.

The second layer is the Dispatcher. It contains the execution logic that runs for every request service. The Dispatcher execution cycle is comprised of several steps:

  • Validation - validates the session, the execution context and the application/service/stage registry.
  • Authentication - authenticates the user on the framework.
  • Authorization - checks if the user has permissions to run the requested stage.
  • Business logic execution - executes the stage methods that contain the business logic.
  • Conclusion - touches the session and performs other post-execution tasks.

It makes sense to have a per-channel Dispatcher implementation if you need to have different authentication, execution or results publishing for different channels. So, the steps above can be overridden programmatically or turned off.

You can roll your own implementations for these elements and DIF will pick them up and apply them on the correct situation without any further configuration steps. You can have the same stage running on the new channel implementation if your view render is able to work with the new channel.

DEM - DIF Entity Metamodel

DIF aims to adhere to the SOA convention and as such is based on an entity hierarchy which offers the following advantages:

  • Centralized management for messages and parameters.
  • Defining a SOA for Web Services.
  • Application/service licensing
  • Access management

There are four elements on the DEM hierarchy:

  • Provider
  • Application
  • Service
  • Stage

Defining these elements is as simple as annotate a java class and they can be accessed programmatically through a dedicated API. This way it is possible to have access to the information on the parent and child entities and use it on the present element.

The DEM also allows to aim for such things as automatic generation of UDDI and WSDL descriptors for Web Services or even an application map available to the user (think of if as a "site map" for applications).

Dynamic Code Generation

DIF uses a code generation mechanism to implement conventioned or configurable features. This reduces the burden on the developer and avoids direct usage of DIF's API to a great extent. It also has a long term benefit, which is protecting the application code of future framework extensions or modifications. Using this mechanism makes possible to adapt the framework to the user needs and not the other way around.

This feature is based on Java Annotations and DIF offers a lot of annotations to cover a great number of features. The philosophy behind this feature is convention over configuration over coding. That is, there are standard behaviors conventioned and several ways to change them to suit the user needs. If this doesn't suffices theres still the possibility to alter programmatically.

Keep in mind that new annotations can be added to the framework. This is done in two steps: create the annotation and supplying the code generation logic associated with it. The code to be generated in response to the new annotation is plain-text Java source that will be compiled by an internal framework compiler. This extension ability is useful since it allows to have a new feature available to a whole programming team with a simple annotation.

This dynamic code generation mechanism bestows several interesting framework features:

  • Automatic class enrichment - adding new methods, enhancing existing ones.
  • Attribute initialization and finalization - value injection prior to code execution and saving it back subsequently.
  • Building RAM models - the DEM hierarchy is mapped to RAM by reading the DEM annotations. Parameters are also mapped to RAM via annotation usage.

IoC - Inversion of Control

The cornerstone of DIF's integration layer is IoC. The framework modules are also integrated with IoC, privileging the Separation of Concerns principle and making integration with other technologies. Since the framework is built upon a modular architecture it's very easy to replace the existing implementations with different ones. This easiness is due to the IoC philosophy.

Furthermore, the addition of a new module does not require recoding or reconfiguring. The features are packaged in a JAR file with a descriptor file (named modules.properties) that states the class names that declare the binding between interfaces and implementation. The JAR is deployed on an applicational server and read by the IoC framelet. After that, all the contributions are available to be used on DIF.

To use IoC we need an IoC container implementation. DIF uses an specially developed abstraction layer that allows for easy container implementation changing. You can read more about the used IoC abstraction layer here. At the present time, the IoC container implementation used by DIF is Google Guice.

AOP - Aspect-Oriented Programming

DIF uses AspectJ for cross-cutting concerns such as logging and exception handling. The framework's logging mechanism is 100% AOP enabling logging optimization and easier maintaining. The logging mechanism supports extension for logging specialization on the framework or the applications built with it. The exception handling and reporting is also done through AspectJ. The use of AOP enables code centralizing and reporting normalization.

Model ORM

DIF includes integration with Hibernate for Model class code generation out of the box. This is done through the Maven ORM Generator plugin.

The mapping is done through reverse engineering and includes the following:

  • Data Objects - simple POJOs with an Hibernate mapping file.
  • DAOs - data accessor objects.
  • Services - entity grouping objects to ease the mapping for developers unfamiliar with the business.

The generated DAOs include beside the typical CRUD (Create, Read, Update, Delete) operations the following finder methods:

  • findByID - finds by ID with simple or composite keys.
  • findByField - exists on of these methods for each table field.
  • findByExample - receives a partially-filled object and searches for the missing data.

The generated classes can extended later, namely the DAOs, and if needed, these customizations can be persisted for future model updates. The produced mapping can be accessed through automatically generated IoC contributions. The ORM generation process might be entirely configured (even altering the code templates for any class that will be generated). Albeit this ability, care was taken to allow a fully-functionally out of the box usage.

Security

Security is broad scope issue. There are several domains requiring security. For each concern there's a framework module. See below:

  • Identity manager - manages users, groups, their relations, and their information.
  • Authentication manager - authentication management and mechanisms.
  • Authorization manager - authorization management and mechanisms for user/group service access control.

Different application types need different security concerns. Small sites typical don't need a tight security, while big enterprise applications might need LDAP or Kerberos integration. It is possible to choose what kind of security feature implementations should be included on the framework (courtesy of IoC). There's a lightweight static manager implementation well suited for small apps and developing environments. Support for native user/group DB and LDAP servers (AD, openLDAP) is also available (OID will also be supported). For persistent no integration scenarios a proprietary database persistent implementation will also be supported.

Standard development environments often require predefined user/group credentials right out of the box. DIF simplifies this task with annotations and abstracts the developer from the used repository technology. It will check which contributions are available for the identity manager and will create the users/groups without any further intervention from the developer.

Parameter management

DIF offers a powerful parameter management. A parameter in the application sense fit in the same definition as the conventional programming parameter: data that can change between calls. DIF can validate parameters automatically and also convert them to Java types. The validation can include constraints such as limits for numerical values, string formats and the like. The validation mechanisms can be easily extended or customized. It supports default values for the parameters. Parameters can be inherited from parent DEM entities.

As for persistency, parameters can be stored on an external repository so they can live between JVM shutdowns and startups. The repository can have several different implementations that can be selected through IoC. Parameter persistency is useful on critical applications where application data can't be lost between server restarts or if the user looses connection.

Parameters can have the following scopes:

  • Request - URL parameter that dies when the request is served.
  • Static - static parameters shared between all instances of the same entity.
  • Session - parameters that hold their values during the session.
  • User - holds the value between user sessions.

Messages

The framework offers a very flexible and simple way to customize messages. Messages are defined on plain-text properties files on an entity basis. These files are named after the entity class name followed by the ".messages" suffix. This option allows message inheritance between hierarchical entities in a transparent fashion for the programmer. Another side effect is the possibility of message reuse. Messages can be supplied in different languages. All it takes is appending a language extension to the messages file name. Messages can also be customized on a user basis. These customizations are stored on an external repository on a convenient format. Once again, the repository implementation can be selected by IoC.

For performance reasons the default message manager uses lazy loading to store the messages in RAM. Soon there will be made available an implementation where there will be possible to define different message loading policies.

Error reporting

Most of the frameworks (and to a certain extent even the Java language) are not user-friendly in terms of error reporting. One of DIFs goals was to make the error reporting friendly and human-readable. As such all the dumped objects have are converted to a human-readable form, the stack trace is shown only on user request, an expressive error hierarchy was devised to shield the programmer from Java's typical exceptions and an hint system is available to help the programmer correcting the error. Moreover, a rich UI error report will be available for the Web environment. This will allow a finer-grain control of the displayed information, a better rendering layout and a more concise error reporting. The user will be able to choose what he needs to see and will not be presented with a large bulk of confusing information. The execution context is also made available on error situations. This allows a better comprehension of the error since the developer can access a wide variety of internal information.

Configuration

Java web applications usually have complex configuration settings. Moreover, a large set of configuration formats are used on the same app. These might include XML, properties, plain text, proprietary file types or even DB engines with different model data. It takes a lot of time to understand the configuration options of some of these formats. To make things worse, configuration files typical scatter through a lot of folders.

DIF offers a configuration engine that abstracts the user from these details. It supports properties files, JavaBeans (read dynamically and conterved to the appropriate values) and annotated Beans that specify how to treat the configurations. The user just have to tell the engine to read or write a class. There "where" and "how" are dealt by the configuration engine. There's also an API available to alter configurations programmatically and the engine supports default values for the configuration parameters.

By default, the configuration options are stored in the Registry (for Windows environments) or on a file system structure (for Unix/Linux environments). The configurations are persisted on these repositories and written in an hierarchical and readable structure and thus are accessible for direct edition without using the framework's API. As with many other DIF modules, the user can replace the default configuration persistency technology with another that suits his/hers needs best.

Web 2.0 Component Library

Before delving into DIF's Web 2.0 support there are some architectural considerations to weave about the framework's presentation layer. There's a relevant architectural framework element that plays a crucial part on the request execution and framework extension: the Listener. Listeners, as their name implies, listen the channel for requests. As such, they're aware of channel-dependent issues and are strictly bound to the channel. They're responsibility is also to invoke the appropriate view rendering engine and that's why they're tied to the presentation layer. The Listener for the Web channel is a Java servlet.

DIF was designed with a component-driven approach on the presentation layer. This policy is biased to page elements reusage and will be natively supported by the framework. Component usage will therefore totally transparent to users. It will be much safer, efficient and easy to use than the traditional JSP include.

There will be a large component library available containing both layout and UI components. Those components will be integrated with JavaScript libraries such as Dojo Toolkit or ExtJS but besides this rich ability they will have also accessible versions. AJAX requests will also be possible. The framework will hide from the user all the communication, method invoking, partial view rendering and client page updating issues. Some components that traditionally require a lot of development effort will be available out of the box: Grid, BeanEditForm, etc.

Usability issues are also a presentation layer focus. For example, the forms have filling aids that guide the user on the data input and error correction. There will be also helper interfaces available out of the box.

Maven

Credit must be given to the technology that supports a great deal of the framework's easiness of use. That's Maven. Maven is a technical management tool for software development projects created by Jakarta to normalize it's own internal projects. Maven also offers library repositories, with a count of over 25 000 libraries on the main repository.

Maven's big advantage is integration of the project development phases. All of them are managed by Maven, namely:

  • Project structure creation based on a template
  • Framework and dependent libraries downloading and installation (includes versioning management!)
  • Project conversion for IDE compatibility (Eclipse and IntelliJ)
  • Integration and unit testing
  • Documentation and site creation
  • Project quality control through several validating and reporting tools
  • Application server starting and configuration (JBoss, Tomcat, Jetty)
  • Project package and deployment management