castorpsmlmanagerservice.java

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

JAVA
1,570
字号
/*
 * 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;

//Jetspeed stuff
import org.apache.jetspeed.om.profile.ProfileLocator;
import org.apache.jetspeed.om.profile.QueryLocator;
import org.apache.jetspeed.util.FileCopy;
import org.apache.jetspeed.util.DirectoryUtils;
import org.apache.jetspeed.services.Profiler;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.JetspeedSecurity;
import org.apache.jetspeed.services.resources.JetspeedResources;

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

//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.servlet.TurbineServlet;
import org.apache.turbine.services.resources.ResourceService;
import org.apache.turbine.services.servlet.ServletService;

import org.apache.jetspeed.om.security.JetspeedUser;
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.om.security.JetspeedUserFactory;

//castor support
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.Unmarshaller;
import org.exolab.castor.xml.Marshaller;
import org.exolab.castor.xml.ValidationException;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.mapping.MappingException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

// serialization support
import org.apache.xml.serialize.Serializer;
import org.apache.xml.serialize.XMLSerializer;
import org.apache.xml.serialize.OutputFormat;

//standard java stuff
import java.io.File;
import java.io.Reader;
import java.io.FileReader;
import java.io.Writer;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.LinkedList;
import javax.servlet.ServletConfig;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.jetspeed.cache.FileCache;
import org.apache.jetspeed.cache.FileCacheEventListener;
import org.apache.jetspeed.cache.FileCacheEntry;


/**
 * This service is responsible for loading and saving PSML documents.
 *
 * @author <a href="mailto:raphael@apache.org">Rapha雔 Luta</a>
 * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
 * @author <a href="mailto:sgala@apache.org">Santiago Gala</a>
 * @version $Id: CastorPsmlManagerService.java,v 1.44 2004/03/31 00:23:02 jford Exp $
 */
