001    package org.shiftone.jrat.core.config;
002    
003    import org.shiftone.jrat.core.MethodKey;
004    import org.shiftone.jrat.core.criteria.MethodCriteria;
005    import org.shiftone.jrat.core.spi.MethodHandler;
006    import org.shiftone.jrat.core.spi.MethodHandlerFactory;
007    import org.shiftone.jrat.core.spi.RuntimeContext;
008    import org.shiftone.jrat.provider.silent.SilentMethodHandler;
009    import org.shiftone.jrat.util.Assert;
010    import org.shiftone.jrat.util.log.Logger;
011    
012    import java.util.ArrayList;
013    import java.util.Collection;
014    import java.util.Iterator;
015    import java.util.List;
016    
017    /**
018     * @author jeff@shiftone.org (Jeff Drost)
019     */
020    public class ConfigMethodHandlerFactory implements MethodHandlerFactory {
021    
022        private static final Logger LOG = Logger.getLogger(ConfigMethodHandlerFactory.class);
023        private final List profileFactories = new ArrayList();
024    
025        public ConfigMethodHandlerFactory(Configuration configuration) {
026    
027            List profiles = configuration.getProfiles();
028    
029            for (int p = 0; p < profiles.size(); p++) {
030    
031                Profile profile = (Profile) profiles.get(p);
032    
033                String profileName = profile.getName() != null
034                        ? "'" + profile.getName() + "'"
035                        : String.valueOf(p);
036    
037                LOG.info("Loading profile " + profileName + "...");
038    
039                List factories = profile.getFactories();
040    
041                for (int f = 0; f < factories.size(); f++) {
042    
043                    Handler handler = (Handler) factories.get(f);
044                    String factoryName = profileName + ", factory " + f + " (" + handler.getClassName() + ")";
045                    LOG.info("Loading factory " + handler + "...");
046    
047                    try {
048    
049                        profileFactories.add(new FactoryInstance(handler.buildMethodHandlerFactory(), profile));
050    
051                    } catch (Exception e) {
052    
053                        LOG.error("There was an error loading factory " + factoryName, e);
054                        LOG.info("Execution will proceed, however this factory will not receieve events.");
055    
056                    }
057    
058                }
059            }
060        }
061    
062    
063        public MethodHandler createMethodHandler(MethodKey methodKey) throws Exception {
064    
065            List methodHandlers = new ArrayList();
066            Iterator iterator = profileFactories.iterator();
067    
068            while (iterator.hasNext()) {
069    
070                FactoryInstance factoryInstance = (FactoryInstance) iterator.next();
071    
072                // todo - get modifiers
073                factoryInstance.addHandlerIfApplicable(methodHandlers, methodKey);
074    
075            }
076    
077            if (methodHandlers.isEmpty()) {
078                return SilentMethodHandler.METHOD_HANDLER;
079            } else if (methodHandlers.size() == 1) {
080                return (MethodHandler) methodHandlers.get(0);
081            } else {
082                return new CompositeMethodHandler(methodHandlers);
083            }
084    
085        }
086    
087        public void startup(RuntimeContext context) throws Exception {
088    
089            LOG.info("startup");
090    
091            Iterator iterator = profileFactories.iterator();
092    
093            while (iterator.hasNext()) {
094    
095                FactoryInstance factoryInstance = (FactoryInstance) iterator.next();
096                factoryInstance.methodHandlerFactory.startup(context);
097    
098            }
099    
100        }
101    
102        private class FactoryInstance {
103    
104            private final MethodHandlerFactory methodHandlerFactory;
105            private final MethodCriteria methodCriteria;
106    
107    
108            public FactoryInstance(MethodHandlerFactory methodHandlerFactory, MethodCriteria methodCriteria) {
109                Assert.assertNotNull(methodHandlerFactory);
110                Assert.assertNotNull(methodCriteria);
111                this.methodHandlerFactory = methodHandlerFactory;
112                this.methodCriteria = methodCriteria;
113            }
114    
115            public void addHandlerIfApplicable(Collection methodHandlers, MethodKey methodKey) throws Exception {
116    
117                if (methodCriteria.isMatch(methodKey.getClassName(), methodKey.getMethodName(), methodKey.getSignature(), 0)) {
118                    methodHandlers.add(methodHandlerFactory.createMethodHandler(methodKey));
119                }
120            }
121        }
122    
123    }