Package org.apache.jetspeed.tools.pamanager

Source Code of org.apache.jetspeed.tools.pamanager.PortletApplicationManager

/*
* Copyright 2000-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.tools.pamanager;

import java.io.File;
import java.io.IOException;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.jetspeed.cluster.NodeManager;
import org.apache.jetspeed.components.portletentity.PortletEntityAccessComponent;
import org.apache.jetspeed.components.portletentity.PortletEntityNotDeletedException;
import org.apache.jetspeed.components.portletregistry.PortletRegistry;
import org.apache.jetspeed.components.portletregistry.RegistryException;
import org.apache.jetspeed.container.window.PortletWindowAccessor;
import org.apache.jetspeed.factory.PortletFactory;
import org.apache.jetspeed.om.common.portlet.MutablePortletApplication;
import org.apache.jetspeed.om.common.servlet.MutableWebApplication;
import org.apache.jetspeed.search.SearchEngine;
import org.apache.jetspeed.security.PermissionManager;
import org.apache.jetspeed.security.PortletPermission;
import org.apache.jetspeed.security.Role;
import org.apache.jetspeed.security.RoleManager;
import org.apache.jetspeed.security.SecurityException;
import org.apache.jetspeed.util.DirectoryHelper;
import org.apache.jetspeed.util.FileSystemHelper;
import org.apache.jetspeed.util.MultiFileChecksumHelper;
import org.apache.jetspeed.util.descriptor.PortletApplicationWar;
import org.apache.pluto.om.common.SecurityRole;
import org.apache.pluto.om.entity.PortletEntity;
import org.apache.pluto.om.entity.PortletEntityCtrl;
import org.apache.pluto.om.portlet.PortletDefinition;

/**
* PortletApplicationManager
*
* @author <a href="mailto:ate@douma.nu">Ate Douma</a>
* @version $Id: PortletApplicationManager.java,v 1.21 2005/04/09 00:24:44 shinsuke Exp $
*/
public class PortletApplicationManager implements PortletApplicationManagement
{
    private static int DEFAULT_DESCRIPTOR_CHANGE_MONITOR_INTERVAL = 10*1000; // 10 seconds
    private static final Log    log = LogFactory.getLog("deployment");

    protected PortletEntityAccessComponent entityAccess;
    protected PortletFactory        portletFactory;
    protected PortletRegistry       registry;
    protected PortletWindowAccessor windowAccess;
    protected SearchEngine          searchEngine;
    protected RoleManager           roleManager;
    protected PermissionManager     permissionManager;
    protected boolean               autoCreateRoles;
    protected List                  permissionRoles;
    protected int  descriptorChangeMonitorInterval = DEFAULT_DESCRIPTOR_CHANGE_MONITOR_INTERVAL;
    protected DescriptorChangeMonitor monitor;
    protected boolean started;

    protected NodeManager nodeManager;
   
    /**
   * Creates a new PortletApplicationManager object.
   */
  public PortletApplicationManager(PortletFactory portletFactory, PortletRegistry registry,
    PortletEntityAccessComponent entityAccess, PortletWindowAccessor windowAccess,
        PermissionManager permissionManager, SearchEngine searchEngine,
        RoleManager roleManager, List permissionRoles, NodeManager nodeManager)
  {
    this.portletFactory     = portletFactory;
    this.registry        = registry;
    this.entityAccess      = entityAccess;
    this.windowAccess      = windowAccess;
        this.permissionManager  = permissionManager;
        this.searchEngine       = searchEngine;
        this.roleManager        = roleManager;       
        this.permissionRoles    = permissionRoles;
        this.nodeManager    = nodeManager;
  }
   
    public void start()
    {
        if ( descriptorChangeMonitorInterval > 0 )
        {
            try
            {
                monitor = new DescriptorChangeMonitor(Thread.currentThread().getThreadGroup(),
                                                "PortletApplicationManager Descriptor Change Monitor Thread", this, descriptorChangeMonitorInterval);

                monitor.setContextClassLoader(getClass().getClassLoader());
                monitor.start();
                log.info("PortletApplicationManager Descriptor Change Monitor started!");
            }
            catch (Exception e)
            {
                log.warn("Unable to start PortletApplicationManager Descriptor Change Monitor: "+ e.toString(), e);
                monitor.safeStop();
                monitor = null;
            }
        }
        started = true;
    }
   
