databasepsmlmanagerservice.java

来自「jetspeed源代码」· Java 代码 · 共 1,277 行 · 第 1/3 页

JAVA
1,277
字号
/*
 * Copyright 2000-2001,2004 The Apache Software Foundation.
 * 
 * Licensed 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.
 */

package org.apache.jetspeed.services.psmlmanager.db;

import java.sql.Connection;

// PSML Manager Service interface
import org.apache.jetspeed.services.psmlmanager.PsmlManagerService;


// Jetspeed Security service
import org.apache.jetspeed.services.JetspeedSecurity;

// Profile and ProfileLocator interface
import org.apache.jetspeed.om.profile.Profile;
import org.apache.jetspeed.om.profile.ProfileLocator;
import org.apache.jetspeed.om.profile.QueryLocator;
import org.apache.jetspeed.services.Profiler;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;

//Castor defined API
import org.apache.jetspeed.om.profile.Portlets;
import org.apache.jetspeed.om.profile.PSMLDocument;
import org.apache.jetspeed.om.profile.BasePSMLDocument;

//turbine stuff
import org.apache.turbine.services.TurbineBaseService;
import org.apache.turbine.services.InitializationException;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.resources.ResourceService;
import org.apache.turbine.services.servlet.TurbineServlet;
import org.apache.turbine.services.servlet.ServletService;

// torque
import org.apache.torque.Torque;

// jetspeed security
import org.apache.jetspeed.om.security.JetspeedUser;
import org.apache.jetspeed.om.security.JetspeedUserFactory;
import org.apache.jetspeed.om.security.Role;
import org.apache.jetspeed.om.security.JetspeedRoleFactory;
import org.apache.jetspeed.om.security.Group;
import org.apache.jetspeed.om.security.JetspeedGroupFactory;
import org.apache.jetspeed.services.security.JetspeedSecurityException;

//Servlet API
import javax.servlet.ServletConfig;

// Torque generated classes
import org.apache.jetspeed.om.dbpsml.JetspeedUserProfile;
import org.apache.jetspeed.om.dbpsml.JetspeedUserProfilePeer;
import org.apache.jetspeed.om.dbpsml.JetspeedRoleProfile;
import org.apache.jetspeed.om.dbpsml.JetspeedRoleProfilePeer;
import org.apache.jetspeed.om.dbpsml.JetspeedGroupProfile;
import org.apache.jetspeed.om.dbpsml.JetspeedGroupProfilePeer;

//standard java stuff
import java.lang.Thread;
import java.util.List;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.io.FileReader;
import java.io.File;

import org.exolab.castor.mapping.Mapping;
import org.xml.sax.InputSource;


/**
 * This service is responsible for loading and saving PSML documents. It uses
 * database to persist the PSML documents.
 *
 * @author <a href="mailto:adambalk@cisco.com">Atul Dambalkar</a>
 * @author <a href="mailto:mvaidya@cisco.com">Medha Vaidya</a>
 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
 * @version $Id: DatabasePsmlManagerService.java,v 1.35 2004/02/23 03:32:19 jford Exp $
 */
