001    package com.khubla.pragmatach.framework.listener;
002    
003    import java.lang.reflect.Method;
004    import java.lang.reflect.Modifier;
005    import java.util.Set;
006    
007    import javax.servlet.ServletContext;
008    import javax.servlet.ServletContextEvent;
009    import javax.servlet.ServletContextListener;
010    import javax.servlet.ServletException;
011    
012    import org.slf4j.Logger;
013    import org.slf4j.LoggerFactory;
014    
015    import com.khubla.pragmatach.framework.annotation.OnShutdown;
016    import com.khubla.pragmatach.framework.annotation.OnStartup;
017    import com.khubla.pragmatach.framework.api.Configuration;
018    import com.khubla.pragmatach.framework.api.PragmatachException;
019    import com.khubla.pragmatach.framework.application.Application;
020    import com.khubla.pragmatach.framework.controller.ControllerClasses;
021    import com.khubla.pragmatach.framework.i8n.I8NProviders;
022    import com.khubla.pragmatach.framework.plugin.PluginDescriptor;
023    import com.khubla.pragmatach.framework.plugin.PluginDescriptors;
024    import com.khubla.pragmatach.framework.router.PragmatachRoute;
025    import com.khubla.pragmatach.framework.router.PragmatachRoutes;
026    import com.khubla.pragmatach.framework.scanner.AnnotationScanner;
027    
028    /**
029     * @author tome
030     */
031    public class StartupListener implements ServletContextListener {
032       /**
033        * logger
034        */
035       private final Logger logger = LoggerFactory.getLogger(this.getClass());
036       /**
037        * configuration
038        */
039       private static final String CONFIGURATION = "configuration";
040    
041       @Override
042       public void contextDestroyed(ServletContextEvent servletContextEvent) {
043          try {
044             invokeShutdownMethods();
045          } catch (final Exception e) {
046             logger.error("Exception in contextDestroyed", e);
047          }
048       }
049    
050       @Override
051       public void contextInitialized(ServletContextEvent servletContextEvent) {
052          try {
053             /*
054              * get the configuration
055              */
056             loadConfiguration(servletContextEvent.getServletContext());
057             /*
058              * scan the annotations (@Route and @Controller, and everything else)
059              */
060             AnnotationScanner.scan(servletContextEvent.getServletContext());
061             /*
062              * find the controllers and routes
063              */
064             ControllerClasses.buildDB();
065             /*
066              * scan the plugins
067              */
068             PluginDescriptors.scan(servletContextEvent.getServletContext());
069             /*
070              * start all the plugins
071              */
072             for (final PluginDescriptor pluginDescriptor : PluginDescriptors.getPlugins().values()) {
073                pluginDescriptor.getPlugin().startup();
074             }
075             /*
076              * this loads and validates the routes
077              */
078             PragmatachRoutes.getInstance();
079             /*
080              * report the routes
081              */
082             reportRoutes();
083             /*
084              * load the i8N providers
085              */
086             I8NProviders.getInstance();
087             /*
088              * startup methods
089              */
090             invokeStartupMethods();
091          } catch (final Exception e) {
092             logger.error("Exception in contextInitialized", e);
093          }
094       }
095    
096       private void invokeShutdownMethods() throws PragmatachException {
097          try {
098             final Set<Class<?>> classes = AnnotationScanner.getAllClasses(OnShutdown.class);
099             for (final Class<?> clazz : classes) {
100                for (final Method method : clazz.getDeclaredMethods()) {
101                   if (Modifier.isStatic(method.getModifiers())) {
102                      if (null != method.getAnnotation(OnShutdown.class)) {
103                         method.invoke(null, (Object[]) null);
104                      }
105                   }
106                }
107             }
108          } catch (final Exception e) {
109             throw new PragmatachException(e);
110          }
111       }
112    
113       private void invokeStartupMethods() throws PragmatachException {
114          try {
115             final Set<Class<?>> classes = AnnotationScanner.getAllClasses(OnStartup.class);
116             for (final Class<?> clazz : classes) {
117                for (final Method method : clazz.getDeclaredMethods()) {
118                   if (Modifier.isStatic(method.getModifiers())) {
119                      if (null != method.getAnnotation(OnStartup.class)) {
120                         method.invoke(null, (Object[]) null);
121                      }
122                   }
123                }
124             }
125          } catch (final Exception e) {
126             throw new PragmatachException(e);
127          }
128       }
129    
130       /**
131        * load the application configuration
132        */
133       private void loadConfiguration(ServletContext servletContext) throws Exception {
134          try {
135             /*
136              * get the name
137              */
138             final String configurationClassName = servletContext.getInitParameter(CONFIGURATION);
139             if (null != configurationClassName) {
140                /*
141                 * get the class
142                 */
143                logger.info("Pragmatach configuration loaded from class '" + configurationClassName + "'");
144                final Class<?> configurationClazz = Class.forName(configurationClassName);
145                /*
146                 * get the configuration
147                 */
148                Application.setConfiguration((Configuration) configurationClazz.newInstance());
149             } else {
150                throw new ServletException("Configuration parameter '" + CONFIGURATION + "' not found");
151             }
152          } catch (final Exception e) {
153             throw new Exception("Exception in loadConfiguration", e);
154          }
155       }
156    
157       private void reportRoutes() {
158          try {
159             /*
160              * get routes
161              */
162             final PragmatachRoutes pragmatachRoutes = PragmatachRoutes.getInstance();
163             /*
164              * GET routes
165              */
166             logger.info("Ordered GET routes");
167             for (final PragmatachRoute pragmatachRoute : pragmatachRoutes.getGETRoutes()) {
168                logger.info("GET " + pragmatachRoute.getDescription());
169             }
170             /*
171              * POST routes
172              */
173             logger.info("Ordered POST routes");
174             for (final PragmatachRoute pragmatachRoute : pragmatachRoutes.getPOSTRoutes()) {
175                logger.info("POST " + pragmatachRoute.getDescription());
176             }
177          } catch (final Exception e) {
178             logger.error("Exceptioin in reportRoutes", e);
179             e.printStackTrace();
180          }
181       }
182    }