    public void stop()
    {
        started = false;
        if (monitor != null)
        {
            monitor.safeStop();
            monitor = null;
        }
    }
   
    public boolean isStarted()
    {
        return started;
    }
   
    public void setRoleManager(RoleManager roleManager)
    {
        this.roleManager = roleManager;
    }
   
    public void setAutoCreateRoles(boolean autoCreateRoles)
    {
        this.autoCreateRoles = autoCreateRoles;
    }

  public void setSearchEngine(SearchEngine searchEngine)
  {
    this.searchEngine = searchEngine;
  }
   
    private void checkStarted()
    {
        if (!started)
        {
            throw new IllegalStateException("Not started yet");
        }
    }

  public void startLocalPortletApplication(String contextName, FileSystemHelper warStruct,
    ClassLoader paClassLoader)
    throws RegistryException
  {
        checkStarted();
        startPA(contextName, warStruct, paClassLoader, true);
  }

  public void startPortletApplication(String contextName, FileSystemHelper warStruct,
    ClassLoader paClassLoader)
    throws RegistryException
  {
        checkStarted();
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        try
        {
            startPA(contextName, warStruct, paClassLoader, false);
        }
        finally
        {
            Thread.currentThread().setContextClassLoader(contextClassLoader);
        }
  }

  public void stopLocalPortletApplication(String contextName)
    throws RegistryException
  {
    stopPA(contextName, true);
  }

  public void stopPortletApplication(String contextName)
    throws RegistryException
  {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        try
        {
            stopPA(contextName, false);
        }
        finally
        {
            Thread.currentThread().setContextClassLoader(contextClassLoader);
        }
  }

  public void unregisterPortletApplication(String paName)
    throws RegistryException
  {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
        try
        {
            MutablePortletApplication pa = null;
           
            try
            {
                pa = (MutablePortletApplication) registry.getPortletApplication(paName);
            }
            catch (Exception e)
            {
                // ignore errors during portal shutdown
            }

           
            if (pa != null)
            {
                if (portletFactory.isPortletApplicationRegistered(pa))
                {
                    throw new RegistryException("Portlet Application " + paName + " still running");
                }

                unregisterPortletApplication(pa, true);
                try
                {
                  nodeManager.removeNode(paName);
                }
                catch (Exception ee)
                {
                  // we actually do not care about an exception in the remove operation...
                }
            }
        }
        finally
        {
            Thread.currentThread().setContextClassLoader(contextClassLoader);
        }
  }
   
    protected int getApplicationType(boolean local)
    {
        return local ?  MutablePortletApplication.LOCAL : MutablePortletApplication.WEBAPP;
    }

  protected void checkValidContextName(String contextName, boolean local)
    throws RegistryException
  {
    int prefixLength = LOCAL_PA_PREFIX.length();

    if ((contextName.length() >= prefixLength)
      && contextName.substring(0, prefixLength).equalsIgnoreCase(LOCAL_PA_PREFIX))
    {
      if (!local)
      {
        throw new RegistryException("Prefix \"" + LOCAL_PA_PREFIX
          + "\" is reserved for Local Portlet Applications only.");
      }
    }
    else if (local)
    {
      throw new RegistryException("Prefix \"" + LOCAL_PA_PREFIX
        + "\" is required for Local Portlet Applications.");
    }
  }

