001    package com.khubla.pragmatach.plugin.cluster;
002    
003    import java.util.HashMap;
004    import java.util.Map;
005    import java.util.Set;
006    
007    import javassist.util.proxy.ProxyFactory;
008    import javassist.util.proxy.ProxyObject;
009    
010    import org.slf4j.Logger;
011    import org.slf4j.LoggerFactory;
012    
013    import com.khubla.pragmatach.framework.annotation.Controller;
014    import com.khubla.pragmatach.framework.api.PragmatachException;
015    import com.khubla.pragmatach.framework.controller.PragmatachController;
016    import com.khubla.pragmatach.framework.scanner.AnnotationScanner;
017    import com.khubla.pragmatach.plugin.cluster.annotation.Clustered;
018    import com.khubla.pragmatach.plugin.cluster.multicast.JGroupsSenderReceiver;
019    
020    /**
021     * A collection of the clustered controller instances
022     * 
023     * @author tome
024     */
025    public class ClusteredControllers {
026       /**
027        * logger
028        */
029       private final Logger logger = LoggerFactory.getLogger(this.getClass());
030       /**
031        * instance
032        */
033       private static ClusteredControllers instance;
034    
035       /**
036        * singleton
037        */
038       public static ClusteredControllers getInstance() throws PragmatachException {
039          if (null == instance) {
040             instance = new ClusteredControllers();
041          }
042          return instance;
043       }
044    
045       /**
046        * cluster object
047        */
048       private final JGroupsSenderReceiver jGroupsSenderReceiver;
049       /**
050        * controllers
051        */
052       private final Map<String, PragmatachController> controllerInstances = new HashMap<String, PragmatachController>();
053       /**
054        * clustered beans
055        */
056       private final Set<Class<?>> clusteredControllerClasses;
057    
058       /**
059        * ctor
060        */
061       private ClusteredControllers() throws PragmatachException {
062          /*
063           * create the controllerCluster
064           */
065          jGroupsSenderReceiver = new JGroupsSenderReceiver();
066          try {
067             jGroupsSenderReceiver.startup();
068          } catch (final Exception e) {
069             logger.error("Exception starting ClusteredControllers", e);
070          }
071          clusteredControllerClasses = findClusteredControllerClasses();
072          instantiateControllers();
073       }
074    
075       /**
076        * find all the beans annotated with @Clustered
077        */
078       private Set<Class<?>> findClusteredControllerClasses() throws PragmatachException {
079          try {
080             return AnnotationScanner.getAllClasses(Clustered.class);
081          } catch (final Exception e) {
082             throw new PragmatachException("Exception in findClusteredControllerClasses", e);
083          }
084       }
085    
086       public Set<Class<?>> getClusteredControllerClasses() {
087          return clusteredControllerClasses;
088       }
089    
090       private String getClusteredControllerName(Class<?> clazz) throws PragmatachException {
091          try {
092             final Controller controller = clazz.getAnnotation(Controller.class);
093             if (null != controller) {
094                return controller.name();
095             } else {
096                throw new Exception("ClusteredController '" + clazz.getName() + "' does not have a @Controller annotation");
097             }
098          } catch (final Exception e) {
099             throw new PragmatachException("Exception in getClusteredControllerName", e);
100          }
101       }
102    
103       public Map<String, PragmatachController> getControllerInstances() {
104          return controllerInstances;
105       }
106    
107       /**
108        * create the instances and return proxies to them
109        */
110       private void instantiateControllers() throws PragmatachException {
111          try {
112             for (final Class<?> controllerClazz : clusteredControllerClasses) {
113                final ProxyFactory proxyFactory = new ProxyFactory();
114                proxyFactory.setSuperclass(controllerClazz);
115                final Class<?> c = proxyFactory.createClass();
116                final PragmatachController pragmatachController = (PragmatachController) c.newInstance();
117                ((ProxyObject) pragmatachController).setHandler(new ControllerMethodHandler());
118                final String name = getClusteredControllerName(controllerClazz);
119                controllerInstances.put(name, pragmatachController);
120             }
121          } catch (final Exception e) {
122             throw new PragmatachException("Exception in instantiateControllers", e);
123          }
124       }
125    }