Package org.apache.jetspeed.factory

Source Code of org.apache.jetspeed.factory.JetspeedPortletFactory

/*
* 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.factory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.portlet.Portlet;
import javax.portlet.PortletConfig;
import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.PreferencesValidator;
import javax.portlet.UnavailableException;
import javax.servlet.ServletContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jetspeed.container.JetspeedPortletConfig;
import org.apache.jetspeed.container.PortalAccessor;
import org.apache.jetspeed.om.common.portlet.PortletApplication;
import org.apache.jetspeed.om.common.portlet.PortletDefinitionComposite;
import org.apache.pluto.om.portlet.PortletDefinition;

/**
* <p>
* JetspeedPortletFactory
* </p>
* <p>
*
* </p>
* @author <a href="mailto:weaver@apache.org">Scott T. Weaver</a>
* @version $Id: JetspeedPortletFactory.java 509904 2007-02-21 05:55:40Z taylor $
*
*/
public class JetspeedPortletFactory implements PortletFactory
{

    private Map portletCache;
    private Map validatorCache;
   
    private static final Log log = LogFactory.getLog(JetspeedPortletFactory.class);
    private final Map classLoaderMap;

    /**
     *
     */
    public JetspeedPortletFactory()
    {
        this.portletCache =  Collections.synchronizedMap(new HashMap());
        this.validatorCache = Collections.synchronizedMap(new HashMap());
        classLoaderMap = Collections.synchronizedMap(new HashMap());
    }

    public void registerPortletApplication(PortletApplication pa, ClassLoader cl)
        {
            synchronized (classLoaderMap)
            {
                unregisterPortletApplication(pa);
                classLoaderMap.put(pa.getId(), cl);
            }
    }
   
    public void unregisterPortletApplication(PortletApplication pa)
    {
        synchronized (classLoaderMap)
        {
            synchronized (portletCache)
            {
                ClassLoader cl = (ClassLoader) classLoaderMap.remove(pa.getId());
                if (cl != null)
                {
                    ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();

                    Iterator portletDefinitions = pa.getPortletDefinitions().iterator();
                    while (portletDefinitions.hasNext())
                    {
                        PortletDefinition pd = (PortletDefinition) portletDefinitions.next();
                        String pdId = pd.getId().toString();
                        Portlet portlet = (Portlet) portletCache.remove(pdId);
                        if (portlet != null)
                        {
                            try
                            {
                                Thread.currentThread().setContextClassLoader(cl);
                                portlet.destroy();
                            }
                            finally
                            {
                                Thread.currentThread().setContextClassLoader(currentContextClassLoader);
                            }
                        }
                        validatorCache.remove(pdId);
                    }
                }
            }
        }
    }
   