  protected MutablePortletApplication registerPortletApplication(PortletApplicationWar paWar,
    MutablePortletApplication oldPA, boolean local, ClassLoader paClassLoader)
    throws RegistryException
  {
    if (oldPA != null)
    {
      unregisterPortletApplication(oldPA, false);
      oldPA = null;
    }

    MutablePortletApplication pa     = null;
    boolean            registered = false;
    String            paName     = paWar.getPortletApplicationName();

    try
    {
      log.info("Loading portlet.xml...." + paName);
      pa = paWar.createPortletApp(paClassLoader);

      if (local)
      {
        pa.setApplicationType(MutablePortletApplication.LOCAL);
      }
      else
      {
        pa.setApplicationType(MutablePortletApplication.WEBAPP);
      }

      // load the web.xml
      log.info("Loading web.xml...." + paName);
      MutableWebApplication wa = paWar.createWebApp();
      paWar.validate();

      if (local)
      {
        wa.setContextRoot("<portal>");
      }

      pa.setWebApplicationDefinition(wa);
           
            // Make sure existing entities are refreshed with the most
            // recent PortletDefintion.
            Collection portletDefs = pa.getPortletDefinitions();
            if(portletDefs != null && portletDefs.size() > 0)
            {
                Iterator pdItr = portletDefs.iterator();
                while(pdItr.hasNext())
                {
                    PortletDefinition pd = (PortletDefinition) pdItr.next();
                    Collection portletEntites = entityAccess.getPortletEntities(pd);
                    if(portletEntites != null && portletEntites.size() > 0)
                    {
                        Iterator peItr = portletEntites.iterator();
                        while(peItr.hasNext())
                        {
                            PortletEntityCtrl portletEntity = (PortletEntityCtrl) peItr.next();
                            portletEntity.setPortletDefinition(pd);
                        }
                    }
                }
            }
    }
    catch (Exception e)
    {
      String msg = "Failed to load portlet application for "
        + paWar.getPortletApplicationName();
      log.error(msg, e);
      throw new RegistryException(msg);
    }

    // register the portlet application
    try
    {
      registry.registerPortletApplication(pa);
      registered = true;
      log.info("Registered the portlet application " + paName);

      // add to search engine result
      this.updateSearchEngine(false, pa);
     
      // and add to the current node info
      nodeManager.addNode(new Long(pa.getId().toString()), pa.getName());
           
            // grant default permissions to portlet application
      grantDefaultPermissions(paName);
           
            if ( autoCreateRoles && roleManager != null && pa.getWebApplicationDefinition().getSecurityRoles() != null )
            {
                try
                {
                    Iterator rolesIter = pa.getWebApplicationDefinition().getSecurityRoles().iterator();
                    SecurityRole sr;
                    while ( rolesIter.hasNext() )
                    {
                        sr = (SecurityRole)rolesIter.next();
                        if ( !roleManager.roleExists(sr.getRoleName()) )
                        {
                            roleManager.addRole(sr.getRoleName());
                            log.info("AutoCreated role: "+sr.getRoleName()+" from portlet application "+paName+" its web definition");
                        }
                    }
                }
                catch (SecurityException sex)
                {
                    log.warn("Failed to autoCreate roles for portlet application " + paName+": "+sex.getMessage(), sex);
                }
            }

      return pa;
    }
    catch (Exception e)
    {
      String msg = "Failed to register portlet application, " + paName;
      log.error(msg, e);

      if (registered)
      {
        try
        {
          unregisterPortletApplication(pa, local);
        }
        catch (Exception re)
        {
          log.error("Failed to rollback registration of portlet application" + paName, re);
        }
      }

      throw new RegistryException(msg, e);
    }
  }

  protected void startPA(String contextName, FileSystemHelper warStruct,
          ClassLoader paClassLoader, boolean local)
  throws RegistryException
  {
      startPA(contextName, warStruct, paClassLoader, local, 0);
  }
 
