Package org.apache.roller.ui.core

Source Code of org.apache.roller.ui.core.RollerContext

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

package org.apache.roller.ui.core;

import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionEvent;
import javax.sql.DataSource;
import org.acegisecurity.providers.ProviderManager;
import org.acegisecurity.providers.dao.DaoAuthenticationProvider;
import org.acegisecurity.providers.encoding.Md5PasswordEncoder;
import org.acegisecurity.providers.encoding.PasswordEncoder;
import org.acegisecurity.providers.encoding.ShaPasswordEncoder;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.RollerException;
import org.apache.roller.business.runnable.RollerTask;
import org.apache.roller.business.utils.UpgradeDatabase;
import org.apache.roller.config.PingConfig;
import org.apache.roller.config.RollerConfig;
import org.apache.roller.business.Roller;
import org.apache.roller.business.RollerFactory;
import org.apache.roller.business.runnable.ThreadManager;
import org.apache.roller.ui.core.plugins.UIPluginManager;
import org.apache.roller.ui.core.plugins.UIPluginManagerImpl;
import org.apache.roller.ui.core.security.AutoProvision;
import org.apache.roller.util.cache.CacheManager;
import org.apache.velocity.runtime.RuntimeSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.WebApplicationContextUtils;


/**
* Responds to app init/destroy events and holds Roller instance.
*
* @web.listener
*/
public class RollerContext extends ContextLoaderListener implements ServletContextListener {
   
    private static Log mLogger = LogFactory.getLog(RollerContext.class);
   
    private String mVersion = null;
    private String mBuildTime = null;
    private String mBuildUser = null;
   
    public static final String ROLLER_CONTEXT = "roller.context";
   
