KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > roller > ui > core > RollerContext


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. The ASF licenses this file to You
4  * under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License. For additional information regarding
15  * copyright in this work, please see the NOTICE file in the top level
16  * directory of this distribution.
17  */

18
19 package org.apache.roller.ui.core;
20
21 import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.io.InputStream JavaDoc;
25 import java.sql.Connection JavaDoc;
26 import java.sql.SQLException JavaDoc;
27 import java.util.Properties JavaDoc;
28 import java.util.TimerTask JavaDoc;
29 import javax.naming.InitialContext JavaDoc;
30 import javax.naming.NamingException JavaDoc;
31 import javax.servlet.ServletContext JavaDoc;
32 import javax.servlet.ServletContextEvent JavaDoc;
33 import javax.servlet.ServletContextListener JavaDoc;
34 import javax.servlet.http.HttpServletRequest JavaDoc;
35 import javax.servlet.http.HttpSessionEvent JavaDoc;
36 import javax.sql.DataSource JavaDoc;
37 import org.acegisecurity.providers.ProviderManager;
38 import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
39 import org.acegisecurity.providers.encoding.Md5PasswordEncoder;
40 import org.acegisecurity.providers.encoding.PasswordEncoder;
41 import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
42 import org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint;
43 import org.apache.commons.lang.StringEscapeUtils;
44 import org.apache.commons.lang.StringUtils;
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.apache.roller.RollerException;
48 import org.apache.roller.business.utils.UpgradeDatabase;
49 import org.apache.roller.config.PingConfig;
50 import org.apache.roller.config.RollerConfig;
51 import org.apache.roller.config.RollerRuntimeConfig;
52 import org.apache.roller.model.Roller;
53 import org.apache.roller.model.RollerFactory;
54 import org.apache.roller.model.ScheduledTask;
55 import org.apache.roller.pojos.WeblogEntryData;
56 import org.apache.roller.ui.core.pings.PingQueueTask;
57 import org.apache.roller.ui.core.security.AutoProvision;
58 import org.apache.roller.util.cache.CacheManager;
59 import org.apache.velocity.runtime.RuntimeSingleton;
60 import org.springframework.context.ApplicationContext;
61 import org.springframework.web.context.ContextLoaderListener;
62 import org.springframework.web.context.support.WebApplicationContextUtils;
63
64
65 /**
66  * Responds to app init/destroy events and holds Roller instance.
67  *
68  * @web.listener
69  */