  protected void startPA(String contextName, FileSystemHelper warStruct,
          ClassLoader paClassLoader, boolean local, long checksum)
  throws RegistryException
  {
        PortletApplicationWar paWar = null;
    try
    {
            boolean register = true;
            boolean monitored = checksum != 0;
            paWar = new PortletApplicationWar(warStruct, contextName, "/" + contextName, checksum);
            try
            {
                if (paClassLoader == null)
                {
                    paClassLoader = paWar.createClassloader(getClass().getClassLoader());
                }               
                checksum = paWar.getPortletApplicationChecksum();               
            }
            catch (IOException e)
            {
                String msg = "Invalid PA WAR for " + contextName;
                log.error(msg, e);
                if ( paClassLoader == null )
                {
                    // nothing to be done about it anymore: this pa is beyond repair :(
                    throw new RegistryException(e);
                }
                register = false;
            }

      MutablePortletApplication pa = (MutablePortletApplication) registry.getPortletApplication(contextName);

            if (pa != null)
            {
                if ( pa.getApplicationType() != getApplicationType(local) )
                {
                    if ( local )
                    {
                        throw new RegistryException("Cannot start local portlet application "+contextName+": it is not a local application");
                    }
                    else
                    {
                        throw new RegistryException("Cannot start portlet application "+contextName+": it is a local application");
                    }                   
                }
                DescriptorChangeMonitor changeMonitor = this.monitor;
                if (!monitored && changeMonitor != null)
                {
                    changeMonitor.remove(contextName);
                }
                portletFactory.unregisterPortletApplication(pa);                       
            }
//            if (register && (pa == null || checksum != pa.getChecksum()))
            if (register)
            {
              if (pa == null)
              {
                // new
                  try
                  {
                      pa = registerPortletApplication(paWar, pa, local, paClassLoader);
                  }
                  catch (Exception e)
                  {
                      // don't register the pa
                      register = false;
                  }
              }
              else
              {
                int status = nodeManager.checkNode(new Long(pa.getId().toString()), pa.getName());
              boolean reregister = false;
              boolean deploy = false;
              switch (status)
              {
                case  NodeManager.NODE_NEW:
                {
                    //only reason is that the file got somehow corrupted
                    // so we really do not know what is going on here...
                    // the best chance at this point is to reregister (which might be the absolute wrong choice)
                    log.warn("The portlet application " + pa.getName() + " is registered in the database but not locally .... we will reregister");
                    reregister = true;
                  if (checksum != pa.getChecksum())
                  {
                        log.warn("The provided portlet application " + pa.getName() + " is a different version than in the database (db-checksum=" + pa.getChecksum() + ", local-checksum=: " + checksum + ") .... we will redeploy (also to the database)");
                  deploy = true;
                  }
                  break;
                }
                case  NodeManager.NODE_SAVED:
                {
                  if (checksum != pa.getChecksum())
                        { 
                        log.warn("The provided portlet application " + pa.getName() + " is a different version than in the local node info and the database (db-checksum=" + pa.getChecksum() + ", local-checksum=: " + checksum + ") .... we will reregister AND redeploy (also to the database)");
                    //database and local node info are in synch, so we assume that this is a brand new
                    // war .... let's deploy
                    reregister = true;
                    deploy = true;
                        }
                  break;
                }
                case  NodeManager.NODE_OUTDATED:
                {
                    //database version is older (determined by id) than the database
                  //let's deploy and reregister
                  if (checksum != pa.getChecksum())
                        log.error("The portlet application " + pa.getName() + " provided for the upgrade IS WRONG. The database checksum= " + pa.getChecksum() + ", but the local=" + checksum + "....THIS NEEDS TO BE CORRECTED");
                   reregister = true;
                  break;
                }
              }
              if (deploy)
                      pa = registerPortletApplication(paWar, pa, local, paClassLoader);
              else
                if (reregister)
                {
                  // add to search engine result
                  this.updateSearchEngine(true, pa);
                  this.updateSearchEngine(false, pa);
                 
                  // and add to the current node info
                  try
                  {
                    nodeManager.addNode(new Long(pa.getId().toString()), pa.getName());
                  } catch (Exception e)
                  {
                    log.error("Adding node for portlet application " + pa.getName() + " caused exception" , e);
                  }
                }
               
             
              }
            }
            if (register)
            {
                portletFactory.registerPortletApplication(pa, paClassLoader);
            }
           
            DescriptorChangeMonitor changeMonitor = this.monitor;
            if (!monitored && changeMonitor != null)
            {
                changeMonitor.monitor(contextName,paClassLoader, local, warStruct.getRootDirectory(), checksum);
            }
    }
    finally
    {
      if (paWar != null)
      {
        try
        {
          paWar.close();
        }
        catch (IOException e)
        {
          log.error("Failed to close PA WAR for " + contextName, e);
        }
      }
    }
  }