public class DatabasePsmlManagerService extends TurbineBaseService
                                     implements DatabasePsmlManager
{
    /**
     * Static initialization of the logger for this class
     */    
    private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(DatabasePsmlManagerService.class.getName());
    
    private Map psmlCache = new HashMap();

    /** The watcher for the document locations */
    private CacheRefresher refresher = null;

    /** the base refresh rate for documents */
    private long refreshRate;  // default will be 8 hours

    private final static String REFRESH_RATE = "refresh-rate";
    private final static long DEFAULT_REFRESH_RATE = 60 * 60 * 8 * 1000; //8hrs

    /** whether caching is allowed */
    private boolean cachingOn;  // default will be false

    private final static String CACHING_ON = "caching-on";
    private final static boolean DEFAULT_CACHING_ON = false;

    private final static String POOL_NAME = "database";

    /** the import/export consumer service **/
    private PsmlManagerService consumer = null;

    // castor mapping
    public static final String DEFAULT_MAPPING = "${webappRoot}/WEB-INF/conf/psml-mapping.xml";
    String mapFile = null;
    /** the Castor mapping file name */
    private Mapping mapping = null;

    /** The pool name to use for database requests. */
    private String poolName = null;

    /**
     * This is the early initialization method called by the
     * Turbine <code>Service</code> framework
     */
    public void init(ServletConfig conf) throws InitializationException
    {
        if (getInit())
        {
            return;
        }

        logger.info("Initializing DatabasePsmlManagerService...");
        initConfiguration(conf);

        logger.info("Done initializing DatabasePsmlManagerService.");

    }

    /**
     * Loads the configuration parameters for this service from the
     * JetspeedResources.properties file.
     *
     * @exception throws a <code>InitializationException</code> if the service
     * fails to initialize
     */
    private void initConfiguration(ServletConfig conf)
                            throws InitializationException
    {

        //Ensure that the servlet service is initialized
        TurbineServices.getInstance().initService(ServletService.SERVICE_NAME, conf);

        ResourceService serviceConf =
                      ((TurbineServices)TurbineServices.getInstance())
                              .getResources(PsmlManagerService.SERVICE_NAME);
        try
        {
            // get configuration parameters from Turbine Resources
            // we'll use only string accessors so the values can be multiply
            // specified in the properties files (the first one wins).
            String value = serviceConf.getString(REFRESH_RATE);
            refreshRate = DEFAULT_REFRESH_RATE;
            try
            {
                refreshRate = Long.parseLong(value);
            }
            catch (Exception e)
            {
                logger.warn("DatabasePsmlManagerService: error in refresh-rate configuration: using default");
            }

            // get the name of the torque database pool to use
            poolName = serviceConf.getString(POOL_NAME);

            //find out if caching allowed
            value = serviceConf.getString(CACHING_ON);
            cachingOn = DEFAULT_CACHING_ON;
            try
            {
                cachingOn = value.equals("true");
            }
            catch (Exception e)
            {
                logger.warn("DatabasePsmlManagerService: error in caching-on configuration: using default");
            }

            // psml castor mapping file
            mapFile = serviceConf.getString("mapping",DEFAULT_MAPPING);
            mapFile = TurbineServlet.getRealPath( mapFile );
            loadMapping();
        }
        catch (Throwable t)
        {
            logger.error(this + ".init:" , t);
            throw new InitializationException("Exception initializing DatabasePsmlManagerService" + t);
        }

        if (cachingOn)
        {
            this.refresher = new CacheRefresher();
            refresher.start();
        }
    }

    /** Late init method from Turbine Service model */
    public void init() throws InitializationException
    {
        //Mark that we are done
        setInit(true);
/*
        try
        {
            PsmlImporter importer = new PsmlImporter();
            importer.run(null);
        }
        catch (Exception e)
        {
            logger.warn("DatabasePsmlManagerService.init: exception while importing:" , e);
        }
  */
    }

    protected void loadMapping()
        throws InitializationException
    {
        // test the mapping file and create the mapping object

        if (mapFile != null)
        {
            File map = new File(mapFile);
            if (logger.isDebugEnabled())
                logger.debug("Loading psml mapping file " + mapFile);
            if (map.exists() && map.isFile() && map.canRead())
            {
                try
                {
                    mapping = new Mapping();
                    InputSource is = new InputSource( new FileReader(map) );
                    is.setSystemId( mapFile );
                    mapping.loadMapping( is );
                }
                catch (Exception e)
                {
                    logger.error("Error in psml mapping creation",e);
                    throw new InitializationException("Error in mapping",e);
                }
            }
            else
            {
                throw new InitializationException("PSML Mapping not found or not a file or unreadable: "+mapFile);
            }
        }
    }

    /**
     * This is the shutdown method called by the
     * Turbine <code>Service</code> framework
     */
    public void shutdown()
    {
        if (this.refresher != null)
        {
            this.refresher.setDone(true);
        }
    }


    /**
     * A thread implementation of cache refreshing mechanism for database
     * persisted PSMLs. We have to refresh the cache after specific intervals
     * if someone manually updates the PSML database.
     *
     * @author <a href="mailto:adambalk@cisco.com">Atul Dambalkar</a>
     */
    class CacheRefresher extends Thread
    {
        private boolean done = false;

        /**
         * Constructor to to set the priority.
         */
        CacheRefresher()
        {
            setDaemon(true);
            setPriority(Thread.MIN_PRIORITY+1);
        }

        /**
         * We are all done, system is shutting down.
         */
        void setDone(boolean done)
        {
            this.done = done;
        }

        /**
         * Method as needed for a Thread to run
         */
        public void run()
        {
            try
            {
                while (!done)
                {
                    if (logger.isDebugEnabled())
                        logger.debug("Cache Refresher thread sleeping now!");
                    sleep (refreshRate);
                    if (logger.isDebugEnabled())
                        logger.debug("Cache Refresher thread working now!");

                    try
                    {
                        synchronized (this)
                       {
                            Iterator i = psmlCache.keySet().iterator();

                            while(i.hasNext())
                            {
                                String locator = (String)i.next();

                                // do refresh for the locator
                                PSMLDocument doc =
                                            refresh(stringToLocator(locator));

                                // over write the existing document in cache
                                psmlCache.put(locator, doc);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        logger.warn("DatabasePsmlManagerService.CacheRefresher: Error in cache refresher...", e);
                    }
                }
            }
            catch (InterruptedException e)
            {
                if (logger.isDebugEnabled())
                    logger.debug("DatabasePsmlManagerService.CacheRefresher: recieved interruption, aborting.");
            }
        }
    }

    /**
     * Return a unique string identifying this object.
     */
    private String locatorToString(ProfileLocator locator)
    {
        StringBuffer keybuf = new StringBuffer();

        JetspeedUser user = locator.getUser();
        Role role = locator.getRole();
        Group group = locator.getGroup();
        String name = locator.getName();
        String mediaType = locator.getMediaType();
        String country = locator.getCountry();
        String language = locator.getLanguage();

       synchronized (this)
       {
            if (user != null)
            {
                keybuf.append("User:").append(user.getUserName());
           }
            else if (group != null)
            {
                keybuf.append("Group:").append(group.getName());
            }
            else if (role != null)
            {
                keybuf.append("Role:").append(role.getName());
            }

            if (name != null)
            {
                keybuf.append('$').append("Page:").append(name);
            }

            if (mediaType != null)
            {
                keybuf.append('$').append("MediaType:").append(mediaType);
            }
            if (country != null && (! country.equals("-1")))
            {
                keybuf.append('$').append("Country:").append(country);
            }
            if (language != null && (! language.equals("-1")))
            {
                keybuf.append('$').append("Language:").append(language);
            }
        }
        if (logger.isDebugEnabled())
            logger.debug("DatabasePsmlManagerService: Returning locator string: " + keybuf.toString());

        return keybuf.toString();
    }

    private ProfileLocator stringToLocator(String locstr) throws Exception
    {
        ProfileLocator locator = Profiler.createLocator();
        String entity = null;

        if (logger.isDebugEnabled())
            logger.debug("DatabasePsmlManagerService: Creating locator for string: " + locstr);

        StringTokenizer dollarTokens = new StringTokenizer(locstr, "$");
        while (dollarTokens.hasMoreTokens())
        {
            String dollarToken = dollarTokens.nextToken().trim();

            StringTokenizer colonTokens = new StringTokenizer(dollarToken, ":");
            String colonToken = colonTokens.nextToken();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?