70 public class RollerContext extends ContextLoaderListener implements ServletContextListener JavaDoc {
71     
72     private static Log mLogger = LogFactory.getLog(RollerContext.class);
73     
74     private String JavaDoc mVersion = null;
75     private String JavaDoc mBuildTime = null;
76     private String JavaDoc mBuildUser = null;
77     
78     public static final String JavaDoc ROLLER_CONTEXT = "roller.context";
79     
80     private static ServletContext JavaDoc mContext = null;
81     private static Authenticator mAuthenticator = null;
82     private final SynchronizedInt mSessionCount = new SynchronizedInt(0);
83     
84     
85     /**
86      * Constructor for RollerContext.
87      */

88     public RollerContext() {
89         super();
90         
91         Properties JavaDoc props = new Properties JavaDoc();
92         try {
93             props.load(getClass().getResourceAsStream("/version.properties"));
94         } catch (IOException JavaDoc e) {
95             mLogger.error("version.properties not found", e);
96         }
97         
98         mVersion = props.getProperty("ro.version", "UNKNOWN");
99         mBuildTime = props.getProperty("ro.buildTime", "UNKNOWN");
100         mBuildUser = props.getProperty("ro.buildUser", "UNKNOWN");
101     }
102     
103     
104     /* Returns Roller instance for specified app */
105     public static RollerContext getRollerContext() {
106         // get roller from servlet context
107
ServletContext JavaDoc sc = RollerContext.getServletContext();
108         return (RollerContext) sc.getAttribute(ROLLER_CONTEXT);
109     }
110     
111     
112     /** Responds to app-destroy by saving the indexManager's information */
113     public void contextDestroyed(ServletContextEvent JavaDoc sce) {
114         RollerFactory.getRoller().shutdown();
115         
116         // do we need a more generic mechanism for presentation layer shutdown?
117
CacheManager.shutdown();
118     }
119     
120     
121     /**
122      * Responds to context initialization event by processing context
123      * paramters for easy access by the rest of the application.
124      */

125     public void contextInitialized(ServletContextEvent JavaDoc sce) {
126         
127         try {
128             Class.forName("org.hibernate.Session");
129         } catch (Throwable JavaDoc t) {
130             // if Hibernate is not available, we're hosed
131
throw new RuntimeException JavaDoc(
132                "FATAL ERROR: Hibernate not found, please refer to the Roller Installation Guide for instructions on how to install the required Hibernate jars");
133         }
134         
135         mLogger.debug("RollerContext initializing");
136         
137         // Save context in self and self in context
138
mContext = sce.getServletContext();
139         mContext.setAttribute(ROLLER_CONTEXT, this);
140         
141         // get the *real* path to <context>/resources
142
String JavaDoc ctxPath = mContext.getRealPath("/");
143         if(!ctxPath.endsWith(File.separator))
144             ctxPath += File.separator + "resources";
145         else
146             ctxPath += "resources";
147         
148         // try setting the uploads path to <context>/resources
149
// NOTE: this should go away at some point
150
// we leave it here for now to allow users to keep writing
151
// uploads into their webapp context, but this is a bad idea
152
//
153
// also, the RollerConfig.setUploadsDir() method is smart
154
// enough to disregard this call unless the uploads.path
155
// is set to ${webapp.context}
156
RollerConfig.setUploadsDir(ctxPath);
157         
158         // set the roller context real path in RollerConfig
159
// NOTE: it seems that a few backend classes do actually need
160
// to know what the real path to the roller context is,
161
// so we set this property to give them the info they need.
162
//
163
// this is really not a best practice and we should try to
164
// remove these dependencies on the webapp context if possible
165
RollerConfig.setContextRealPath(mContext.getRealPath("/"));
166         
167         try {
168             // always upgrade database first
169
upgradeDatabaseIfNeeded();
170             
171             Roller roller = RollerFactory.getRoller();
172             
173             setupRollerProperties();
174             
175             // call Spring's context ContextLoaderListener to initialize
176
// all the context files specified in web.xml. This is necessary
177
// because listeners don't initialize in the order specified in
178
// 2.3 containers
179
super.contextInitialized(sce);
180             
181             initializeSecurityFeatures(mContext);
182             
183             setupVelocity();
184             roller.getThemeManager();
185             setupIndexManager(roller);
186             initializePingFeatures(roller);
187             setupPingQueueTask(roller);
188             setupScheduledTasks(mContext, roller);
189             
190             roller.flush();
191             roller.release();
192             
193         } catch (Throwable JavaDoc t) {
194             mLogger.fatal("RollerContext initialization failed", t);
195         }
196         
197         mLogger.debug("RollerContext initialization complete");
198     }
199     
200     
201     private void setupVelocity() throws RollerException {
202         
203         mLogger.info("Initializing Velocity");
204         
205         // initialize the Velocity engine
206
Properties JavaDoc velocityProps = new Properties JavaDoc();
207         
208         try {
209             InputStream JavaDoc instream = mContext.getResourceAsStream("/WEB-INF/velocity.properties");
210             
211             velocityProps.load(instream);
212             
213             // need to dynamically add old macro libraries if they are enabled
214
if(RollerConfig.getBooleanProperty("rendering.legacyModels.enabled")) {
215                 String JavaDoc macroLibraries = (String JavaDoc) velocityProps.get("velocimacro.library");
216                 String JavaDoc oldLibraries = RollerConfig.getProperty("velocity.oldMacroLibraries");
217                 
218                 // set the new value
219
velocityProps.setProperty("velocimacro.library", oldLibraries+","+macroLibraries);
220             }
221             
222             mLogger.debug("Velocity props = "+velocityProps);
223             
224             // init velocity
225
RuntimeSingleton.init(velocityProps);
226             
227         } catch (Exception JavaDoc e) {
228             throw new RollerException(e);
229         }
230         
231     }
232     
233     
234     private void setupRollerProperties() throws RollerException {
235         // init property manager by creating it
236
Roller mRoller = RollerFactory.getRoller();
237         mRoller.getPropertiesManager();
238     }
239     
240     
241     /** Setup daily and hourly tasks specified in web.xml */
242     private void setupScheduledTasks(ServletContext JavaDoc context, Roller roller)
243             throws RollerException, InstantiationException JavaDoc,
244             IllegalAccessException JavaDoc, ClassNotFoundException JavaDoc {
245         
246         // setup the hourly tasks
247
String JavaDoc hourlyString = RollerConfig.getProperty("tasks.hourly");
248         if (hourlyString != null && hourlyString.trim().length() > 0) {
249             String JavaDoc[] hourlyTasks = StringUtils.stripAll(
250                     StringUtils.split(hourlyString, ",") );
251             for (int i=0; i<hourlyTasks.length; i++) {
252                 mLogger.info("Setting hourly task: "+hourlyTasks[i]);
253                 ScheduledTask task =
254                         (ScheduledTask)Class.forName(hourlyTasks[i]).newInstance();
255                 task.init(roller, mContext.getRealPath("/"));
256                 roller.getThreadManager().scheduleHourlyTimerTask((TimerTask JavaDoc)task);
257             }
258         }
259         
260         // setup the daily tasks
261
String JavaDoc dailyString = RollerConfig.getProperty("tasks.daily");
262         if (dailyString != null && dailyString.trim().length() > 0) {
263             String JavaDoc[] dailyTasks = StringUtils.stripAll(
264                     StringUtils.split(dailyString, ",") );
265             for (int j=0; j<dailyTasks.length; j++) {
266                 mLogger.info("Setting daily task: "+dailyTasks[j]);
267                 ScheduledTask task =
268                         (ScheduledTask)Class.forName(dailyTasks[j]).newInstance();
269                 task.init(roller, mContext.getRealPath("/"));
270                 roller.getThreadManager().scheduleDailyTimerTask((TimerTask JavaDoc)task);
271             }
272         }
273     }
274     
275     
276     // Initialize ping features
277
private void initializePingFeatures(Roller roller) throws RollerException {
278         
279         // Initialize common targets from the configuration
280
PingConfig.initializeCommonTargets();
281         // Initialize ping variants
282
PingConfig.initializePingVariants();
283         // Remove custom ping targets if they have been disallowed
284
if (PingConfig.getDisallowCustomTargets()) {
285             mLogger.info("Custom ping targets have been disallowed. Removing any existing custom targets.");
286             roller.getPingTargetManager().removeAllCustomPingTargets();
287         }
288         // Remove all autoping configurations if ping usage has been disabled.
289
if (PingConfig.getDisablePingUsage()) {
290             mLogger.info("Ping usage has been disabled. Removing any existing auto ping configurations.");
291             roller.getAutopingManager().removeAllAutoPings();
292         }
293     }
294     
295     
296     // Set up the ping queue processing task
297
private void setupPingQueueTask(Roller roller) throws RollerException {
298         
299         long intervalMins = PingConfig.getQueueProcessingIntervalMins();
300         if (intervalMins == 0) {
301             // Ping queue processing interval of 0 indicates that ping queue processing is disabled on this host.
302
// This provides a crude way to disable running the ping queue task on some servers if there are
303
// multiple servers in a cluster sharing a db. Exclusion should really be handled dynamically but isn't.
304
mLogger.warn("Ping queue processing interval is zero; processing from the ping queue will be disabled on this server.");
305             mLogger.warn("Please make sure that ping queue processing is configured to run on one server in the cluster.");
306             return;
307         }
308         
309         // Set up the task
310
PingQueueTask pingQueueTask = new PingQueueTask();
311         pingQueueTask.init(intervalMins);
312         
313         // Schedule it at the appropriate interval, delay start for one interval.
314
mLogger.info("Scheduling ping queue task to run at " + intervalMins + " minute intervals.");
315         roller.getThreadManager().scheduleFixedRateTimerTask(pingQueueTask, intervalMins, intervalMins);
316     }
317     
318     
319     protected void initializeSecurityFeatures(ServletContext JavaDoc context) {
320         
321         ApplicationContext ctx =
322                 WebApplicationContextUtils.getRequiredWebApplicationContext(context);
323         
324         String JavaDoc rememberMe = RollerConfig.getProperty("rememberme.enabled");
325         boolean rememberMeEnabled = Boolean.valueOf(rememberMe).booleanValue();
326         
327         mLogger.info("Remember Me enabled: " + rememberMeEnabled);
328         
329         context.setAttribute("rememberMeEnabled", rememberMe);
330         
331         if (rememberMeEnabled) {
332             ProviderManager provider = (ProviderManager) ctx.getBean("authenticationManager");
333             provider.getProviders().add(ctx.getBean("rememberMeAuthenticationProvider"));
334         }
335         
336         String JavaDoc encryptPasswords = RollerConfig.getProperty("passwds.encryption.enabled");
337         boolean doEncrypt = Boolean.valueOf(encryptPasswords).booleanValue();
338         
339         if (doEncrypt) {
340             DaoAuthenticationProvider provider =
341                     (DaoAuthenticationProvider) ctx.getBean("daoAuthenticationProvider");
342             String JavaDoc algorithm = RollerConfig.getProperty("passwds.encryption.algorithm");
343             PasswordEncoder encoder = null;
344             if (algorithm.equalsIgnoreCase("SHA")) {
345                 encoder = new ShaPasswordEncoder();
346             } else if (algorithm.equalsIgnoreCase("MD5")) {
347                 encoder = new Md5PasswordEncoder();
348             } else {
349                 mLogger.error("Encryption algorithm '" + algorithm +
350                         "' not supported, disabling encryption.");
351             }
352             if (encoder != null) {
353                 provider.setPasswordEncoder(encoder);
354                 mLogger.info("Password Encryption Algorithm set to '" + algorithm + "'");
355             }
356         }
357         
358         if (RollerConfig.getBooleanProperty("securelogin.enabled")) {
359             AuthenticationProcessingFilterEntryPoint entryPoint =
360                     (AuthenticationProcessingFilterEntryPoint)ctx.getBean("authenticationProcessingFilterEntryPoint");
361             entryPoint.setForceHttps(true);
362         }
363         /*
364         if (RollerConfig.getBooleanProperty("schemeenforcement.enabled")) {
365             
366             ChannelProcessingFilter procfilter =
367                     (ChannelProcessingFilter)ctx.getBean("channelProcessingFilter");
368             ConfigAttributeDefinition secureDef = new ConfigAttributeDefinition();
369             secureDef.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
370             ConfigAttributeDefinition insecureDef = new ConfigAttributeDefinition();
371             insecureDef.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
372             PathBasedFilterInvocationDefinitionMap defmap =
373                     (PathBasedFilterInvocationDefinitionMap)procfilter.getFilterInvocationDefinitionSource();
374             
375             // add HTTPS URL path patterns to Acegi config
376             String httpsUrlsProp = RollerConfig.getProperty("schemeenforcement.https.urls");
377             if (httpsUrlsProp != null) {
378                 String[] httpsUrls = StringUtils.stripAll(StringUtils.split(httpsUrlsProp, ",") );
379                 for (int i=0; i<httpsUrls.length; i++) {
380                     defmap.addSecureUrl(httpsUrls[i], secureDef);
381                 }
382             }
383             // all other action URLs are non-HTTPS
384             defmap.addSecureUrl("/**<!-- need to remove this when uncommenting -->/*.do*", insecureDef);
385         }
386         */

387     }
388     
389     
390     protected void upgradeDatabaseIfNeeded() throws RollerException {
391         
392         try {
393             InitialContext JavaDoc ic = new InitialContext JavaDoc();
394             DataSource JavaDoc ds = (DataSource JavaDoc)ic.lookup("java:comp/env/jdbc/rollerdb");
395             Connection JavaDoc con = ds.getConnection();
396             UpgradeDatabase.upgradeDatabase(con, mVersion);
397             con.close();
398         } catch (NamingException JavaDoc e) {
399             mLogger.warn("Unable to access DataSource", e);
400         } catch (SQLException JavaDoc e) {
401             mLogger.warn(e);
402         }
403     }
404     
405     
406     private void setupIndexManager(Roller roller) throws RollerException {
407         roller.getIndexManager();
408     }
409     
410     
411     public void sessionCreated(HttpSessionEvent JavaDoc se) {
412         mSessionCount.increment();
413         
414         mLogger.debug("sessions="+ mSessionCount
415                     + ":freemem=" + Runtime.getRuntime().freeMemory()
416                     + ":totmem=" + Runtime.getRuntime().totalMemory());
417     }
418     
419     
420     public void sessionDestroyed(HttpSessionEvent JavaDoc se) {
421         mSessionCount.decrement();
422         
423         mLogger.debug("sessions=" + mSessionCount
424                     + ":freemem=" + Runtime.getRuntime().freeMemory()
425                     + ":totalmem=" + Runtime.getRuntime().totalMemory());
426     }
427     
428     
429     /**
430      * Get authenticator
431      */

432     public Authenticator getAuthenticator() {
433         if (mAuthenticator == null) {
434             try {
435                 Class JavaDoc authClass =
436                         Class.forName(RollerConfig.getProperty("authenticator.classname"));
437                 mAuthenticator = (Authenticator) authClass.newInstance();
438             } catch (Exception JavaDoc e) {
439                 // this isn't an ERROR if no authenticatorClass was specified
440
if (!(e instanceof NullPointerException JavaDoc)) {
441                     mLogger.error("ERROR creating authenticator, using default", e);
442                 } else {
443                     mLogger.debug("No authenticator specified, using DefaultAuthenticator");
444                 }
445                 mAuthenticator = new DefaultAuthenticator();
446             }
447         }
448         return mAuthenticator;
449     }
450     
451     
452     /**
453      * Get the ServletContext.
454      *
455      * @return ServletContext
456      */

457     public static ServletContext JavaDoc getServletContext() {
458         return mContext;
459     }
460     
461     
462     /** Roller version */
463     public String JavaDoc getRollerVersion() {
464         return mVersion;
465     }
466     
467     
468     /** Roller build time */
469     public String JavaDoc getRollerBuildTime() {
470         return mBuildTime;
471     }
472     
473     
474     /** Get username that built Roller */
475     public String JavaDoc getRollerBuildUser() {
476         return mBuildUser;
477     }
478     
479     /**
480      * Get an instance of AutoProvision, if available in roller.properties
481      *
482      * @return AutoProvision
483      */

484     public static AutoProvision getAutoProvision() {
485       
486       String JavaDoc clazzName = RollerConfig.getProperty("users.sso.autoProvision.className");
487       
488       if(null == clazzName) {
489         return null;
490       }
491       
492       Class JavaDoc clazz;
493       try {
494         clazz = Class.forName(clazzName);
495       } catch (ClassNotFoundException JavaDoc e) {
496         mLogger.warn("Unable to found specified Auto Provision class.", e);
497         return null;
498       }
499       
500       if(null == clazz) {
501         return null;
502       }
503       
504       Class JavaDoc[] interfaces = clazz.getInterfaces();
505       for (int i = 0; i < interfaces.length; i++) {
506           if (interfaces[i].equals(AutoProvision.class))
507           {
508             try {
509               return (AutoProvision) clazz.newInstance();
510             } catch (InstantiationException JavaDoc e) {
511               mLogger.warn("InstantiationException while creating: " + clazzName, e);
512             } catch (IllegalAccessException JavaDoc e) {
513               mLogger.warn("IllegalAccessException while creating: " + clazzName, e);
514             }
515           }
516       }
517       
518       return null;
519       
520     }
521
522 }
523
Popular Tags