  protected void stopPA(String contextName, boolean local)
    throws RegistryException
  {
    MutablePortletApplication pa = null;
       
        try
        {
            pa = (MutablePortletApplication) registry.getPortletApplication(contextName);
        }
        catch (Exception e)
        {
            // ignore errors during portal shutdown
        }
        if  (pa != null && pa.getApplicationType() != getApplicationType(local) )
        {
            if ( local )
            {
                throw new RegistryException("Cannot stop local portlet application "+contextName+": it is not a local application");
            }
            else
            {
                throw new RegistryException("Cannot stop portlet application "+contextName+": it is a local application");
            }
        }
        DescriptorChangeMonitor monitor = this.monitor;
        if ( monitor != null )
        {
            monitor.remove(contextName);
        }
    if (pa != null)
    {
            portletFactory.unregisterPortletApplication(pa);
    }
  }

 
  protected void updateSearchEngine(boolean remove,MutablePortletApplication pa )
  {
    if (searchEngine != null)
    {
      if (remove)
      {
        searchEngine.remove(pa);
        searchEngine.remove(pa.getPortletDefinitions());
          log.info("Un-Registered the portlet application in the search engine... " + pa.getName());
      }
      else
      {
          searchEngine.add(pa);
          searchEngine.add(pa.getPortletDefinitions());
          log.info("Registered the portlet application in the search engine... " + pa.getName());
      }
    }
   
  }
  protected void unregisterPortletApplication(MutablePortletApplication pa,
    boolean purgeEntityInfo)
    throws RegistryException
  {

    updateSearchEngine(true,pa);
    log.info("Remove all registry entries defined for portlet application " + pa.getName());

    Iterator portlets = pa.getPortletDefinitions().iterator();

    while (portlets.hasNext())
    {
      PortletDefinition portletDefinition = (PortletDefinition) portlets.next();
      Iterator      entities = entityAccess.getPortletEntities(portletDefinition)
                           .iterator();

      while (entities.hasNext())
      {
        PortletEntity entity = (PortletEntity) entities.next();

        if (purgeEntityInfo)
        {
          try
          {
            entityAccess.removePortletEntity(entity);
          }
          catch (PortletEntityNotDeletedException e)
          {
            String msg = "Failed to delete Portlet Entity " + entity.getId();
            log.error(msg, e);
            throw new RegistryException(msg, e);
          }
        }

        entityAccess.removeFromCache(entity);
        windowAccess.removeWindows(entity);
      }
    }

    // todo keep (User)Prefs?
    registry.removeApplication(pa);
        revokeDefaultPermissions(pa.getName());
  }
   
    protected void grantDefaultPermissions(String paName)
    {
        try
        {
            // create a default permission for this portlet app, granting configured roles to the portlet application
            Iterator roles = permissionRoles.iterator();
            while (roles.hasNext())
            {
                String roleName = (String)roles.next();
                Role userRole = roleManager.getRole(roleName);
                if (userRole != null)
                {
                    Permission permission = new PortletPermission(paName + "::*", "view, edit");
                    if (!permissionManager.permissionExists(permission))
                    {
                        permissionManager.addPermission(permission);
                        permissionManager.grantPermission(userRole.getPrincipal(), permission);
                    }                   
                }
            }
        }
        catch (SecurityException e)
        {
            log.error("Error granting default permissions for " + paName, e);
        }       
    }
   
    protected void revokeDefaultPermissions(String paName)
    {
        try
        {
            Iterator roles = permissionRoles.iterator();
            while (roles.hasNext())
            {
                String roleName = (String)roles.next();
                Role userRole = roleManager.getRole(roleName);
                if (userRole != null)
                {
                    Permission permission = new PortletPermission(paName + "::*", "view, edit");
                    if (permissionManager.permissionExists(permission))
                    {
                        permissionManager.removePermission(permission);
                    }                   
                   
                }
            }
        }
        catch (SecurityException e)
        {
            log.error("Error revoking default permissions for " + paName, e);
        }
    }

    public int getDescriptorChangeMonitorInterval()
    {
        return descriptorChangeMonitorInterval/1000;
    }

    public void setDescriptorChangeMonitorInterval(int descriptorChangeMonitorInterval)
    {
        this.descriptorChangeMonitorInterval = descriptorChangeMonitorInterval*1000;
    }   
   
    private static class DescriptorChangeMonitor extends Thread
    {
        private static class DescriptorChangeMonitorInfo
        {
            private String contextName;
            private ClassLoader paClassLoader;
            private boolean local;
            private File paDir;
            private File[] descriptors;
            private long descriptorModificationTime;
            private long extendedDescriptorModificationTime;
            private long checksum;
            private boolean obsolete;
                       
            /*
             * Constructor only used for looking up the matching registered one in monitorsInfo
             */
            public DescriptorChangeMonitorInfo(String contextName)
            {
                this.contextName = contextName;
            }
           
            public DescriptorChangeMonitorInfo(String contextName, ClassLoader paClassLoader, boolean local, File paDir, long checksum)
            {
                this.contextName = contextName;
                this.paClassLoader = paClassLoader;
                this.local = local;
                this.paDir = paDir.isAbsolute() ? paDir : paDir.getAbsoluteFile();
                this.checksum = checksum;
               
                this.descriptors = new File[] {
                        new File(paDir, PortletApplicationWar.WEB_XML_PATH),
                        new File(paDir, PortletApplicationWar.PORTLET_XML_PATH),
                        new File(paDir, PortletApplicationWar.EXTENDED_PORTLET_XML_PATH) };

                descriptorModificationTime = descriptors[1].lastModified();
                extendedDescriptorModificationTime = descriptors[2].lastModified();
            }
           
