You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by ra...@apache.org on 2001/06/04 19:30:44 UTC

cvs commit: jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager CastorPsmlManagerService.java PsmlManagerService.java

raphael     01/06/04 10:30:44

  Modified:    src/java/org/apache/jetspeed/services/jsp/tags
                        JetspeedPaneTag.java JetspeedPortletTag.java
               src/java/org/apache/jetspeed/services/portletcache
                        Cacheable.java
               src/java/org/apache/jetspeed/services/profiler
                        JetspeedProfilerService.java
  Added:       src/java/org/apache/jetspeed/services PortalToolkit.java
                        PortletFactory.java PsmlManager.java
               src/java/org/apache/jetspeed/services/portaltoolkit
                        JetspeedPortalToolkitService.java
                        PortalToolkitService.java
               src/java/org/apache/jetspeed/services/portletfactory
                        JetspeedPortletFactoryService.java
                        PortletFactoryService.java
               src/java/org/apache/jetspeed/services/psmlmanager
                        CastorPsmlManagerService.java
                        PsmlManagerService.java
  Removed:     src/java/org/apache/jetspeed/services ControllerFactory.java
  Log:
  add 3 new services:
  - PsmlManager (handling configuration serialization/deserialization)
  - PortletFactory (creating and initializing "user" portlets)
  - PortalToolkit (creating portal specific objects: skins, controls, controllers, portlet sets)
  
  Revision  Changes    Path
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/PortalToolkit.java
  
  Index: PortalToolkit.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services;
  
  //jetspeed stuff
  import org.apache.jetspeed.portal.PortletSet;
  import org.apache.jetspeed.portal.PortletSkin;
  import org.apache.jetspeed.portal.PortletControl;
  import org.apache.jetspeed.portal.PortletController;
  import org.apache.jetspeed.xml.api.portletmarkup.Control;
  import org.apache.jetspeed.xml.api.portletmarkup.Controller;
  import org.apache.jetspeed.xml.api.portletmarkup.Portlets;
  import org.apache.jetspeed.xml.api.portletmarkup.Skin;
  import org.apache.jetspeed.services.portaltoolkit.PortalToolkitService;
  import org.apache.turbine.services.TurbineServices;
   
  /**
   * Commodity static wrapper around the PortalToolit service
   * 
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: PortalToolkit.java,v 1.1 2001/06/04 17:30:26 raphael Exp $
   */
  public class PortalToolkit
  {
              
      /** 
       * Commodity method for getting a reference to the service
       * singleton
       */
      private static PortalToolkitService getService()
      {
          return (PortalToolkitService)TurbineServices
                  .getInstance()
                  .getService(PortalToolkitService.SERVICE_NAME);     
      }
  
      /**
       * Instanciates a PortletControl based on a Registry entry, if available 
       * or directly from a classname.
       *
       * @param name a PortletControl name available in the registry or a classname
       * @return the created PortletControl
       */
      public static PortletControl getControl( String name )
      {
          return getService().getControl(name);
      }
  
      /**
       * Instanciates a PortletControl based on a PSML Control object
       *
       * @param control the PSML control object
       * @return the created PortletControl
       */
      public static PortletControl getControl( Control control )
      {
          return getService().getControl(control);
      }
  
      /**
       * Instanciates a PortletController based on a Registry entry, if available 
       * or directly from a classname.
       *
       * @param name a PortletController name available in the registry or a classname
       * @return the created PortletController
       */
      public static PortletController getController( String name )
      {
          return getService().getController(name);
      }
  
      /**
       * Instanciates a PortletController based on a PSML Controller object
       *
       * @param control the PSML controller object
       * @return the created PortletController
       */
      public static PortletController getController( Controller controller )
      {
          return getService().getController(controller);
      }
  
      /**
       * Create a PortletSkin object based on a Registry entry if available
       *
       * @param name the skin name in the Registry
       * @return the new PortletSkin object
       */
      public static PortletSkin getSkin( String name )
      {
          return getService().getSkin(name);
      }
  
      /**
       * Create a PortletSkin object based on PSML skin description
       *
       * @param skin the PSML Skin object
       * @return the new PortletSkin object
       */
      public static PortletSkin getSkin( Skin skin )
      {
          return getService().getSkin(skin);
      }
  
      /**
       * Creates a PortletSet from a PSML portlets description
       *
       * @param portlets the PSML portlet set description
       * @return a new instance of PortletSet
       */
      public static PortletSet getSet( Portlets portlets )
      {
          return getService().getSet(portlets);
      }
      
  }
  
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/PortletFactory.java
  
  Index: PortletFactory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services;
  
  //jetspeed stuff
  import org.apache.jetspeed.portal.Portlet;
  import org.apache.jetspeed.portal.PortletException;
  import org.apache.jetspeed.xml.api.portletmarkup.Entry;
  import org.apache.jetspeed.services.portletfactory.PortletFactoryService;
  import org.apache.turbine.services.TurbineServices;
   
  /**
   * Static wrapper around the PortletFactoryService
   * 
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: PortletFactory.java,v 1.1 2001/06/04 17:30:26 raphael Exp $
   */
  public class PortletFactory
  {
  
      /** 
       * Commodity method for getting a reference to the service
       * singleton
       */
      private static PortletFactoryService getService()
      {
          return (PortletFactoryService)TurbineServices
                  .getInstance()
                  .getService(PortletFactoryService.SERVICE_NAME);     
      }
  
      /**
       * Given a PSML Entry return an instanciated Portlet.
       *
       * @param entry a PSML Entry describing a portlet
       * @return an instanciated portlet corresponding to this entry
       */
      public static Portlet getPortlet( Entry entry ) throws PortletException
      {
          return getService().getPortlet( entry );
      }
  
      /**
       * Given a Portlet registry entry name, instanciate it
       *
       * @param name the name of a portlet in the registry
       * @return an instanciated portlet corresponding to this entry
       */
      public static Portlet getPortlet( String name ) throws PortletException
      {
          return getService().getPortlet( name );
      }
  }
  
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/PsmlManager.java
  
  Index: PsmlManager.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services;
  
  import org.apache.jetspeed.services.psmlmanager.PsmlManagerService;
  import org.apache.jetspeed.om.profile.PSMLDocument;
  import org.apache.turbine.services.TurbineServices;
  
  /**
   * Static accessor for the PsmlManagerService
   *
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: PsmlManager.java,v 1.1 2001/06/04 17:30:27 raphael Exp $
   */
  public class PsmlManager
  {
  
      /** 
       * Commodity method for getting a reference to the service
       * singleton
       */
      private static PsmlManagerService getService()
      {
          return (PsmlManagerService)TurbineServices
                  .getInstance()
                  .getService(PsmlManagerService.SERVICE_NAME);     
      }
  
      /**
       * Returns a PSML document of the given name.
       * For this implementation, the name must be the document
       * URL or absolute filepath
       *
       * @param name the name of the document to retrieve
       */
      public static PSMLDocument getDocument( String name )
      {
          return getService().getDocument(name);
      }
  
      /** Save the PSML document on disk, using its name as filepath
       * 
       * @param doc the document to save
       */
      public static boolean saveDocument(PSMLDocument doc)
      {
          return getService().saveDocument(doc);
      }
      
      /** Save the PSML document on disk to the specififed fileOrUrl
       * 
       * @param fileOrUrl a String representing either an absolute URL
       * or an absolute filepath
       * @param doc the document to save
       */
      public static boolean saveDocument(String fileOrUrl, PSMLDocument doc)
      {
          return getService().saveDocument(fileOrUrl, doc);
      }
  }
  
  
  
  
  1.2       +12 -14    jakarta-jetspeed/src/java/org/apache/jetspeed/services/jsp/tags/JetspeedPaneTag.java
  
  Index: JetspeedPaneTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/jsp/tags/JetspeedPaneTag.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JetspeedPaneTag.java	2001/05/27 15:31:30	1.1
  +++ JetspeedPaneTag.java	2001/06/04 17:30:29	1.2
  @@ -59,20 +59,17 @@
   import javax.servlet.jsp.tagext.*;
   
   // Turbine Classes 
  -import org.apache.turbine.util.RunData;
   import org.apache.turbine.util.Log;
   import org.apache.turbine.services.jsp.JspService;
   
   import org.apache.ecs.ConcreteElement;
   import org.apache.ecs.StringElement;
   
  -import org.apache.jetspeed.services.Profiler;
  +import org.apache.jetspeed.om.profile.PSMLDocument;
  +import org.apache.jetspeed.services.PortalToolkit;
  +import org.apache.jetspeed.services.PsmlManager;
   import org.apache.jetspeed.services.resources.JetspeedResources;
  -import org.apache.jetspeed.om.profile.Profile;
  -import org.apache.jetspeed.om.profile.ProfileException;
  -import org.apache.jetspeed.capability.CapabilityMapFactory;
  -import org.apache.jetspeed.capability.CapabilityMap;
  -import org.apache.jetspeed.portal.factory.PortletSetFactory;
  +import org.apache.jetspeed.services.rundata.JetspeedRunData;
   
   /**
    * Supporting class for the pane tag.
  @@ -80,7 +77,7 @@
    * current JSP page
    *
    * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
  - * @version $Id: JetspeedPaneTag.java,v 1.1 2001/05/27 15:31:30 raphael Exp $
  + * @version $Id: JetspeedPaneTag.java,v 1.2 2001/06/04 17:30:29 raphael Exp $
    */
   public class JetspeedPaneTag extends TagSupport 
   {
  @@ -104,7 +101,7 @@
        */
       public int doStartTag() throws JspException 
       {
  -        RunData data = (RunData)pageContext.getAttribute(JspService.RUNDATA, PageContext.REQUEST_SCOPE);
  +        JetspeedRunData data = (JetspeedRunData)pageContext.getAttribute(JspService.RUNDATA, PageContext.REQUEST_SCOPE);
           
           // retrieve the name attribute val
           if (this.name == null)
  @@ -120,9 +117,7 @@
           
               if ((name == null) || "default".equals(name) || "".equals(name))
               {
  -                CapabilityMap cm = CapabilityMapFactory.getCapabilityMap(data);
  -                Profile profile = Profiler.getProfile(data,cm);
  -                result = profile.getRootSet(data).getContent(data);
  +                result = data.getProfile().getRootSet().getContent(data);
               }
               else
               {
  @@ -132,9 +127,12 @@
                   String path = JetspeedResources.getString( JetspeedResources.PSML_BASE_URL_KEY )
                                       + name
                                       + ".psml";
  -                result = PortletSetFactory.getInstance(path)
  -                                          .getPortletSet(data)
  +                PSMLDocument doc = PsmlManager.getDocument(path);
  +                if (doc != null)
  +                {
  +                    result = PortalToolkit.getSet(doc.getPortlets())
                                             .getContent(data);
  +                }
               }
           
               // Check whether this is an "old" screen (that returns a ConcreteElement)
  
  
  
  1.2       +5 -14     jakarta-jetspeed/src/java/org/apache/jetspeed/services/jsp/tags/JetspeedPortletTag.java
  
  Index: JetspeedPortletTag.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/jsp/tags/JetspeedPortletTag.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- JetspeedPortletTag.java	2001/05/28 15:10:47	1.1
  +++ JetspeedPortletTag.java	2001/06/04 17:30:30	1.2
  @@ -66,14 +66,9 @@
   import org.apache.ecs.ConcreteElement;
   import org.apache.ecs.StringElement;
   
  -import org.apache.jetspeed.services.Profiler;
  +import org.apache.jetspeed.services.PortletFactory;
   import org.apache.jetspeed.services.resources.JetspeedResources;
  -import org.apache.jetspeed.om.profile.Profile;
  -import org.apache.jetspeed.om.profile.ProfileException;
  -import org.apache.jetspeed.capability.CapabilityMapFactory;
  -import org.apache.jetspeed.capability.CapabilityMap;
  -import org.apache.jetspeed.portal.factory.PortletSetFactory;
  -import org.apache.jetspeed.portal.factory.PortletFactory;
  +import org.apache.jetspeed.services.rundata.JetspeedRunData;
   import org.apache.jetspeed.xml.api.portletmarkup.Entry;
   
   /**
  @@ -82,7 +77,7 @@
    * current JSP page
    *
    * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
  - * @version $Id: JetspeedPortletTag.java,v 1.1 2001/05/28 15:10:47 raphael Exp $
  + * @version $Id: JetspeedPortletTag.java,v 1.2 2001/06/04 17:30:30 raphael Exp $
    */
   public class JetspeedPortletTag extends TagSupport 
   {
  @@ -106,7 +101,7 @@
        */
       public int doStartTag() throws JspException 
       {
  -        RunData data = (RunData)pageContext.getAttribute(JspService.RUNDATA, PageContext.REQUEST_SCOPE);
  +        JetspeedRunData data = (JetspeedRunData)pageContext.getAttribute(JspService.RUNDATA, PageContext.REQUEST_SCOPE);
           
           // if called without arguments, use the default request parameter
           if (this.name == null)
  @@ -119,11 +114,7 @@
               pageContext.getOut().flush();
   
               ConcreteElement result = new ConcreteElement();
  -        
  -            CapabilityMap cm = CapabilityMapFactory.getCapabilityMap(data);
  -    
  -            Profile profile = Profiler.getProfile(data,cm);
  -            Entry entry  = profile.getFactory().getEntry(name);
  +            Entry entry  = data.getProfile().getDocument().getEntry(name);
                   
               if (entry != null)
               {
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/portaltoolkit/JetspeedPortalToolkitService.java
  
  Index: JetspeedPortalToolkitService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.portaltoolkit;
  
  //jetspeed stuff
  import org.apache.jetspeed.portal.*;
  import org.apache.jetspeed.xml.api.portletmarkup.*;
  import org.apache.jetspeed.services.Registry;
  import org.apache.jetspeed.services.PortletFactory;
  import org.apache.jetspeed.om.newregistry.PortletEntry;
  import org.apache.jetspeed.om.newregistry.PortletControlEntry;
  import org.apache.jetspeed.om.newregistry.PortletControllerEntry;
  import org.apache.jetspeed.om.newregistry.SkinEntry;
  import org.apache.jetspeed.util.MetaData;
  import org.apache.jetspeed.util.JetspeedException;
  
  import org.apache.turbine.services.TurbineServices;
  import org.apache.turbine.services.TurbineBaseService;
  import org.apache.turbine.services.InitializationException;
  import org.apache.turbine.services.resources.ResourceService;
  import org.apache.turbine.util.Log;
  
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Map;
  import javax.servlet.ServletConfig;
  
  /**
   * Simple implementation of the PortalFactoryService.
   * 
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: JetspeedPortalToolkitService.java,v 1.1 2001/06/04 17:30:35 raphael Exp $
   */
  public class JetspeedPortalToolkitService extends TurbineBaseService
      implements PortalToolkitService
  {
  
      /** The default control to use when none is specified */
      private String defaultControl = null;
  
      /** The default controller to use when none is specified */
      private String defaultController = null;
              
      /** The default skin to use when none is specified */
      private String defaultSkin = null;
              
      /**
       * This is the early initialization method called by the 
       * Turbine <code>Service</code> framework
       */
      public void init( ServletConfig conf ) throws InitializationException
      {
  
          ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
                                                       .getResources(PortalToolkitService.SERVICE_NAME);
  
          this.defaultControl = serviceConf.getString("default.control");
          this.defaultController = serviceConf.getString("default.controller");
          this.defaultSkin = serviceConf.getString("default.skin");
          
          setInit(true);
  
      }
              
      /**
       * Instanciates a PortletControl based on a Registry entry, if available 
       * or directly from a classname.
       *
       * @param name a PortletControl name available in the registry or a classname
       * @return the created PortletControl
       */
      public PortletControl getControl( String name )
      {
          PortletControl pc = null;
          PortletControlEntry entry = null;
          
          if (name != null)
          {
              entry = (PortletControlEntry)Registry.getEntry(Registry.PORTLET_CONTROL, name);
          }
          
          Map params = null;
          
          try
          {
              if (entry == null)
              {
                  if (name!=null)
                  {
                      pc = (PortletControl)Class.forName(name).newInstance();
                      params = new Hashtable();
                  }
              }
              else
              {
                  pc = (PortletControl)Class.forName(entry.getClassname()).newInstance();
                  params = entry.getParameterMap();
              }
          }
          catch (Exception e)
          {
              Log.error("Unable to instanciate control "+name+", using default", e);
          }
  
          if (    (pc == null)
               && (defaultControl != null)
               && (!defaultControl.equals(name)) )
          {
              return getControl( defaultControl );
          }
          
          PortletControlConfig pcConf = new BasePortletControlConfig();
          pcConf.setName( name );
          pcConf.setInitParameters(params);
          pc.setConfig(pcConf);
  
          return pc;
      }
  
      /**
       * Instanciates a PortletControl based on a PSML Control object
       *
       * @param control the PSML control object
       * @return the created PortletControl
       */
      public PortletControl getControl( Control control )
      {
          PortletControl pc = null;
  
          if (control!=null)
          {
              pc = getControl(control.getName());
              pc.getConfig().getInitParameters().putAll(getParameters(control));
          }
          else
          {
              if (defaultControl!=null)
              {
                  pc = getControl(this.defaultControl);
              }
          }
  
          return pc;
      }
  
  
      /**
       * Instanciates a PortletController based on a Registry entry, if available 
       * or directly from a classname.
       *
       * @param name a PortletController name available in the registry or a classname
       * @return the created PortletController
       */
      public PortletController getController( String name )
      {
          PortletController pc = null;
          PortletControllerEntry entry = null;
          
          
          if (name != null)
          {
              entry = (PortletControllerEntry)Registry
                                              .getEntry(Registry.PORTLET_CONTROLLER, name);
          }
          
          Map params = null;
          
          try
          {
              if (entry == null)
              {
                  if (name!=null)
                  {
                      pc = (PortletController)Class.forName(name).newInstance();
                      params = new Hashtable();
                  }
              }
              else
              {
                  pc = (PortletController)Class.forName(entry.getClassname()).newInstance();
                  params = entry.getParameterMap();
              }
          }
          catch (Exception e)
          {
              Log.error("Unable to instanciate controller "+name+", using default");
          }
  
          if (   (pc == null) 
              && (defaultController != null)
              && (!defaultController.equals(name)) )
          {
              return getController( defaultController );
          }
          
          PortletControllerConfig pcConf = new BasePortletControllerConfig();
          pcConf.setName( name );
          pcConf.setInitParameters(params);
          pc.setConfig(pcConf);
          pc.init();
          
          return pc;
      }
  
      /**
       * Instanciates a PortletController based on a PSML Controller object
       *
       * @param controller the PSML controller object
       * @return the created PortletController
       */
      public PortletController getController( Controller controller )
      {
  
          PortletController pc = null;
  
          if (controller!=null)
          {
              pc = getController(controller.getName());
              pc.getConfig().getInitParameters().putAll(getParameters(controller));
          }
          else
          {
              if (defaultController!=null)
              {
                  pc = getController(this.defaultController);
              }
          }
  
          pc.init();
  
          return pc;
      }
  
      /**
       * Create a PortletSkin object based on a Registry skin name
       *
       * @param name the registry SkinEntry name
       * @return the new PortletSkin object
       */
      public PortletSkin getSkin( String name )
      {
          BasePortletSkin result = new BasePortletSkin();
  
          SkinEntry entry = null;
          
          if (name!=null)
          {
              entry = (SkinEntry)Registry.getEntry(Registry.SKIN, name);
          }
  
          // either we don't have any skin defined, the skin reference is null
          // or the skin reference is invalid, in all case, retrieve the default
          // skin entry
          if (entry == null)
          {
              entry = (SkinEntry)Registry.getEntry(Registry.SKIN, this.defaultSkin);
          }
          
          if (entry!=null)
          {
              // build the PortletSkin object
              result.setName(entry.getName());
              result.putAll(entry.getParameterMap());
          }
          
          return result;
      }
  
      /**
       * Create a PortletSkin object based on PSML skin description
       *
       * @param skin the PSML Skin object
       * @return the new PortletSkin object
       */
      public PortletSkin getSkin( Skin skin )
      {
          PortletSkin result = null;
          String name = null;
  
          if (skin != null)
          {
              name = skin.getName();
          }
          else
          {
              name = defaultSkin;
          }
  
          // create the PortletSkin corresponding to this entry
          result = getSkin( name );
          
          // override the values with the locally defined properties
          result.putAll(getParameters(skin));
          
          return result;
      }
  
      /**
       * Creates a PortletSet from a PSML portlets description
       *
       * @param portlets the PSML portlet set description
       * @return a new instance of PortletSet
       */
      public PortletSet getSet( Portlets portlets )
      {
  
          // Create a new BasePortletSet to handle the portlets
          PortletSet set = new BasePortletSet();
          PortletController controller = getController( portlets.getController() );
          set.setController( controller );
  
          //FIXME: this sucks ! we should either associate the portlet set
          //with its portlets peer or set the porpoerties directly on the portlet
          //set object
          //Unfortunately, this would change the API too drastically for now...
          set.setPortletConfig( getPortletConfig( portlets ) );
  
          // Add all sub portlet sets in the main set
          Portlets[] subsets = portlets.getPortlets();
          for (int i=0; i < subsets.length; i++ )
          {
              Map constraints = getParameters(subsets[i].getLayout());
              int position = getPosition( subsets[i].getLayout() );
              set.addPortlet( getSet( subsets[i] ),
                              controller.getConstraints(constraints),
                              position );
          }
  
          // Populate the PortletSet with Portlets
          Entry[] entries = portlets.getEntry();
  
          for( int i = 0; i < entries.length; ++i )
          {
              try
              {
  
                  PortletEntry entry = (PortletEntry)Registry.getEntry( Registry.PORTLET, entries[i].getParent() );
             
                  if ( entry != null )
                  {
                      Portlet p = PortletFactory.getPortlet( entries[i] );
                      Map constraints = getParameters(entries[i].getLayout());
                      int position = getPosition( entries[i].getLayout() );
                      
                      PortletControl control =  getControl(entries[i].getControl());
                      
                      set.addPortlet( initControl(control,p),
                                      controller.getConstraints( constraints ),
                                      position );
                  }
                  else 
                  {
                      Log.error(" The portlet "+entries[i].getParent()+" does not exist in the Registry ");
                      continue;
                  }
              }
              catch ( JetspeedException e )
              {
                  Log.error( e );
                  continue;
              }
  
          }
  
          // Decorate with a control if required and return
          if ( portlets.getControl() != null )
          {
              PortletControl control = getControl(portlets.getControl());
              return initControl(control,set);            
          }
  
          // Or return the set
          return set;
      }
  
      /**
       * Associates a PortletControl wit an existing Portlet and
       * returns the Control
       *
       * @param pc the existing PortletControl
       * @param portlet the existing Portlet to be associated with the control
       * @return first PortletControl associated with the portlet
       */
      protected PortletControl initControl( PortletControl pc, Portlet portlet )
      {
  
          if (portlet == null)
          {
              throw new IllegalArgumentException( "Portlet not specified" );
          }
  
          if ( pc == null )
          {
              throw new IllegalArgumentException( "PortletControl not specified" );
          }
  
          pc.init( portlet );
  
          return pc;
  
      }
  
      /**
      Given a PSML Portlets, get the value of what its PortletConfig would be.
      
      @param entry the Portlets containing the config
      @returns the newly created PortletConfig object
      */
      protected PortletConfig getPortletConfig( Portlets portlets )
      {
          
          PortletConfig pc = new BasePortletConfig();
          pc.setName( portlets.getName() );
          pc.setInitParameters( getParameters( portlets ) );
          
          if (portlets.getSkin()!=null)
          {
              pc.setPortletSkin( getSkin( portlets.getSkin() ) );
          }
          
          pc.setMetainfo( getMetaData( portlets ) );
          
          return pc;
      }
      
      /**
       * Fetches the parameters out of a PSML Portlets entry
       *
       * @param portlets the Portlets entry to check for parameters
       * @returns a Map containing the parameters names/values, an empty Dictionary 
       *        is returned if there are no parameters
       */
      protected static Map getParameters( Portlets portlets )
      {
          Hashtable hash = new Hashtable();
          
          if (portlets != null)
          {
              Parameter[] props = portlets.getParameter();
          
              for(int i = 0; i < props.length; ++i)
              {
                  hash.put(props[i].getName(), props[i].getValue() );
              }
          }
          
          return hash;
      }
  
      /**
       * Retrieves the parameters from a PSML Control object
       *
       * @param control the PSML object to explore
       * @return a Map of the existing control parameters or an empty map
       */
      protected static Map getParameters(Control control)
      {
          Hashtable hash = new Hashtable();
  
          if (control!=null)
          {
              Parameter[] params = control.getParameter();
  
              for (int i=0; i < params.length; i++ )
              {
                  hash.put(params[i].getName(),params[i].getValue());
              }
          }
          return hash;
      }
  
      /**
       * Retrieves the parameters from a PSML Controller object
       *
       * @param controller the PSML object to explore
       * @return a Map of the existing controller parameters or an empty map
       */
      protected static Map getParameters(Controller controller)
      {
          Hashtable hash = new Hashtable();
  
          if (controller!=null)
          {
              Parameter[] params = controller.getParameter();
  
              for (int i=0; i < params.length; i++ )
              {
                  hash.put(params[i].getName(),params[i].getValue());
              }
          }
          return hash;
      }
      
      /**
       * Retrieves a parameter Map from an array of PSML Layout object
       * 
       * @param layout the Layout object to use
       * @return a Map containing the names/values, an empty map
       *  is returned if there are no properties
       */
      protected static Map getParameters(Layout layout)
      {
          Hashtable hash = new Hashtable();
  
          if (layout!=null)
          {
              Property[] props = layout.getProperty();
              
              for(int i = 0; i < props.length; ++i)
              {
                  hash.put(props[i].getName(), props[i].getValue() );
              }
          }
          
          return hash;
      }    
  
      /**
       * Retrieves a parameter Map from a PSML skin object
       * 
       * @param skin the Skin object to use
       * @return a Map containing the names/values, an empty map
       *  is returned if there are no properties
       */
      protected static Map getParameters(Skin skin)
      {
          Hashtable hash = new Hashtable();
  
          if (skin!=null)
          {
              Property[] props = skin.getProperty();
              
              for(int i = 0; i < props.length; ++i)
              {
                  hash.put(props[i].getName(), props[i].getValue() );
              }
          }
          
          return hash;
      }    
  
      /**
      Create a MetaData object from a PSML Metainfo object
      
      @param meta the Metainfo to copy
  
      @returns the new MetaData object, empty if meta is null
      */
      protected static MetaData getMetaData(Portlets portlets)
      {
          MetaData data = new MetaData();
          Metainfo meta = portlets.getMetainfo();
  
          if ( meta != null )
          {
              if ( meta.getTitle() != null )
              {
                  data.setTitle( meta.getTitle() );
              }
  
              if ( meta.getDescription() != null )
              {
                  data.setDescription( meta.getDescription() );
              }
  
              if ( meta.getImage() != null )
              {
                  data.setImage( meta.getImage() );
              }
          }
  
          return data;
  
      }
  
      /**
       * Get the position value in a Layout object
       *
       * @param layout the Layout object to use
       *
       * @return the defined position or -1 if undefined
       */
      protected static int getPosition(Layout layout)
      {
          int pos=-1;
          
          try {
              pos=Integer.parseInt(layout.getPosition());
          } catch (RuntimeException e) {
              // either layout is null or the position isn't an integer
              // keep the default value
          }
          
          return pos;
      }
  
  }
  
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/portaltoolkit/PortalToolkitService.java
  
  Index: PortalToolkitService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.portaltoolkit;
  
  //jetspeed stuff
  import org.apache.jetspeed.portal.PortletSet;
  import org.apache.jetspeed.portal.PortletSkin;
  import org.apache.jetspeed.portal.PortletControl;
  import org.apache.jetspeed.portal.PortletController;
  import org.apache.jetspeed.xml.api.portletmarkup.Control;
  import org.apache.jetspeed.xml.api.portletmarkup.Controller;
  import org.apache.jetspeed.xml.api.portletmarkup.Portlets;
  import org.apache.jetspeed.xml.api.portletmarkup.Skin;
  import org.apache.turbine.services.Service;
   
  /**
   * This service is a Factory for creating new Portal objects from
   * named Registry entries or PSML configuration entries.
   * It handles all the portal specific objects except Portlet which are 
   * handled by a separate PortletFactory service
   * 
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: PortalToolkitService.java,v 1.1 2001/06/04 17:30:36 raphael Exp $
   */
  public interface PortalToolkitService extends Service
  {
  
      /** The default control to use when none is specified */
      public String SERVICE_NAME = "PortalToolkit";
              
      /**
       * Instanciates a PortletControl based on a Registry entry, if available 
       * or directly from a classname.
       *
       * @param name a PortletControl name available in the registry or a classname
       * @return the created PortletControl
       */
      public PortletControl getControl( String name );
  
      /**
       * Instanciates a PortletControl based on a PSML Control object
       *
       * @param control the PSML control object
       * @return the created PortletControl
       */
      public PortletControl getControl( Control control );
  
      /**
       * Instanciates a PortletController based on a Registry entry, if available 
       * or directly from a classname.
       *
       * @param name a PortletController name available in the registry or a classname
       * @return the created PortletController
       */
      public PortletController getController( String name );
  
      /**
       * Instanciates a PortletController based on a PSML Controller object
       *
       * @param control the PSML controller object
       * @return the created PortletController
       */
      public PortletController getController( Controller controller );
  
      /**
       * Create a PortletSkin object based on a Registry entry if available
       *
       * @param name the skin name in the Registry
       * @return the new PortletSkin object
       */
      public PortletSkin getSkin( String name );
  
      /**
       * Create a PortletSkin object based on PSML skin description
       *
       * @param skin the PSML Skin object
       * @return the new PortletSkin object
       */
      public PortletSkin getSkin( Skin skin );
  
      /**
       * Creates a PortletSet from a PSML portlets description
       *
       * @param portlets the PSML portlet set description
       * @return a new instance of PortletSet
       */
      public PortletSet getSet( Portlets portlets );
  }
  
  
  
  
  1.3       +6 -3      jakarta-jetspeed/src/java/org/apache/jetspeed/services/portletcache/Cacheable.java
  
  Index: Cacheable.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/portletcache/Cacheable.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Cacheable.java	2001/03/07 06:48:48	1.2
  +++ Cacheable.java	2001/06/04 17:30:37	1.3
  @@ -63,10 +63,11 @@
    * that will uniquely identify it within the cache system</p>
    *
    * @author <a href="mailto:burton@apache.org">Kevin A. Burton</a>
  - * @version $Id: Cacheable.java,v 1.2 2001/03/07 06:48:48 taylor Exp $
  + * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
  + * @version $Id: Cacheable.java,v 1.3 2001/06/04 17:30:37 raphael Exp $
    */
  -public interface Cacheable {
  -
  +public interface Cacheable
  +{
       /**
       Return true if this Cacheable is allowed to be cached.  
       */
  @@ -89,6 +90,7 @@
       
       <p>Most implementations should just call the CacheHandleManager with
       the given params within the implementation and just return this.</p>
  +    * @deprecated cacheable classes should now implement a static getHandle(config) method
       */
       public String getHandle();
   
  @@ -97,6 +99,7 @@
       
       <p>Note that factories should call setHandle() so that getHandle() always
       returns a value correctly.</p>
  +    * @deprecated cacheable classes should now implement a static getHandle(config) method
       */
       public void setHandle( String handle );
     
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/portletfactory/JetspeedPortletFactoryService.java
  
  Index: JetspeedPortletFactoryService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.portletfactory;
  
  //jetspeed stuff
  import org.apache.jetspeed.portal.Portlet;
  import org.apache.jetspeed.portal.PortletConfig;
  import org.apache.jetspeed.portal.PortletException;
  import org.apache.jetspeed.portal.BasePortletConfig;
  import org.apache.jetspeed.xml.api.portletmarkup.Entry;
  import org.apache.jetspeed.xml.api.portletmarkup.Parameter;
  import org.apache.jetspeed.xml.api.portletmarkup.Metainfo;
  import org.apache.jetspeed.services.Registry;
  import org.apache.jetspeed.services.PortalToolkit;
  import org.apache.jetspeed.services.portletcache.PortletCache;
  import org.apache.jetspeed.services.portletcache.Cacheable;
  import org.apache.jetspeed.om.newregistry.PortletEntry;
  import org.apache.jetspeed.om.newregistry.SkinEntry;
  import org.apache.jetspeed.util.MetaData;
  import org.apache.jetspeed.util.JetspeedException;
  
  import org.apache.turbine.services.TurbineServices;
  import org.apache.turbine.services.TurbineBaseService;
  import org.apache.turbine.services.InitializationException;
  import org.apache.turbine.services.resources.ResourceService;
  import org.apache.turbine.util.Log;
  
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Map;
  import java.util.HashMap;
  import javax.servlet.ServletConfig;
  
  /**
   * Simple implementation of the PortalFactoryService.
   * 
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: JetspeedPortletFactoryService.java,v 1.1 2001/06/04 17:30:39 raphael Exp $
   */
  public class JetspeedPortletFactoryService extends TurbineBaseService
      implements PortletFactoryService
  {
  
      /** The default control to use when none is specified */
      private boolean enableCache = false;
  
      /**
       * This is the early initialization method called by the 
       * Turbine <code>Service</code> framework
       */
      public void init( ServletConfig conf ) throws InitializationException
      {
  
          ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
                                                       .getResources(PortletFactoryService.SERVICE_NAME);
  
          this.enableCache = serviceConf.getBoolean("enable.cache",true);
          
          setInit(true);
  
      }
              
      /**
       * Given a PSML Entry return an instanciated Portlet.
       *
       * @param entry a PSML Entry describing a portlet
       * @return an instanciated portlet corresponding to this entry
       */
      public Portlet getPortlet( Entry entry ) throws PortletException
      {
          PortletEntry regEntry = (PortletEntry)Registry.getEntry(Registry.PORTLET, 
                                                                  entry.getParent() );
          if (regEntry == null)
          {
              throw new PortletException("PortletFactory: unknown portlet entry in Registry: "+entry.getParent());
          }
          
          if (PortletEntry.TYPE_ABSTRACT.equals(regEntry.getType()))
          {
              throw new PortletException("PortletFactory: can't instanciate abstract registry entry: "+regEntry.getName());
          }
              
          PortletConfig pc = getPortletConfig(regEntry);
          
          pc.getInitParameters().putAll(getParameters(entry));
          
          pc.setPortletSkin( PortalToolkit.getSkin( entry.getSkin() ) );
          
          return getPortlet( regEntry.getClassname(), pc );
      }
  
      /**
       * Given a Portlet registry entry name, instanciate it
       *
       * @param name the name of a portlet in the registry
       * @return an instanciated portlet corresponding to this entry
       */
      public Portlet getPortlet( String name ) throws PortletException
      {
          PortletEntry regEntry = (PortletEntry)Registry.getEntry(Registry.PORTLET, name );
  
          if (regEntry == null)
          {
              throw new PortletException("PortletFactory: unknown portlet entry in Registry: "+name);
          }
          
          if (PortletEntry.TYPE_ABSTRACT.equals(regEntry.getType()))
          {
              throw new PortletException("PortletFactory: can't instanciate abstract registry entry: "+name);
          }
              
          PortletConfig pc = getPortletConfig(regEntry);
          
          return getPortlet( regEntry.getClassname(), pc );
      }
      
      /** 
       * Instanciates or retrieve from memory cache a portlet corresponding to the 
       * passed parameters
       *
       * @param classname the classname of the portlet to instanciate
       * @param pc the PortletConfig object to be associated with this object
       * @return the Portlet created or retrieve from cache
       */
      protected Portlet getPortlet( String classname, PortletConfig pc )
          throws PortletException
      {
  
          //record the begining of the portlet creation
          long begin = System.currentTimeMillis();
  
          Portlet portlet = null;
          Class portletClass = null;
          String handle = null;
          
          try
          {
              portletClass = Class.forName(classname);
          }
          catch (Exception e)
          {
              throw new PortletException( "PortletFactory: Unable to load class " + classname );
          }
          
          if (enableCache)
          {
              try
              {
                  // try to invoke a static getHandle() for this class
                  Class[] signatureParams = { Object.class };
                  Object[] methodParams = { pc };
                  handle = (String)portletClass.getMethod("getHandle",signatureParams)
                                               .invoke(null,methodParams);
                  // make sure the handle is differenciated by class
                  handle = String.valueOf(classname.hashCode())+handle;
              }
              catch (NoSuchMethodException e)
              {
                  // ignore, this simply means the portlet is not cacheable
              }
              catch (Exception e)
              {
                  // invocation failed or security exception, in both case
                  // log the error and treat the class as non cacheable
                  Log.error("PortletFactory: failed to get cache handle",e);
              }
          }
          
          try {
  
              if (enableCache && (handle != null))
              {
                  portlet = (Portlet)PortletCache.getCacheable( handle );
  
                  //portlet in cache but expired, remove it from cache
                  if ((portlet!=null) && ((Cacheable)portlet).getExpire().isExpired() )
                  {
                      Log.note( "The portlet (" + handle + ") is expired" );
                      PortletCache.removeCacheable(handle);
                      portlet = null;
                  }
              }
  
              // we found a portlet in the cache
              if ( (portlet != null)
                   && ( portlet instanceof Cacheable )
                   && (! ((Cacheable)portlet).getExpire().isExpired()) )
              {
                  // set the new context for this portlet
                  // the layout contraints will be reset when it gets added to
                  // a portlet set, based on the PSML markup
                  PortletConfig conf = portlet.getPortletConfig();
  
                  //FIXME: we now avoid to override metainfo when nothing is set
                  //in the markup, so that cached portlets can keep their metainfo
                  //This may lead to an incorrect metainfo retrieved if the first
                  //instance of the portlet, which is put in the cache, has some
                  //special metainfo defined in the markup 
  
                  MetaData meta = pc.getMetainfo();
                  
                  if ( meta != null)
                  {
  
                      if (! MetaData.DEFAULT_TITLE.equals( meta.getTitle() ) )
                      {
                          portlet.setTitle( meta.getTitle() );
                      }
      
                      if (! MetaData.DEFAULT_DESCRIPTION.equals( meta.getDescription() ) )
                      {
                          portlet.setDescription( meta.getDescription() );
                      }
                  }
                      
                  conf.setPortletSkin( pc.getPortletSkin() );
                  return portlet;
                  
              }
  
              // if not found in the cache, instanciate a new Portlet
              portlet = (Portlet)portletClass.newInstance();
  
          }
          catch ( Throwable t )
          {
              Log.error( t );
              throw new PortletException( t.getMessage() );
          }
  
          // save the current meta-info
          String title = null;
          String description = null;
          MetaData metainfo = pc.getMetainfo();
          
          if ( metainfo != null ) {
              title=metainfo.getTitle();
              description=metainfo.getDescription();
          }
          
          
          // init the portlet, it may override its PSML defined markup if
          // it doesn't check for it
          portlet.setName( pc.getName() );
          portlet.setPortletConfig( pc );
          portlet.setCreationTime( System.currentTimeMillis() );
          portlet.init();
  
          //force the title and description from markup metadata
          //in case the portlet overwrote some values
  
          if ( metainfo != null)
          {
              if (!MetaData.DEFAULT_TITLE.equals(title) )
              {
                  portlet.setTitle( title );
              }
  
              if (!MetaData.DEFAULT_DESCRIPTION.equals(description) )
              {
                  portlet.setDescription( description );
              }
          }
  
          if (enableCache && (portlet instanceof Cacheable))
          {
              //place this portlet in a cache...
              ((Cacheable)portlet).setHandle( handle );
              PortletCache.addCacheable( ((Cacheable)portlet) );
          }
  
          //now compute the time it took to instantate and log it...
          // time in millis, sugested by Thomas Schaeck (schaeck@de.ibm.com)
          long milliseconds = ( System.currentTimeMillis() - begin );
  
          Log.debug( "PortletFactory.getPortlet(): took a total of " + milliseconds + " millisecond(s) -> " + handle );
  
          return portlet;
      }
  
      /**
      Given a PSML Entry, get the value of what its PortletConfig would be.
      
      @param entry the PSML Entry containing the config
      @returns the newly created PortletConfig object
      */
      protected PortletConfig getPortletConfig( PortletEntry entry )
      {
          Map map = new HashMap();
          map.putAll(entry.getParameterMap());
          
          PortletConfig pc = new BasePortletConfig();
          pc.setName( entry.getName() );        
          pc.setInitParameters( map );
          pc.setMetainfo( getMetaData( entry ) );
          pc.setURL( entry.getURL() );
          
          return pc;
      }
      
      
      /**
       * Fetches the parameters out of a PSML Entry
       * 
       * @param entry the Entry to check for parameters
       * @returns a Map containing the parameters names/values, an empty Map 
       *         is returned if there are no parameters
       */
      protected static Map getParameters( Entry entry )
      {
          Hashtable hash = new Hashtable();
          
          Parameter[] props = entry.getParameter();
          
          for(int i = 0; i < props.length; ++i)
          {
              hash.put(props[i].getName(), props[i].getValue() );
          }
          
          return hash;
      }
  
      /**
      Create a MetaData object from a PSML Metainfo object
      
      @param meta the Metainfo to copy
  
      @returns the new MetaData object, empty if meta is null
      */
      protected static MetaData getMetaData(Entry entry)
      {
          MetaData data = new MetaData();
          Metainfo meta = entry.getMetainfo();
  
          if ( meta != null )
          {
              if ( meta.getTitle() != null )
                  data.setTitle( meta.getTitle() );
  
              if ( meta.getDescription() != null )
                  data.setDescription( meta.getDescription() );
  
              if ( meta.getImage() != null )
                  data.setImage( meta.getImage() );
          }
  
          if ( entry.getParent() != null )
          {
  
              PortletEntry parent = (PortletEntry)Registry
                  .getEntry( Registry.PORTLET, entry.getParent() );
  
              if (parent != null)
              {
                  MetaData parentData = getMetaData( parent );
                  parentData.merge(data);
                  return parentData;
              }
              
          }
  
          return data;
  
      }
  
      /**
      Create a MetaData object from a registry Metainfo object
      
      @param meta the Metainfo to copy
  
      @returns the new MetaData object, empty if meta is null
      */
      protected static MetaData getMetaData(PortletEntry entry)
      {
          MetaData data = new MetaData();
  
          if ( entry.getTitle() != null )
              data.setTitle( entry.getTitle() );
  
          if ( entry.getDescription() != null )
              data.setDescription( entry.getDescription() );
  
          return data;
      }
  
  }
  
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/portletfactory/PortletFactoryService.java
  
  Index: PortletFactoryService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.portletfactory;
  
  //jetspeed stuff
  import org.apache.jetspeed.portal.Portlet;
  import org.apache.jetspeed.portal.PortletException;
  import org.apache.jetspeed.xml.api.portletmarkup.Entry;
  import org.apache.turbine.services.Service;
   
  /**
   * This service handles the creation of Portlet objects
   * 
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: PortletFactoryService.java,v 1.1 2001/06/04 17:30:39 raphael Exp $
   */
  public interface PortletFactoryService extends Service
  {
  
      /** The default control to use when none is specified */
      public String SERVICE_NAME = "PortletFactory";
              
      /**
       * Given a PSML Entry return an instanciated Portlet.
       *
       * @param entry a PSML Entry describing a portlet
       * @return an instanciated portlet corresponding to this entry
       */
      public Portlet getPortlet( Entry entry ) throws PortletException;
  
      /**
       * Given a Portlet registry entry name, instanciate it
       *
       * @param name the name of a portlet in the registry
       * @return an instanciated portlet corresponding to this entry
       */
      public Portlet getPortlet( String name ) throws PortletException;
  }
  
  
  
  
  1.4       +2 -2      jakarta-jetspeed/src/java/org/apache/jetspeed/services/profiler/JetspeedProfilerService.java
  
  Index: JetspeedProfilerService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/profiler/JetspeedProfilerService.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- JetspeedProfilerService.java	2001/06/04 07:14:37	1.3
  +++ JetspeedProfilerService.java	2001/06/04 17:30:41	1.4
  @@ -108,7 +108,7 @@
    *
    * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>
    * @author <a href="mailto:sgala@hisitech.com">Santiago Gala</a>
  - * @version $Id: JetspeedProfilerService.java,v 1.3 2001/06/04 07:14:37 taylor Exp $
  + * @version $Id: JetspeedProfilerService.java,v 1.4 2001/06/04 17:30:41 raphael Exp $
    */
   
   public class JetspeedProfilerService  extends TurbineBaseService
  @@ -429,7 +429,7 @@
        * @parameter rundata, the <code>RunData</code> turbine request context information
        * @param cm the <code>CapabilityMap</code> of the current requesting device
        */
  -    private Profile getResourceURL(RunData rundata, CapabilityMap cm, boolean fallback)
  +    protected Profile getResourceURL(RunData rundata, CapabilityMap cm, boolean fallback)
           throws ProfileException
       {
           // get the media type from the capability map or rundata
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/CastorPsmlManagerService.java
  
  Index: CastorPsmlManagerService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.psmlmanager;
  
  //Jetspeed stuff
  import org.apache.jetspeed.cache.disk.JetspeedDiskCache;
  
  //Castor defined API
  import org.apache.jetspeed.xml.api.portletmarkup.Portlets;
  import org.apache.jetspeed.om.profile.PSMLDocument;
  import org.apache.jetspeed.om.profile.BasePSMLDocument;
  
  //turbine stuff
  import org.apache.turbine.util.Log;
  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;
  
  //castor support
  import org.exolab.castor.xml.MarshalException;
  import org.exolab.castor.xml.ValidationException;
  
  // 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.FileWriter;
  import java.io.IOException;
  import java.net.URL;
  import java.util.Date;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.HashMap;
  import java.lang.ref.WeakReference;
  import javax.servlet.ServletConfig;
  
  /**
   * This service is responsible for loading and saving PSML documents.
   *
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: CastorPsmlManagerService.java,v 1.1 2001/06/04 17:30:43 raphael Exp $
   */
  public class CastorPsmlManagerService extends TurbineBaseService
      implements PsmlManagerService
  {
  
      /** The documents loaded by this manager */
      private Map documents = new HashMap();
      
      /** The watcher for the document locations */
      private DocumentWatcher watcher = null;
      
      /** the output format for pretty printing when saving registries */
      private OutputFormat format = null;
          
      /** the base refresh rate for documents */
      private long scanRate = 1000 * 60;
          
      /**
       * This is the early initialization method called by the 
       * Turbine <code>Service</code> framework
       */
      public void init( ServletConfig conf ) throws InitializationException
      {
          ResourceService serviceConf = ((TurbineServices)TurbineServices.getInstance())
                                                       .getResources(PsmlManagerService.SERVICE_NAME);
              
          // create the serializer output format        
          this.format = new OutputFormat();
          format.setIndenting(true);
          format.setIndent(4);
  
          this.watcher = new DocumentWatcher();
          this.watcher.start();
  
          //Mark that we are done
          setInit(true);
      }
  
  
      /** Late init method from Turbine Service model */
      public void init( ) throws InitializationException
      {
          while( !getInit() )
          {
              //Not yet...
              try
              {
                  Thread.sleep( 500 );
              }
              catch (InterruptedException ie )
              {
                  Log.error( ie );
              }
          }
      }
  
      
      /**
       * This is the shutdown method called by the 
       * Turbine <code>Service</code> framework
       */
      public void shutdown()
      {
          this.watcher.setDone(true);
      }
  
      /**
       * Returns a PSML document of the given name.
       * For this implementation, the name must be the document
       * URL or absolute filepath
       *
       * @param name the name of the document to retrieve
       */
      public PSMLDocument getDocument( String name )
      {
          if (name == null)
          {
              String message = "PSMLManager: Must specify a name";
              Log.error( message );
              throw new IllegalArgumentException( message );
          }
          
          PSMLDocument doc = null;
          WeakReference ref = null;
  
          synchronized (documents)
          {
              ref = (WeakReference)documents.get(name);
          }
          
          if (ref != null)
          {
              doc = (PSMLDocument)ref.get();
          }
          
          if (doc == null)
          {
              doc = loadDocument(name);
  
              synchronized (documents)
              {
                  // store the document in the hash and reference it to the watcher
                  documents.put(name, new WeakReference(doc));
              }
          }
  
          return doc;
      }
  
      /** 
       * Load a PSMLDOcument from disk
       *
       * @param fileOrUrl a String representing either an absolute URL or an
       * absolute filepath
       */
      public PSMLDocument loadDocument(String fileOrUrl)
      {
          PSMLDocument doc = new BasePSMLDocument();
          doc.setName(fileOrUrl);
  
          if (fileOrUrl!=null)
          {
              
              // load the document and add it to the watcher
              // we'll assume the name is the the location of the file
              
              File f = getFile(fileOrUrl);
  
              // now that we have a file reference, try to load the serialized PSML
              Portlets portlets = null;
              FileReader reader = null;
              try
              {
                  reader = new FileReader(f);
                  
                  portlets = load(reader);
                  
                  doc.setPortlets(portlets);
  
                  this.watcher.addFile(fileOrUrl,f);
              }
              catch (IOException e)
              {
                  Log.error("PSMLManager: Could not load the file "+f.getAbsolutePath(), e);
              }
              catch (MarshalException e)
              {
                  Log.error("PSMLManager: Could not unmarshal the file "+f.getAbsolutePath(), e);
              }
              catch (ValidationException e)
              {
                  Log.error("PSMLManager: document "+f.getAbsolutePath()+" is not valid", e);
              }
              finally
              {
                  try { reader.close(); } catch (IOException e) {}
              }
          }
          
          return doc;
      }
      
      /** Refresh a named document
       * 
       * @param name the name of the document to refresh
       */
      public void refresh(String name) throws IOException
      {
          PSMLDocument doc = null;
          WeakReference ref = null;
  
          synchronized (documents)
          {
              ref = (WeakReference)documents.get(name);
          }
          
          if (ref != null)
          {
              doc = (PSMLDocument)ref.get();
  
              if (doc!=null)
              {
                  File f = getFile(name);
                  FileReader reader = null;
                  try
                  {
                      reader = new FileReader(f);
                      doc.setPortlets(load(reader));
                  }
                  catch (Exception e)
                  {
                      Log.error("Error refrshing "+f.getAbsolutePath(),e);
                  }
                  finally
                  {
                      try { reader.close(); } catch (Exception e) {}
                  }
                  return;
              }
              else
              {
                  // make sure the bogus key is removed
                  synchronized (documents)
                  {
                      documents.remove(name);
                  }
              }
          }
          
          // we don't know anything about this document, load it normally
          getDocument(name);
      }
      
      /** Save the PSML document on disk, using its name as filepath
       * 
       * @param doc the document to save
       */
      public boolean saveDocument(PSMLDocument doc)
      {
          return saveDocument(doc.getName(), doc);
      }
      
      /** Save the PSML document on disk to the specififed fileOrUrl
       * 
       * @param fileOrUrl a String representing either an absolute URL
       * or an absolute filepath
       * @param doc the document to save
       */
      public boolean saveDocument(String fileOrUrl, PSMLDocument doc)
      {
          boolean success = false;
          
          if (doc == null) return false;
          
          File f = getFile(fileOrUrl);
          FileWriter writer = null;
  
          try
          {
              writer = new FileWriter(f);
              save(writer, doc.getPortlets());
              success = true;
          }
          catch (MarshalException e)
          {
              Log.error("PSMLManager: Could not marshal the file "+f.getAbsolutePath(), e);
          }
          catch (ValidationException e)
          {
              Log.error("PSMLManager: document "+f.getAbsolutePath()+" is not valid", e);
          }
          catch (IOException e)
          {
              Log.error("PSMLManager: Could not save the file "+f.getAbsolutePath(), e);
          }
          catch (Exception e)
          {
              Log.error("PSMLManager: Error while saving  "+f.getAbsolutePath(), e);
          }
          finally
          {
              try { writer.close(); } catch (IOException e) {}
          }   
          
          return success;
      }
      
      /** Deserializes a PSML structure read from the reader using Castor
       *  XML unmarshaller
       *
       * @param reader the reader to load the PSML from
       * @param the loaded portlets structure or null
       */
      protected Portlets load(Reader reader)
          throws IOException, MarshalException, ValidationException
      {
          return Portlets.unmarshal(reader);        
      }
      
      /** Serializes a PSML structure using the specified writer with Castor
       *  XML marshaller and a Xerces serializer for pretty printing
       *
       * @param writer the writer to use for serialization
       * @param portlets the structure to save
       */
      protected void save(Writer writer, Portlets portlets)
          throws IOException, MarshalException, ValidationException
      {
          if (portlets != null)
          {
              Serializer serializer = new XMLSerializer(writer, format); 
              portlets.marshal(serializer.asDocumentHandler());
          }        
      }
  
      /** Tests wether the passed argument is an URL string or a file name
       *  and returns the corresponding file object, using diskcache for
       *  remote URLs
       *
       *  @param fileOrUrl the URL string or file path
       *  @return a File object. This file may not exist on disk.
       */
      protected File getFile(String fileOrUrl)
      {
          File f = null;
  
          try
          {
              //FIXME: this will fail for relative URLs, should we
              //support them ?
              URL url = new URL(fileOrUrl);
                  
              // ok it's an URL, use diskcache and get the file name 
              // through the cache
                  
              f = JetspeedDiskCache.getInstance().getEntry(fileOrUrl).getFile();
                  
          }
          catch (IOException e)
          {
              Log.note("PSMLManager: "+fileOrUrl+" is not a URL or not in cache, trying as file");
              f = new File(fileOrUrl);
          }
          
          return f;
      }    
      
      protected class DocumentWatcher extends Thread
      {
          private Map fileToName = new HashMap();
          private Map fileToDate = new HashMap();
          private boolean done = false;
          
          protected DocumentWatcher()
          {
              setDaemon(true);
              setPriority(Thread.MIN_PRIORITY+1);
          }
          
          protected void addFile(String name, File f)
          {
              synchronized (this)
              {
                  fileToName.put(f, name);
                  fileToDate.put(f, new Date());
              }
          }
          
          protected void removeFile(File f)
          {
              synchronized (this)
              {
                  fileToName.remove(f);
                  fileToDate.remove(f);
              }
          }
          
          public void setDone(boolean done)
          {
              this.done = done;
          }
          
          public void run()
          {
              try
              {
                  while(!done)
                  {
                      try
                      {
                          Iterator i = fileToDate.keySet().iterator();
                      
                          while(i.hasNext())
                          {
                              File f = (File)i.next();
                              Date modified = new Date(f.lastModified());
  
                              synchronized (this)
                              {
                                  if ( modified.after((Date)fileToDate.get(f)) )
                                  {
                                      CastorPsmlManagerService.
                                          this.refresh((String)fileToName.get(f));
                                      fileToDate.put(f,modified);
                                  }
                              }
                          }
                      }
                      catch (Exception e)
                      {
                          Log.error("DocumentWatcher: Error in iteration...", e);
                      }
                      
                      sleep(CastorPsmlManagerService.this.scanRate);
                  }
              }
              catch (InterruptedException e)
              {
                  Log.note("DocumentWatcher: recieved interruption, aborting.");
              }
          }
          
      }
  }
  
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/PsmlManagerService.java
  
  Index: PsmlManagerService.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *     "Apache Jetspeed" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache" or
   *    "Apache Jetspeed", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.jetspeed.services.psmlmanager;
  
  import org.apache.turbine.services.Service;
  import org.apache.jetspeed.om.profile.PSMLDocument;
  
  /**
   * This service is responsible for loading and saving PSML documents.
   *
   * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
   * @version $Id: PsmlManagerService.java,v 1.1 2001/06/04 17:30:43 raphael Exp $
   */
  public interface PsmlManagerService extends Service
  {
  
      /** The name of the service */
      public String SERVICE_NAME = "PsmlManager";
  
      /**
       * Returns a PSML document of the given name.
       * For this implementation, the name must be the document
       * URL or absolute filepath
       *
       * @param name the name of the document to retrieve
       */
      public PSMLDocument getDocument( String name );
  
      /** Save the PSML document on disk, using its name as filepath
       * 
       * @param doc the document to save
       * @return true if the operation succeeded
       */
      public boolean saveDocument(PSMLDocument doc);
      
      /** Save the PSML document on disk to the specififed fileOrUrl
       * 
       * @param fileOrUrl a String representing either an absolute URL
       * or an absolute filepath
       * @param doc the document to save
       * @return true if the operation succeeded
       */
      public boolean saveDocument(String fileOrUrl, PSMLDocument doc);
  }
  
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: jetspeed-dev-help@jakarta.apache.org