    private static ServletContext mContext = null;
    private static Authenticator mAuthenticator = null;
    private final SynchronizedInt mSessionCount = new SynchronizedInt(0);
   
   
    /**
     * Constructor for RollerContext.
     */
    public RollerContext() {
        super();
       
        Properties props = new Properties();
        try {
            props.load(getClass().getResourceAsStream("/version.properties"));
        } catch (IOException e) {
            mLogger.error("version.properties not found", e);
        }
       
        mVersion = props.getProperty("ro.version", "UNKNOWN");
        mBuildTime = props.getProperty("ro.buildTime", "UNKNOWN");
        mBuildUser = props.getProperty("ro.buildUser", "UNKNOWN");
    }
   
   
    /* Returns Roller instance for specified app */
    public static RollerContext getRollerContext() {
        // get roller from servlet context
        ServletContext sc = RollerContext.getServletContext();
        return (RollerContext) sc.getAttribute(ROLLER_CONTEXT);
    }
   
   
    /** Responds to app-destroy by saving the indexManager's information */
    public void contextDestroyed(ServletContextEvent sce) {
        RollerFactory.getRoller().shutdown();
       
        // do we need a more generic mechanism for presentation layer shutdown?
        CacheManager.shutdown();
    }
   
   
    /**
     * Responds to context initialization event by processing context
     * paramters for easy access by the rest of the application.
     */
    public void contextInitialized(ServletContextEvent sce) {
       
        try {
            Class.forName("org.hibernate.Session");
        } catch (Throwable t) {
            // if Hibernate is not available, we're hosed
            throw new RuntimeException(
               "FATAL ERROR: Hibernate not found, please refer to the Roller Installation Guide for instructions on how to install the required Hibernate jars");
        }
       
        mLogger.debug("RollerContext initializing");
       
        // Save context in self and self in context
        mContext = sce.getServletContext();
        mContext.setAttribute(ROLLER_CONTEXT, this);
       
        // get the *real* path to <context>/resources
        String ctxPath = mContext.getRealPath("/");
        if(!ctxPath.endsWith(File.separator))
            ctxPath += File.separator + "resources";
        else
            ctxPath += "resources";
       
        // try setting the uploads path to <context>/resources
        // NOTE: this should go away at some point
        // we leave it here for now to allow users to keep writing
        // uploads into their webapp context, but this is a bad idea
        //
        // also, the RollerConfig.setUploadsDir() method is smart
        // enough to disregard this call unless the uploads.path
        // is set to ${webapp.context}
        RollerConfig.setUploadsDir(ctxPath);
       
        // try setting the themes path to <context>/themes
        // NOTE: this should go away at some point
        // we leave it here for now to allow users to keep using
        // themes in their webapp context, but this is a bad idea
        //
        // also, the RollerConfig.setThemesDir() method is smart
        // enough to disregard this call unless the themes.dir
        // is set to ${webapp.context}
        RollerConfig.setThemesDir(mContext.getRealPath("/")+File.separator+"themes");
       
        try {
            // always upgrade database first
            upgradeDatabaseIfNeeded();
           
            Roller roller = RollerFactory.getRoller();
           
            setupRollerProperties();
           
            // call Spring's context ContextLoaderListener to initialize
            // all the context files specified in web.xml. This is necessary
            // because listeners don't initialize in the order specified in
            // 2.3 containers
            super.contextInitialized(sce);
           
            initializeSecurityFeatures(mContext);
           
            setupVelocity();
            roller.getThemeManager();
            setupIndexManager(roller);
            initializePingFeatures(roller);
            setupTasks();
           
            roller.flush();
            roller.release();
           
        } catch (Throwable t) {
            mLogger.fatal("RollerContext initialization failed", t);
        }
       
        mLogger.debug("RollerContext initialization complete");
    }
   
   
    private void setupVelocity() throws RollerException {
       
        mLogger.info("Initializing Velocity");
       
        // initialize the Velocity engine
        Properties velocityProps = new Properties();
       
        try {
            InputStream instream = mContext.getResourceAsStream("/WEB-INF/velocity.properties");
           
            velocityProps.load(instream);
           
            // need to dynamically add old macro libraries if they are enabled
            if(RollerConfig.getBooleanProperty("rendering.legacyModels.enabled")) {
                String macroLibraries = (String) velocityProps.get("velocimacro.library");
                String oldLibraries = RollerConfig.getProperty("velocity.oldMacroLibraries");
               
                // set the new value
                velocityProps.setProperty("velocimacro.library", oldLibraries+","+macroLibraries);
            }
           
            mLogger.debug("Velocity props = "+velocityProps);
           
            // init velocity
            RuntimeSingleton.init(velocityProps);
           
        } catch (Exception e) {
            throw new RollerException(e);
        }
       
    }
   
   
    private void setupRollerProperties() throws RollerException {
        // init property manager by creating it
        Roller mRoller = RollerFactory.getRoller();
        mRoller.getPropertiesManager();
    }
   
   
    private void setupTasks() throws RollerException {
       
        ThreadManager tmgr = RollerFactory.getRoller().getThreadManager();
       
        Date now = new Date();
       
        // okay, first we look for what tasks have been enabled
        String tasksStr = RollerConfig.getProperty("tasks.enabled");
        String[] tasks = StringUtils.stripAll(StringUtils.split(tasksStr, ","));
        for (int i=0; i < tasks.length; i++) {
           
            String taskClassName = RollerConfig.getProperty("tasks."+tasks[i]+".class");
            if(taskClassName != null) {
                mLogger.info("Initializing task: "+tasks[i]);
               
                try {
                    Class taskClass = Class.forName(taskClassName);
                    RollerTask task = (RollerTask) taskClass.newInstance();
                    task.init();
                   
                    Date startTime = task.getStartTime(now);
                    if(startTime == null || now.after(startTime)) {
                        startTime = now;
                    }
                   
                    // schedule it
                    tmgr.scheduleFixedRateTimerTask(task, startTime, task.getInterval());
                   
                } catch (ClassCastException ex) {
                    mLogger.warn("Task does not extend RollerTask class", ex);
                } catch (RollerException ex) {
                    mLogger.error("Error scheduling task", ex);
                } catch (Exception ex) {
                    mLogger.error("Error instantiating task", ex);
                }
            }
        }
    }
   
   
    // Initialize ping features
    private void initializePingFeatures(Roller roller) throws RollerException {
       
        // Initialize common targets from the configuration
        PingConfig.initializeCommonTargets();
        // Initialize ping variants
        PingConfig.initializePingVariants();
        // Remove custom ping targets if they have been disallowed
        if (PingConfig.getDisallowCustomTargets()) {
            mLogger.info("Custom ping targets have been disallowed.  Removing any existing custom targets.");
            roller.getPingTargetManager().removeAllCustomPingTargets();
        }
        // Remove all autoping configurations if ping usage has been disabled.
        if (PingConfig.getDisablePingUsage()) {
            mLogger.info("Ping usage has been disabled.  Removing any existing auto ping configurations.");
            roller.getAutopingManager().removeAllAutoPings();
        }
    }
   
   
    protected void initializeSecurityFeatures(ServletContext context) {
       
        ApplicationContext ctx =
                WebApplicationContextUtils.getRequiredWebApplicationContext(context);
       
        String rememberMe = RollerConfig.getProperty("rememberme.enabled");
        boolean rememberMeEnabled = Boolean.valueOf(rememberMe).booleanValue();
       
        mLogger.info("Remember Me enabled: " + rememberMeEnabled);
       
        context.setAttribute("rememberMeEnabled", rememberMe);
       
        if (rememberMeEnabled) {
            ProviderManager provider = (ProviderManager) ctx.getBean("authenticationManager");
            provider.getProviders().add(ctx.getBean("rememberMeAuthenticationProvider"));
        }
       
        String encryptPasswords = RollerConfig.getProperty("passwds.encryption.enabled");
        boolean doEncrypt = Boolean.valueOf(encryptPasswords).booleanValue();
       
        if (doEncrypt) {
            DaoAuthenticationProvider provider =
                    (DaoAuthenticationProvider) ctx.getBean("daoAuthenticationProvider");
            String algorithm = RollerConfig.getProperty("passwds.encryption.algorithm");
            PasswordEncoder encoder = null;
            if (algorithm.equalsIgnoreCase("SHA")) {
                encoder = new ShaPasswordEncoder();
            } else if (algorithm.equalsIgnoreCase("MD5")) {
                encoder = new Md5PasswordEncoder();
            } else {
                mLogger.error("Encryption algorithm '" + algorithm +
                        "' not supported, disabling encryption.");
            }
            if (encoder != null) {
                provider.setPasswordEncoder(encoder);
                mLogger.info("Password Encryption Algorithm set to '" + algorithm + "'");
            }
        }
       
        if (RollerConfig.getBooleanProperty("securelogin.enabled")) {
            AuthenticationProcessingFilterEntryPoint entryPoint =
                    (AuthenticationProcessingFilterEntryPoint)ctx.getBean("authenticationProcessingFilterEntryPoint");
            entryPoint.setForceHttps(true);
        }
        /*
        if (RollerConfig.getBooleanProperty("schemeenforcement.enabled")) {
           
            ChannelProcessingFilter procfilter =
                    (ChannelProcessingFilter)ctx.getBean("channelProcessingFilter");
            ConfigAttributeDefinition secureDef = new ConfigAttributeDefinition();
            secureDef.addConfigAttribute(new SecurityConfig("REQUIRES_SECURE_CHANNEL"));
            ConfigAttributeDefinition insecureDef = new ConfigAttributeDefinition();
            insecureDef.addConfigAttribute(new SecurityConfig("REQUIRES_INSECURE_CHANNEL"));
            PathBasedFilterInvocationDefinitionMap defmap =
                    (PathBasedFilterInvocationDefinitionMap)procfilter.getFilterInvocationDefinitionSource();
           
            // add HTTPS URL path patterns to Acegi config
            String httpsUrlsProp = RollerConfig.getProperty("schemeenforcement.https.urls");
            if (httpsUrlsProp != null) {
                String[] httpsUrls = StringUtils.stripAll(StringUtils.split(httpsUrlsProp, ",") );
                for (int i=0; i<httpsUrls.length; i++) {
                    defmap.addSecureUrl(httpsUrls[i], secureDef);
                }
            }
            // all other action URLs are non-HTTPS
            defmap.addSecureUrl("/**<!-- need to remove this when uncommenting -->/*.do*", insecureDef);
        }
        */
    }
   
   
    protected void upgradeDatabaseIfNeeded() throws RollerException {
       
        try {
            InitialContext ic = new InitialContext();
            DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/rollerdb");
            Connection con = ds.getConnection();
            UpgradeDatabase.upgradeDatabase(con, mVersion);
            con.close();
        } catch (NamingException e) {
            mLogger.warn("Unable to access DataSource", e);
        } catch (SQLException e) {
            mLogger.warn(e);
        }
    }
   
   
    private void setupIndexManager(Roller roller) throws RollerException {
        roller.getIndexManager();
    }
   
   
    public void sessionCreated(HttpSessionEvent se) {
        mSessionCount.increment();
       
        mLogger.debug("sessions="+ mSessionCount
                    + ":freemem=" + Runtime.getRuntime().freeMemory()
                    + ":totmem=" + Runtime.getRuntime().totalMemory());
    }
   
   
    public void sessionDestroyed(HttpSessionEvent se) {
        mSessionCount.decrement();
       
        mLogger.debug("sessions=" + mSessionCount
                    + ":freemem=" + Runtime.getRuntime().freeMemory()
                    + ":totalmem=" + Runtime.getRuntime().totalMemory());
    }
   
   
    /**
     * Get authenticator
     */
    public Authenticator getAuthenticator() {
        if (mAuthenticator == null) {
            try {
                Class authClass =
                        Class.forName(RollerConfig.getProperty("authenticator.classname"));
                mAuthenticator = (Authenticator) authClass.newInstance();
            } catch (Exception e) {
                // this isn't an ERROR if no authenticatorClass was specified
                if (!(e instanceof NullPointerException)) {
                    mLogger.error("ERROR creating authenticator, using default", e);
                } else {
                    mLogger.debug("No authenticator specified, using DefaultAuthenticator");
                }
                mAuthenticator = new DefaultAuthenticator();
            }
        }
        return mAuthenticator;
    }
   
   
    /**
     * Get the ServletContext.
     *
     * @return ServletContext
     */
    public static ServletContext getServletContext() {
        return mContext;
    }
   
   
    /** Roller version */
    public String getRollerVersion() {
        return mVersion;
    }
   
   
    /** Roller build time */
    public String getRollerBuildTime() {
        return mBuildTime;
    }
   
   
    /** Get username that built Roller */
    public String getRollerBuildUser() {
        return mBuildUser;
    }
   
