The Dasein Utilities for Java
The Dasein Utilities are general-purpose tools for doing a bunch of unrelated, common programming tasks in Java. It includes components that:
- Better encapsulate java.util.Calendar functionality, especially so that it is accessible via JSTL EL.
- Handle smart-caching of singleton objects that can be accessed by multiple indexes while retaining a small memory footprint.
- Provide generic sorting routines that allow you to sort Java objects on any attribute, including subattributes.
- Store multiple translations for a given expression in memory concurrently and find the translation that best matches a user's language preferences.
- Serve as a tag library for managing Java 5 enumerations using JSTL.
- Serve as a tag library for manipulating dates in JSTL.
- Support type-safe, arbitrary attribute association for objects. Very useful for complex meta-data.
The Java Calendar API may be the worst written set of components in the Java specification. The generic get() and set() methods violate Java Bean standards and make a Calendar object inaccessible to JSTL-compliant JSP pages without dropping into Java code.
The Dasein calendar tools provide a wrapper around the core Java Calendar object and enable you to manipulate dates in a JSP page through a simple tag library. These classes include:
- CalendarWrapper
- CalendarTag
- IncrementTag
When building a server-side, database-driven application, you need to carefully balance calls to the database with memory usage. If you keep everything in memory, you minimize expensive database queries at the expense of RAM. If you go to the database for every object lookup, you sacrifice performance.
A caching library can help you minimize trips to the database without eating up all your memory. The Dasein caching tools will cache objects in memory and index them using weak references. When they are no longer in use by the rest of your application, they become eligible for garbage collection. In the mean time, you can retrieve them using your most common lookups without touching the database.
The result: a lightning fast application with a minimal memory footprint.
Features of this caching library include:
- A single copy of any particular object sits in memory at any given point in time. All clients share this object and thus minimize memory overhead.
- All objects are readily available for garbage collection if the server is done using them. You do not need to track object state.
- You can tell the cache how often to force a re-sync with the database, so that heavy-use objects (objects that never get garbage-collected) are forced to re-sync with the database.
- You can leverage multiple in-memory indexes so that lookups on unique indexes are lightning fast.
The Dasein sorting object can be passed in as a {@link java.util.Comparator} that will do complex, locale-specific sorting on any Java object. Would you like to sort your Employee objects based first on their last name then first name? Just use the following code:
GenericSortersorter = new GenericSorter ("lastName,firstName"); TreeSet employees = new TreeSet (sorter); employees.add(getEmployee(1)); employees.add(getEmployee(2));
The sort criteria can be attributes of attributes. For example, you can sort employees by state by passing in the string "address.state.abbreviation" (assuming, of course, Employee has a getAddress() method returning an Address object which in turn has a getState() method...).
The objects you wish to sort do not need to implement any pre-set interface or extend any base class. You can also specify a locale for locale-specific sorting. If you use the Dasein Translator objects, the sorter will sort any Translator values based on the string representing the user-specific translation.
For example, if you would like to sort a list of web pages by their title:
GenericSortersorter = new GenericSorter ("title", mylocale); TreeSet pages = new TreeSet (sorter); pages.addAll(getAllPages());
Assuming title is a {@link org.dasein.util.Translator}, the list will sort acccording to the English title for English speakers and according to the Spanish title for Spanish speakers.
Translation ManagementProperties files work for managing simple translations for labels and other UI-level components, but are terrible for managing more complex multi-lingual content. The Dasein Translator stores multiple translations for a concept in memory and then provides the best translation to map to a given locale. Combined with the Dasein Persistence Library, you can store multi-lingual content in a database and associate it with your core entities.
Enum ManagementJava 5 enumerations are very useful, but they are not terribly JSTL-friendly. Dasein provides convenient tag libriaries to allow you to iterate over enums and translate between strings and enum classes.
Type-safe AttributesType-safe attributes enable you to associate dynamic meta-data with a given class. In many environments, for example, you need to tag a class with attributes after the class is written. For example, you may allow each department in your organization to specify different employee attributes that have meaning only to that department.
You could, of course, have a generic {@link java.util.Map} in the Employee class to map these custom attributes to the employee. Unfortunately, this map has the following drawbacks:
- Even with Java generics support, it is not typesafe since you cannot know at compile time what the proper data type should be.
- You cannot restrict it so that only members of department X have attributes Y and Z.
The Dasein type-safe attributes let you do just that.
Other Dasein Projects: Dasein Cloud API