"Hello World!" examples are great for general introductions to a concept, but often tend to lack much depth. So, as a follow-up to the original article on enums in Java 5.0, this article goes into a little more depth with a real-world example.
The Container Enum
Figure 1 below illustrates the enumeration of possible application servers to which an application can deploy. Why is this useful? Many organizations have more than one Java application server in different environments, and an EAR or WAR may need to be redeployed to different servers; or, you may be developing a common framework that will be used in different environments. It is often helpful in these situations to abstract many of the (static) variances between containers so that redeployment to a different environment can be done with a minimum of effort.
Figure 1: The Container enum.
public enum Container {
WEBSPHERE, WEBLOGIC, JBOSS, NONE;
}
Now, let is say the application being designed requires an application-controlled JTA TransactionManager (if, for example, the standard way of doing XA transactions cannot be used). But how one is acquired varies pretty widely, depending on which environment the code is running. The variances here can be handled with an abstract method added to the enum, as in Figure 2.
Figure 2: The Container enum with factory methods.
public enum Container
{
WEBSPHERE() {
private String[] factoryNames =
{"com.ibm.ws.Transaction.TransactionManagerFactory",
"com.ibm.ejs.jts.jta.TransactionManagerFactory",
"com.ibm.ejs.jts.jta.JTSXA"};
@Override
public TransactionManager getTransactionManager()
throws Exception {
for (int i = 0; i < factoryNames.length; i++) {
Method getTxMgr = null;
try {
//attempt to get class and method
Class<?> txMgrFactory = Class.forName(factoryNames[i]);
getTxMgr = txMgrFactory
.getMethod("getTransactionManager", null);
} catch (Exception e) {
continue;
}
//attempt to invoke method (let exception throw...)
return (TransactionManager) getTxMgr.invoke(null, null);
}
//if all else fails
return null; //or throw exception
}
},
WEBLOGIC() {
@Override
public TransactionManager getTransactionManager()
throws Exception {
InitialContext ctx = null;
try {
ctx = new InitialContext();
return (TransactionManager) ctx
.lookup("java:comp/UserTransaction");
} finally {
if(ctx!=null) {
try { ctx.close(); } catch (NamingException e) {}
}
}
}
},
JBOSS() {
@Override
public TransactionManager getTransactionManager()
throws Exception {
InitialContext ctx = null;
try {
ctx = new InitialContext();
return (TransactionManager) ctx
.lookup("java:/TransactionManager");
} finally {
if(ctx!=null) {
try { ctx.close(); } catch (NamingException e) {}
}
}
}
},
// Standalone environ or server w/o TM
NONE() {
@Override
public TransactionManager getTransactionManager()
throws Exception {
//Use reflection to avoid necessary dependency
Class<?> clazz = Class.forName("org.objectweb.jotm.Jotm");
Constructor<?> constr = clazz.getConstructor(boolean.class,
boolean.class);
Object jotm = constr.newInstance(true, false);
Method getTxMgr = clazz.getMethod("getTransactionManager",
(Class[])null);
return TransactionManager.class.cast(getTxMgr
.invoke(jotm, (Object[])null));
}
};
// abstract method
public abstract TransactionManager getTransactionManager()
throws Exception;
}
Here we are defining an abstract method getTransactionManager() as a factory method for getting or creating a JTA TransactionManager in a manner similar to the Spring Framework is JtaTransactionManager. Each enumeration instance must implement this method. In most cases, a JEE-compliant server will have a JNDI lookup that can be used. For WebSphere, there is no API for gettng a TransactionManager directly, but instead a time-honored backdoor for creating one. In the case of NONE (either a stand-alone environment or a server that has no TransactionManager), JOTM is used. Of course, the enum would be a lot shorter if the calls were delegated to factory classes, but that is an implementation detail.
Since the JMX default domain for most major Java application servers is self-describing, something like the following snippet of code can be used to "auto-sniff" the container environment:
public Container lookupContainer() {
String defaultDomain = ManagementFactory
.getPlatformMBeanServer()
.getDefaultDomain();
try {
return Container.valueOf(defaultDomain.toUpperCase());
} catch (Exception e) { /*...assume none....*/ }
return Container.NONE; // or null if no default behavior
}
After all of that, the client code to use it is a simple line:
lookupContainer().getTransactionManager():
Conclusion
The Container enum is a good illustration of the power of enumerations in Java compared to their C/C++ counterparts. By associating behavior with each enum instance, a smooth way of dispatching getTransactionManager() to the appropriate implementation has been created. This points out another fact: each enum instance (WEBSPHERE, WEBLOGIC, etc.) is implicitly a subclass of the enum class Container itself. This comes in handy since it means that many other object-oriented design patterns (Abstract Factory, Command, Visitor, and Strategy, to name a few) can be implemented using enums. Those, of course, are left as an exercise to the reader.
source: ajaxonomy
Related Stuff
-
MooV: Using cutting edge Video phones and Software Video Phones - coupling all that with VoIP and empowering the disabled.
-
Moo Telecom: VoIP communications made easy - Ring anyway with the fun and ease of using a normal phone
-
TagR:Mobile Social Network with Real Time Locations Based services, and Ambience Intelligence, VoiP, IM, Skype, Googletalk, Mapping, Flickr, Events, Calendaring, Scheduling, SecondLife Support
-
ClearSMS : ClearSMS is a Web-based application that lets you send bulk SMS messages to your customers, contacts, or just about anyone.
-
Jajah:jah is a VoIP (Voice over IP) provider, founded by Austrians Roman Scharf and Daniel Mattes in 2005[1]. The Jajah headquarters are located in Mountain View, CA, USA, and Luxembourg. Jajah maintains a development centre in Israel.
-
Skype: It’s free to download and free to call other people on Skype. Skype the number one voice over ip software
- PrivatePhone: a free local phone number with voicemail and messages you can check online or from any phone.
Be the first ... |Add your comment.
Your Comment ...
Name (required)
Email (required, hidden)
Website
