• Home
  • New Entries
  • Popular Entries
  • Submit a Story
  • About

Making the Most of Java 5.0: Enum Example ...

"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.

View More Info

"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

 View Full Story.
Posted at 10:07:52 am | Permalink | Posted in Java  

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


About Ajaxlines

Ajaxlines is a project focused on providing its audience with a database of most of Ajax related articles, resources, tutorials and services from around the world.

Its purpose is to showcase the power of Ajax and to act as a portal to the Ajax development community.


Recent Stuff

Using ASP.NET AJAX JSON Asynchronous Web Services

Growl for Windows and a Web Notification API

Learn AJAX from Scratch - Part II

Learn AJAX from Scratch - Part I

PHP AJAX CHAT, Bug fixes - including weird mozilla bug

Learn PHP From Scratch


Our Partners

Ajax Projects

Web 2.0 Sites

Webloglines

Human Development Handbook

Software Development Company

Ajaxlines


Search


Topics

  • .Net (96)
  • Articles (76)
  • Bookmarking (35)
  • Calendar (18)
  • Chat (38)
  • ColdFusion (3)
  • CSS (30)
  • Email (23)
  • Flash (13)
  • Games (6)
  • Google (17)
  • Html (6)
  • Image (11)
  • International Calls & VOIP (7)
  • Java (34)
  • Javascript (146)
  • JSON (16)
  • Perl (2)
  • PHP (82)
  • Presentation (19)
  • Python (3)
  • Resources (1)
  • RSS (1)
  • Ruby (7)
  • Storage (4)
  • Toolkits (87)
  • Tutorials (190)
  • UI (11)
  • Utilities (161)
  • Web2.0 (13)
  • XmlHttpRequest (18)
  • YUI (4)

© 2006 www.ajaxlines.com. All Rights Reserved. Powered by IRange