    /**
     * Get an instance of AutoProvision, if available in roller.properties
     *
     * @return AutoProvision
     */
    public static AutoProvision getAutoProvision() {
     
      String clazzName = RollerConfig.getProperty("users.sso.autoProvision.className");
     
      if(null == clazzName) {
        return null;
      }
     
      Class clazz;
      try {
        clazz = Class.forName(clazzName);
      } catch (ClassNotFoundException e) {
        mLogger.warn("Unable to found specified Auto Provision class.", e);
        return null;
      }
     
      if(null == clazz) {
        return null;
      }
     
      Class[] interfaces = clazz.getInterfaces();
      for (int i = 0; i < interfaces.length; i++) {
          if (interfaces[i].equals(AutoProvision.class))
          {
            try {
              return (AutoProvision) clazz.newInstance();
            } catch (InstantiationException e) {
              mLogger.warn("InstantiationException while creating: " + clazzName, e);
            } catch (IllegalAccessException e) {
              mLogger.warn("IllegalAccessException while creating: " + clazzName, e);
            }
          }
      }
     
      return null;
     
    }

   
    /**
     * Access to the plugin manager for the UI layer.
     *
     * TODO: we may want something similar to the Roller interface for the
     *  ui layer if we dont' want methods like this here in RollerContext.
     */
    public static UIPluginManager getUIPluginManager() {
        // TODO: we may want to do this another way
        return UIPluginManagerImpl.getInstance();
    }

}
TOP

Related Classes of org.apache.roller.ui.core.RollerContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.