    public PreferencesValidator getPreferencesValidator(PortletDefinition pd)
    {
        PreferencesValidator validator = null;
        try
        {
            String pdId = pd.getId().toString();
           
            synchronized (validatorCache)
            {
                validator = (PreferencesValidator)validatorCache.get(pdId);
                if ( validator == null )
                {
                    String className = ((PortletDefinitionComposite)pd).getPreferenceValidatorClassname();
                    if ( className != null )
                    {
                        PortletApplication pa = (PortletApplication)pd.getPortletApplicationDefinition();
                        ClassLoader paCl = (ClassLoader)classLoaderMap.get(pa.getId());
                        if ( paCl == null )
                        {
                            throw new UnavailableException("Portlet Application "+pa.getName()+" not available");
                        }
                       
                        ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
                        try
                        {
                            Class clazz = paCl.loadClass(className);
                            try
                            {
                                Thread.currentThread().setContextClassLoader(paCl);
                                validator = (PreferencesValidator)clazz.newInstance();
                                validatorCache.put(pdId, validator);
                            }
                            finally
                            {
                                Thread.currentThread().setContextClassLoader(currentContextClassLoader);
                            }
                        }
                        catch (Exception e)
                        {
                            String msg = "Cannot create PreferencesValidator instance "+className+" for Portlet "+pd.getName();
                            log.error(msg,e);
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            log.error(e);
        }
        return validator;
    }

    /**
     * Gets a portlet by either creating it or returning a handle to it from the portlet 'cache'
     *
     * @param portletDefinition The definition of the portlet
     * @return PortletInstance
     * @throws PortletException
     */
    public PortletInstance getPortletInstance( ServletContext servletContext, PortletDefinition pd ) throws PortletException
    {
        PortletInstance portlet = null;
        String pdId = pd.getId().toString();
        PortletApplication pa = (PortletApplication)pd.getPortletApplicationDefinition();

        try
        {                       
          synchronized (portletCache)
          {
            portlet = (PortletInstance)portletCache.get(pdId);
            if (null != portlet)
            {
                return portlet;
            }
           
            ClassLoader paCl = (ClassLoader)classLoaderMap.get(pa.getId());
            if ( paCl == null )
            {
                throw new UnavailableException("Portlet Application "+pa.getName()+" not available");
            }
           
            ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader();
            try
            {
              Class clazz = paCl.loadClass(pd.getClassName());
              try
            {
                Thread.currentThread().setContextClassLoader(paCl);
                // wrap new Portlet inside PortletInstance which ensures the destroy
                // method will wait for all its invocation threads to complete
                // and thereby releasing all its ClassLoader locks as needed for local portlets.
                portlet = new JetspeedPortletInstance(pd.getName(), (Portlet)clazz.newInstance());
            }
              finally
            {
                Thread.currentThread().setContextClassLoader(currentContextClassLoader);
              }
            }
            catch (Exception e)
            {
                String msg = "Cannot create Portlet instance "+pd.getClassName()+" for Portlet Application "+pa.getName();
                log.error(msg,e);
                throw new UnavailableException(msg);
            }
     
            PortletContext portletContext = PortalAccessor.createPortletContext(servletContext, pa);           
            PortletConfig portletConfig = PortalAccessor.createPortletConfig(portletContext, pd);
           
            try
            {
              try
              {
                Thread.currentThread().setContextClassLoader(paCl);
            portlet.init(portletConfig);           
              }
              finally
              {
                Thread.currentThread().setContextClassLoader(currentContextClassLoader);
              }
            }
            catch (PortletException e1)
            {
                log.error("Failed to initialize Portlet "+pd.getClassName()+" for Portlet Application "+pa.getName(), e1);
                throw e1;
            }           
            portletCache.put(pdId, portlet);
          }
        }
        catch (PortletException pe)
        {
            throw pe;
        }
        catch (Throwable e)
        {
            log.error("PortletFactory: Failed to load portlet "+pd.getClassName(), e);
            throw new UnavailableException( "Failed to load portlet " + pd.getClassName() +": "+e.toString());
        }
        return portlet;
    }
   
    public void updatePortletConfig(PortletDefinition pd)
    {
        if (pd != null)
        {
            //System.out.println("$$$$ updating portlet config for " + pd.getName());
            String key = pd.getId().toString();
            PortletInstance instance = (PortletInstance)portletCache.get(key);
            if (instance != null)
            {
                JetspeedPortletConfig config = (JetspeedPortletConfig)instance.getConfig();
                config.setPortletDefinition(pd);
            }
        }
    }
   
    public ClassLoader getPortletApplicationClassLoader(PortletApplication pa)
    {
        synchronized (classLoaderMap)
        {
          if ( pa != null )
        {
              return (ClassLoader)classLoaderMap.get(pa.getId());
        }
          return null;
        }
    }
   
    public boolean isPortletApplicationRegistered(PortletApplication pa)
    {
        return getPortletApplicationClassLoader(pa) != null;
    }
}
TOP

Related Classes of org.apache.jetspeed.factory.JetspeedPortletFactory

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.