public class CastorPsmlManagerService extends TurbineBaseService
                                      implements FileCacheEventListener,
                                                 PsmlManagerService
{
    /**
     * Static initialization of the logger for this class
     */    
    private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(CastorPsmlManagerService.class.getName());
    
    // resource path constants
    protected static final String PATH_GROUP              = "group";
    protected static final String PATH_ROLE               = "role";
    protected static final String PATH_USER               = "user";

    // configuration keys
    protected final static String CONFIG_ROOT             = "root";
    protected final static String CONFIG_EXT              = "ext";
    protected final static String CONFIG_SCAN_RATE        = "scanRate";
    protected final static String CONFIG_CACHE_SIZE       = "cacheSize";

    // default configuration values
    public final static String DEFAULT_ROOT             = "/WEB-INF/psml";
    public final static String DEFAULT_EXT              = ".psml";

    // default resource
    public final static String DEFAULT_RESOURCE         = "default.psml";

    // the root psml resource directory
    protected String root;
    // base store directory
    protected File rootDir = null;
    // file extension
    protected String ext;

    /** The documents loaded by this manager */
    protected FileCache documents = null;

    /** the output format for pretty printing when saving registries */
    protected OutputFormat format = null;

    /** the base refresh rate for documents */
    protected long scanRate = 1000 * 60; // every minute

    /** the default cache size */
    protected int cacheSize = 100;

    /** the import/export consumer service **/
    protected PsmlManagerService consumer = null;
    protected boolean importFlag = false;

    // castor mapping
    public static final String DEFAULT_MAPPING = "${webappRoot}/WEB-INF/conf/psml-mapping.xml";
    protected String mapFile = null;

    /** the Castor mapping file name */
    protected Mapping mapping = null;

    /** The default encoding used to serialize PSML files to disk */
    protected String defaultEncoding = JetspeedResources.getString(JetspeedResources.CONTENT_ENCODING_KEY, "utf-8");

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

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

        // get configuration parameters from Jetspeed Resources
        ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
                                                     .getResources(PsmlManagerService.SERVICE_NAME);
        // get the PSML Root Directory
        this.root = serviceConf.getString( CONFIG_ROOT, DEFAULT_ROOT );
        this.rootDir = new File(root);

        //If the rootDir does not exist, treat it as context relative
        if ( !rootDir.exists() )
        {
            try
            {
                this.rootDir = new File(conf.getServletContext().getRealPath(root));
            }
            catch (Exception e)
            {
                // this.rootDir = new File("./webapp" + this.rootDir.toString());
            }
        }
        //If it is still missing, try to create it
        if (!rootDir.exists())
        {
            try
            {
                rootDir.mkdirs();
            }
            catch (Exception e)
            {
            }
        }

        // get default extension
        this.ext = serviceConf.getString( CONFIG_EXT, DEFAULT_EXT );

        // create the serializer output format
        this.format = new OutputFormat();
        format.setIndenting(true);
        format.setIndent(4);
        format.setLineWidth(0);

        // psml castor mapping file
        mapFile = serviceConf.getString("mapping",DEFAULT_MAPPING);
        mapFile = TurbineServlet.getRealPath( mapFile );
        loadMapping();

        this.scanRate = serviceConf.getLong(CONFIG_SCAN_RATE, this.scanRate);
        this.cacheSize= serviceConf.getInt(CONFIG_CACHE_SIZE, this.cacheSize);

        documents = new FileCache(this.scanRate, this.cacheSize);
        documents.addListener(this);
        documents.startFileScanner();


        //Mark that we are done
        setInit(true);

        // Test
        //testCases();

    }


    /** Late init method from Turbine Service model */
    public void init() throws InitializationException
    {
        while( !getInit() )
        {
            //Not yet...
            try
            {
                Thread.sleep( 500 );
            }
            catch (InterruptedException ie )
            {
                logger.error("Exception", ie);
            }
        }
    }


    /**
     * This is the shutdown method called by the
     * Turbine <code>Service</code> framework
     */
    public void shutdown()
    {
        documents.stopFileScanner();
    }

    /**
     * Returns a PSML document of the given name.
     * For this implementation, the name must be the document
     * URL or absolute filepath
     *
     * @deprecated
     * @param name the name of the document to retrieve
     */
    public PSMLDocument getDocument( String name )
    {
        if (name == null)
        {
            String message = "PSMLManager: Must specify a name";
            logger.error( message );
            throw new IllegalArgumentException( message );
        }

        if (logger.isDebugEnabled())
        {
            logger.debug( "PSMLManager: asked for " + name );
        }

        PSMLDocument doc = null;

        doc = (PSMLDocument)documents.getDocument(name);

        if (doc == null)
        {
            doc = loadDocument(name);

            synchronized (documents)
            {
                // store the document in the hash and reference it to the watcher
                try
                {
                    documents.put(name, doc);
                }
                catch (java.io.IOException e)
                {
                    logger.error("Error putting document", e);
                }
            }
        }

        return doc;
    }

    /**
     * Returns a cached PSML document for the given locator
     * 
     * @param locator The locator descriptor of the document to be retrieved.
     * @return PSML document  from cache (or disk if not yet cached)
     */
    public PSMLDocument getDocument( ProfileLocator locator)
    {
        return getDocument(locator, true);
    }

    /**
     * Returns a PSML document for the given locator
     * 
     * @param locator   The locator descriptor of the document to be retrieved.
     * @param getCached Look in the cache (true) or umarshall a fresh copy from disk (false)
     * @return 
     */
    protected PSMLDocument getDocument( ProfileLocator locator, boolean getCached )
    {
        if (locator == null)
        {
            String message = "PSMLManager: Must specify a name";
            logger.error( message );
            throw new IllegalArgumentException( message );
        }
        File base = this.rootDir;
        String path = mapLocatorToFile(locator);
        File file = new File(base, path);
        String name = null;

        try
        {
            name = file.getCanonicalPath();
        }
        catch (IOException e)
        {
            logger.error("PSMLManager: unable to resolve file path for "+ file);
        }

        if (logger.isDebugEnabled())
        {
            logger.debug("PSMLManager: calculated resource:" + path + ". Base: " + base + " File: " + name);
        }

        PSMLDocument doc = null;
        Profile profile = null;

        if (getCached == true)
        {
            profile = (Profile)documents.getDocument(name);
        }

        if (profile == null)
        {
            doc = loadDocument(name);
            if (null == doc)
            {
                if (logger.isWarnEnabled())
                {
                    logger.warn( "PSMLManager: " + name + " not found, returning null document" );
                }
                return null;
            }

            synchronized (documents)
            {
                // store the document in the hash and reference it to the watcher
                Profile newProfile = createProfile(locator);
                newProfile.setDocument(doc);
                try
                {
                    documents.put(name, newProfile);
                }
                catch (IOException e)
                {
                    logger.error("Error putting document", e);
                }
            }
        }
        else
        {
            doc = profile.getDocument();
        }

        return doc;
    }

    /**

⌨️ 快捷键说明

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