            public String getContextName()
            {
                return contextName;
            }
           
            public ClassLoader getPAClassLoader()
            {
                return paClassLoader;
            }
           
            public boolean isLocal()
            {
                return local;
            }
           
            public File getPADir()
            {
                return paDir;
            }

            public long getChecksum()
            {
                return checksum;
            }
           
            public boolean isChanged()
            {
                if ( !obsolete)
                {
                    long newDescriptorModificationTime = descriptors[1].lastModified();
                    long newExtendedDescriptorModificationTime = descriptors[2].lastModified();
                    if ( descriptorModificationTime != newDescriptorModificationTime ||
                            extendedDescriptorModificationTime != newExtendedDescriptorModificationTime )
                    {
                        descriptorModificationTime = newDescriptorModificationTime;
                        extendedDescriptorModificationTime = newExtendedDescriptorModificationTime;
                        long newChecksum = MultiFileChecksumHelper.getChecksum(descriptors);
                        if ( checksum != newChecksum )
                        {
                            checksum = newChecksum;
                            return true;
                        }
                    }
                }
                return false;
            }
           
            public void setObsolete()
            {
                obsolete = true;
            }
           
            public boolean isObsolete()
            {
                return obsolete;
            }
        }       

        private PortletApplicationManager pam;
        private long interval;
        private boolean started = true;
        private ArrayList monitorInfos;

        public DescriptorChangeMonitor(ThreadGroup group, String name, PortletApplicationManager pam, long interval)
        {
            super(group, name);
            this.pam = pam;
            this.interval = interval;
            monitorInfos = new ArrayList();
            setPriority(MIN_PRIORITY);
            setDaemon(true);
        }
       
        public void run()
        {
            try
            {
                sleep(interval);
            }
            catch (InterruptedException e)
            {
            }
            while (started)
            {
                checkDescriptorChanges();

                try
                {
                    sleep(interval);
                }
                catch (InterruptedException e)
                {

                }
            }
        }

        /**
         * notifies a switch variable that exits the watcher's montior loop started in the <code>run()</code> method.
         */
        public synchronized void safeStop()
        {
            started = false;
            monitorInfos.clear();
        }
       
        public synchronized void monitor(String contextName, ClassLoader paClassLoader, boolean local, File paDir, long checksum)
        {
            monitorInfos.add(new DescriptorChangeMonitorInfo(contextName, paClassLoader, local, paDir, checksum));
        }
       
        public synchronized void remove(String contextName)
        {
            DescriptorChangeMonitorInfo monitorInfo;
            for ( int i = monitorInfos.size()-1; i > -1; i-- )
            {
                monitorInfo = (DescriptorChangeMonitorInfo)monitorInfos.get(i);
                if (contextName.equals(monitorInfo.getContextName()))
                {
                    // will be removed by checkDescriptorChanges on next iteration
                    monitorInfo.setObsolete();
                    break;
                }
            }
        }
       
        private void checkDescriptorChanges()
        {
            int size;
            synchronized (this)
            {
                size = monitorInfos.size();
            }
            for (int i = size-1; i > -1; i--)
            {
                DescriptorChangeMonitorInfo monitorInfo;
                synchronized (this)
                {
                    if ( started )
                    {
                        monitorInfo = (DescriptorChangeMonitorInfo)monitorInfos.get(i);
                        if (monitorInfo.isObsolete())
                        {
                            monitorInfos.remove(i);
                        }
                        else
                        {
                            try
                            {
                                if (monitorInfo.isChanged())
                                {
                                    try
                                    {
                                        pam.startPA(monitorInfo.getContextName(), new DirectoryHelper(monitorInfo.getPADir()),
                                                monitorInfo.getPAClassLoader(), monitorInfo.isLocal(), monitorInfo.getChecksum());
                                    }
                                    catch (Exception e)
                                    {
                                        log.error("Failed to restart PortletApplication "+monitorInfo.getContextName(),e);
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                // ignore filesystem and/or descriptor errors, maybe next time round they'll be fixed again
                                log.error("Descriptor Change check failure for PortletApplication "+monitorInfo.getContextName(),e);
                            }
                        }
                    }
                }
            }
        }       
    }   
}
TOP

Related Classes of org.apache.jetspeed.tools.pamanager.PortletApplicationManager

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.