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 ta...@apache.org on 2001/11/12 04:40:29 UTC

cvs commit: jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/db DBOperations.java DBUtils.java DatabaseInitializer.java DatabasePsmlManagerService.java

taylor      01/11/11 19:40:29

  Modified:    src/java/org/apache/jetspeed/services PsmlManager.java
               src/java/org/apache/jetspeed/services/psmlmanager
                        CastorPsmlManagerService.java
                        PsmlManagerService.java
  Added:       src/java/org/apache/jetspeed/services/psmlmanager/db
                        DBOperations.java DBUtils.java
                        DatabaseInitializer.java
                        DatabasePsmlManagerService.java
  Log:
  - Changed interface for 'store' on PsmlManager to take a Profile interface
  - added new DatabasePsmlManagerService ** warning ** it isn't quite working yet, almost there...
  - fixed bug in CastorPsmlManagerService.query to correctly return users/roles/groups
  
  Revision  Changes    Path
  1.6       +13 -3     jakarta-jetspeed/src/java/org/apache/jetspeed/services/PsmlManager.java
  
  Index: PsmlManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/PsmlManager.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- PsmlManager.java	2001/07/30 03:50:07	1.5
  +++ PsmlManager.java	2001/11/12 03:40:24	1.6
  @@ -71,7 +71,7 @@
    * Static accessor for the PsmlManagerService
    *
    * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
  - * @version $Id: PsmlManager.java,v 1.5 2001/07/30 03:50:07 taylor Exp $
  + * @version $Id: PsmlManager.java,v 1.6 2001/11/12 03:40:24 taylor Exp $
    */
   public class PsmlManager
   {
  @@ -121,8 +121,18 @@
           return getService().getDocument(locators);
       }
   
  -    /** Save the PSML document on disk, using its name as filepath
  +    /** Store the PSML document on disk, using its locator
        * 
  +     * @param profile the profile locator description.
  +     * @return true if the operation succeeded
  +     */
  +    public static boolean store(Profile profile)
  +    {
  +        return getService().store(profile);
  +    }
  +
  +    /** Save the PSML document on disk, using its name as filepath
  +     * @deprecated
        * @param doc the document to save
        */
       public static boolean saveDocument(PSMLDocument doc)
  @@ -131,7 +141,7 @@
       }
       
       /** Save the PSML document on disk to the specififed fileOrUrl
  -     * 
  +     * @deprecated
        * @param fileOrUrl a String representing either an absolute URL
        * or an absolute filepath
        * @param doc the document to save
  
  
  
  1.11      +40 -10    jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/CastorPsmlManagerService.java
  
  Index: CastorPsmlManagerService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/CastorPsmlManagerService.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- CastorPsmlManagerService.java	2001/09/13 06:24:05	1.10
  +++ CastorPsmlManagerService.java	2001/11/12 03:40:25	1.11
  @@ -76,6 +76,10 @@
   import org.apache.turbine.om.security.User;
   import org.apache.turbine.om.security.Role;
   import org.apache.turbine.om.security.Group;
  +import org.apache.turbine.om.security.TurbineUser;
  +import org.apache.turbine.om.security.TurbineRole;
  +import org.apache.turbine.om.security.TurbineGroup;
  +
   //castor support
   import org.exolab.castor.xml.MarshalException;
   import org.exolab.castor.xml.ValidationException;
  @@ -108,7 +112,7 @@
    * @author <a href="mailto:raphael@apache.org">Rapha�l Luta</a>
    * @author <a href="mailto:taylor@apache.org">David Sean Taylor</a>
    * @author <a href="mailto:sgala@apache.org">Santiago Gala</a>
  - * @version $Id: CastorPsmlManagerService.java,v 1.10 2001/09/13 06:24:05 taylor Exp $
  + * @version $Id: CastorPsmlManagerService.java,v 1.11 2001/11/12 03:40:25 taylor Exp $
    */
   public class CastorPsmlManagerService extends TurbineBaseService
       implements PsmlManagerService
  @@ -148,14 +152,14 @@
           
       /** 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
       {
  -
  +        System.out.println("in castor psml init");
           if (getInit())
           {
               return;
  @@ -192,6 +196,7 @@
   
           //Mark that we are done
           setInit(true);
  +        System.out.println("exit castor psml init");
   
           // Test
           //testCases();
  @@ -202,6 +207,8 @@
       /** Late init method from Turbine Service model */
       public void init() throws InitializationException
       {
  +        System.out.println("in late castor psml init");
  +
           while( !getInit() )
           {
               //Not yet...
  @@ -214,6 +221,7 @@
                   Log.error( ie );
               }
           }
  +        System.out.println("exit LATE castor psml init");
   
       }
   
  @@ -450,8 +458,20 @@
           getDocument(name);
       }
       
  -    /** Save the PSML document on disk, using its name as filepath
  +    /** Store the PSML document on disk, using its locator
        * 
  +     * @param profile the profile locator description.
  +     * @return true if the operation succeeded
  +     */
  +    public boolean store(Profile profile)
  +    {
  +        PSMLDocument doc = profile.getDocument();
  +        String path = mapLocatorToFile(profile);
  +        return saveDocument(path, doc);
  +    }
  +
  +    /** Save the PSML document on disk, using its name as filepath
  +     * @deprecated
        * @param doc the document to save
        */
       public boolean saveDocument(PSMLDocument doc)
  @@ -1123,9 +1143,13 @@
                           User user = qs.profile.getUser();
                           if (null == user)
                           {
  -                            user = JetspeedSecurity.getUser(dirName);
  -                            qs.clearName = true;
  +                            // warning: this ties us to turbine security
  +                            // we could load class from TRP 
  +                            // (services.SecurityService.user.class)
  +                            user = new TurbineUser();
  +                            user.setUserName(file.getName());
                               qs.profile.setUser(user);
  +                            qs.clearName = true;
                           }
                       }
                       else if (QUERY_BY_ROLE == qs.queryBy)
  @@ -1133,9 +1157,12 @@
                           Role role = qs.profile.getRole();
                           if (null == role)
                           {
  -                            role = JetspeedSecurity.getRole(dirName);
  -                            qs.clearName = true;
  +                            // warning: this ties us to turbine security
  +                            // we could load class from TRP 
  +                            // (services.SecurityService.user.class)
  +                            role = new TurbineRole(file.getName());
                               qs.profile.setRole(role);
  +                            qs.clearName = true;
                           }
                       }
                       else if (QUERY_BY_GROUP == qs.queryBy)
  @@ -1143,9 +1170,12 @@
                           Group group = qs.profile.getGroup();
                           if (null == group)
                           {
  -                            group = JetspeedSecurity.getGroup(dirName);
  -                            qs.clearName = true;
  +                            // warning: this ties us to turbine security
  +                            // we could load class from TRP 
  +                            // (services.SecurityService.user.class)
  +                            group = new TurbineGroup(file.getName());
                               qs.profile.setGroup(group);
  +                            qs.clearName = true;
                           }
                       }
                   }
  
  
  
  1.7       +11 -1     jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/PsmlManagerService.java
  
  Index: PsmlManagerService.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/PsmlManagerService.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- PsmlManagerService.java	2001/09/13 18:36:07	1.6
  +++ PsmlManagerService.java	2001/11/12 03:40:26	1.7
  @@ -64,12 +64,13 @@
   import org.apache.turbine.om.security.User;
   import org.apache.turbine.om.security.Role;
   import org.apache.turbine.om.security.Group;
  +import org.apache.turbine.services.InitializationException;
   
   /**
    * 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.6 2001/09/13 18:36:07 sgala Exp $
  + * @version $Id: PsmlManagerService.java,v 1.7 2001/11/12 03:40:26 taylor Exp $
    */
   public interface PsmlManagerService extends Service
   {
  @@ -102,8 +103,16 @@
        */
       public PSMLDocument getDocument( List locators );
   
  +    /** Store the PSML document on disk, using its locator
  +     * 
  +     * @param profile the profile locator description.
  +     * @return true if the operation succeeded
  +     */
  +    public boolean store(Profile profile);
  +
       /** Save the PSML document on disk, using its name as filepath
        * 
  +     * @deprecated
        * @param doc the document to save
        * @return true if the operation succeeded
        */
  @@ -155,6 +164,7 @@
        * @param locator The profile locator criteria.
        */
       public Iterator query( QueryLocator locator );
  +
   
   }
   
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/db/DBOperations.java
  
  Index: DBOperations.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.db;
  
  /**
   * Interface used for database various database operations in Database
   * PSML Manager implementation.
   *
   * @author <a href="mailto:adambalk@cisco.com">Atul Dambalkar</a>
   * @version 
   */
  public interface DBOperations 
  {
  
      /**
       * Variable to represent database operation insert.
       */ 
      public static final int INSERT = 1;
   
      /**
       * Variable to represent database operation update.
       */ 
      public static final int UPDATE = 2;
  
      /**
       * Variable to represent database operation update.
       */ 
      public static final int DELETE = 3;
  }
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/db/DBUtils.java
  
  Index: DBUtils.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.db;
  
  //Castor defined API
  import org.apache.jetspeed.xml.api.portletmarkup.Portlets;
   
  //turbine stuff
  import org.apache.turbine.util.Log;
  
  //castor support
  import org.exolab.castor.xml.MarshalException;
  import org.exolab.castor.xml.ValidationException;
  
  //standard java stuff
  import java.io.Reader;
  import java.io.StringReader;
  import java.io.StringWriter;
  import java.io.IOException;
  
  
  /**
   * This is a utility class used for database PSML implementation.
   *
   * @author <a href="mailto:adambalk@cisco.com">Atul Dambalkar</a>
   * @version 
   */
  public class DBUtils 
  {
  
      /** Deserialize a PSML structure read from bytes array using Castor
       *  XML unmarshaller
       *
       * @param portletBytes Bytes array to load the PSML from
       * @return PSML structure Portlets object
       */
      public static Portlets bytesToPortlets(byte[] portletBytes) 
      {
          Reader reader = new StringReader(new String(portletBytes));
          try 
          {
              return Portlets.unmarshal(reader);
          }
          catch (MarshalException e)
          {
              Log.error("PSMLManager: Could not unmarshal the inputstream ", e);
          }  
          catch (ValidationException e)
          {
              Log.error("PSMLManager: document is not valid", e);
          }
          finally
          {
              try { reader.close(); } 
              catch (IOException e) { Log.error("", e); }
          }
          return null; // control shouldn't arrive here 
      }
  
      /** Serialize a PSML structure using string writer with Castor XML 
       * marshaller, put it in bytes array and return it.
       *
       * @param portlets the structure to convert to bytes array
       * @return Bytes array object for portles
       */
      public static byte[] portletsToBytes(Portlets portlets) 
      {
          if (portlets == null)
          {
              String message = "PSMLManager: Must specify portlets";
              Log.error( message );
              throw new IllegalArgumentException( message );
          }
  
          StringWriter writer = new StringWriter();
          try 
          {
              portlets.marshal(writer);
  
              Log.debug("Portlets: " + writer.toString());
  
              /**** Platform's default character encoding will be used ****/
              return writer.toString().getBytes(); 
          }
          catch (MarshalException e)
          {
              Log.error("PSMLManager: Could not marshal the stringwriter ", e);
          }
          catch (ValidationException e)
          {
              Log.error("PSMLManager: document is not valid", e);
          }
          finally
          {
              try { writer.close(); } 
              catch (IOException e) { Log.error("", e); }
          }
          return null; // control shouldn't arrive here 
      }
  
  }
  
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/db/DatabaseInitializer.java
  
  Index: DatabaseInitializer.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.db;
  
  // PSML Manager Service interface
  import org.apache.jetspeed.services.PsmlManager;
  import org.apache.jetspeed.services.psmlmanager.PsmlManagerService;
  
  import org.apache.jetspeed.services.psmlmanager.db.DBOperations;
  
  //Jetspeed security interface
  import org.apache.jetspeed.services.JetspeedSecurity;
  import org.apache.jetspeed.services.security.JetspeedSecurityService;
  
  // Profile and ProfileLocator interface 
  import org.apache.jetspeed.om.profile.Profile;
  import org.apache.jetspeed.om.profile.BaseProfile;
  import org.apache.jetspeed.om.profile.ProfileLocator;
  import org.apache.jetspeed.om.profile.QueryLocator;
  //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;
  import org.apache.turbine.om.security.User;
  import org.apache.turbine.om.security.Group;
  import org.apache.turbine.om.security.Role;
  import org.apache.turbine.util.db.pool.DBConnection;
  import org.apache.turbine.services.db.TurbineDB; 
  import org.apache.turbine.util.security.DataBackendException; 
  import org.apache.turbine.util.security.UnknownEntityException; 
  
  
  //Servlet API
  import javax.servlet.ServletConfig;
   
  //castor support
  import org.exolab.castor.xml.MarshalException;
  import org.exolab.castor.xml.ValidationException;
  
  // Torque generated classes
  import org.apache.jetspeed.om.dbpsml.JetspeedUserProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedUserProfilePeer;
  import org.apache.jetspeed.om.dbpsml.JetspeedRoleProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedRoleProfilePeer;
  import org.apache.jetspeed.om.dbpsml.JetspeedGroupProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedGroupProfilePeer;
  import org.apache.jetspeed.om.dbpsml.JetspeedAnonProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedAnonProfilePeer;
  
  //standard java stuff
  import java.lang.Thread;
  import java.util.Iterator;
  import java.util.List;
  import java.util.ArrayList;
  import java.util.Set;
  import java.util.Vector;
  import java.util.StringTokenizer;
  import java.io.IOException;
  import java.io.File;
  import java.io.Reader;
  import java.io.FileReader;
  import java.util.Arrays;
  import java.util.Locale;
  
  
  /**
   * This service is responsible for loading and saving PSML documents. It uses
   * database to persist the PSML documents.
   *
   * @author <a href="mailto:adambalk@cisco.com">Atul Dambalkar</a>
   * @author <a href="mailto:mvaidya@cisco.com">Medha Vaidya</a>
   * @version 
   */
  public class DatabaseInitializer implements DBOperations
  {
  
      // resource path constants
      private static final String PATH_GROUP              = "group";
      private static final String PATH_ROLE               = "role";
      private static final String PATH_USER               = "user";
      private static final String PATH_ANON               = "anon";
  
      // configuration keys
      private final static String CONFIG_TEMPLATES        = "templates";
      private final static String CONFIG_EXT              = "ext";
      private final static String CONFIG_RESOURCE         = "default-resource";
      private final static String CONFIG_MEDIA_TYPES      = "media-types";
      private final static String CONFIG_ADMIN            = "admin";
  
      // default configuration values
      private final static String DEFAULT_TEMPLATES   = "/WEB-INF/psml/templates";
      private final static String DEFAULT_EXT              = ".psml";
      private final static String DEFAULT_RESOURCE         = "default.psml";
      private final static String DEFAULT_MEDIA_TYPES      = "html:wml";
      private final static String DEFAULT_ADMIN            = "admin";
  
      // resource path indicating state constants
      private static final int USER = 1;
      private static final int ROLE = 2;
      private static final int GROUP = 3;
      private static final int ANON = 4;
      private static final int LOCATOR_ENTITY = 5;
  
      // Supported media-types in Jetspeed
      List mediaTypes = new ArrayList();
      // ISO supported countries 
      List isoCountries = new ArrayList();
      // ISO supported languages 
      List isoLanguages = new ArrayList();
      // the root psml resource directory
      private String root;
      // base store directory
      private File rootDir = null;
      // file extension
      private String ext;
      // resource/profile file name
      private String resource;
      // Jetspeed administrator name
      private String admin;
  
      private PsmlManagerService psmlManager;
  
      /**
       * This is the early initialization method called by the
       * Turbine <code>Service</code> framework
       */
      public DatabaseInitializer(PsmlManagerService psmlManager,
                                 ServletConfig conf, 
                                 ResourceService serviceConf) 
                          throws InitializationException 
      {
          Log.note("Initializing DatabaseInitializer...");
  
          // Initialize PsmlManagerService  as well as Security service 
          // before this service, so that we can use both
  
          this.psmlManager = psmlManager;
  
          initConfiguration(serviceConf);
          System.out.println("-------- done initializing configuration");
  
          //If the rootDir does not exist, treat it as context relative
          this.rootDir = new File(conf.getServletContext().getRealPath(root));
          if (!rootDir.exists())
          {
              throw new InitializationException("Error during initializing DatabaseInitializationService. Could not find directory where default resources are located: " + rootDir);
          }
  
          importPSMLFiles();
  
          Log.note("Done initializing DatabaseInitializationService.");
      }
  
      /**
       * Loads the configuration parameters for this service from the
       * JetspeedResources.properties file.
       *
       * @exception throws a <code>InitializationException</code> if the service
       * fails to initialize
       */
      private void initConfiguration(ResourceService serviceConf) 
                              throws InitializationException
      {
          try
          {
              buildMediaTypes(serviceConf.getString(CONFIG_MEDIA_TYPES,
                                                    DEFAULT_MEDIA_TYPES));
              buildISOCountries();
              buildISOLanguages();
              this.ext = serviceConf.getString(CONFIG_EXT, DEFAULT_EXT);
  
              this.resource = serviceConf.getString(CONFIG_RESOURCE, 
                                                    DEFAULT_RESOURCE);
  
              this.root = serviceConf.getString(CONFIG_TEMPLATES, 
                                                DEFAULT_TEMPLATES);
  
              this.admin = serviceConf.getString(CONFIG_ADMIN, DEFAULT_ADMIN);
  
          }
          catch (Exception e)
          {
              throw new InitializationException("Exception during initializing DatabaseInitializationService, will use defaults");
          }
      }
  
      /**
       * Build media types list for the Jetspeed supported media types.
       */
      private void buildMediaTypes(String medias)
      {
          Log.note("MediaTypes found: " + medias);
          StringTokenizer tokens = new StringTokenizer(medias, ":");
          while (tokens.hasMoreTokens())
          {
              this.mediaTypes.add(tokens.nextToken().trim());
          }
          Log.note("MediaTypes: " + mediaTypes);
      }
  
      /**
       * Is media type supported by Jetspeed?
       */
      private boolean isMediaType(String str) 
      {
          return mediaTypes.contains(str);
      } 
  
      /**
       * Build countries list for ISO supported countries.
       */
      private void buildISOCountries()
      {
          String[] countries = Locale.getISOCountries();
          this.isoCountries = Arrays.asList(countries);   
      }
  
      /**
       * Build languages list for ISO supported languages.
       */
      private void buildISOLanguages()
      {
          String[] languages = Locale.getISOLanguages();
          this.isoLanguages = Arrays.asList(languages);   
      }
  
      /**
       * Returns a profile object for the given PSML file.
       *
       * @param filename The profile PSML filename  
       * @return Profile The Profile object for given PSML file
       */
      protected Profile mapFileToProfile(File file) throws InitializationException
      {
          int state = 0;
          Profile profile = null;
  
          String filePath = file.getAbsolutePath();
  
          Log.note("Returning profile for File: " + filePath); 
          
          filePath = filePath.substring(filePath.indexOf(root) + root.length()); 
          
          //Split the filepath and check if the tokens name, mediatype, 
          //country or language        
          StringTokenizer strTok = new StringTokenizer(filePath, File.separator);
          
          while (strTok.hasMoreTokens()) 
          {
              String token = strTok.nextToken();
  
              if (state != LOCATOR_ENTITY) 
              {
                 state = getState(token);
              }
  
              Log.note("Token found: " + token);
          
              switch (state)
              {
                  case USER:
  
                      // if valid user then set to profile object
                      profile = new BaseProfile();
  
                      token = strTok.nextToken();
                      Log.note("Inside user: " + token);
                      try 
                      {
                          //User user = securityService.getUser(token);
                          User user = JetspeedSecurity.getUser(token);
                          profile.setUser(user);
  
                      } 
                      catch (UnknownEntityException e) 
                      {
                          Log.error(e);
                          checkLocatorEntity(token, profile, file);
                      }
                      catch (DataBackendException exc)
                      {
                          throw new InitializationException("Error in accessing backend data!");
                      }
  
                      break;
  
                  case ROLE:
  
                      // if valid role then set to profile object
                      profile = new BaseProfile();
  
                      token = strTok.nextToken();
                
                      try 
                      {
                          //Role role = securityService.getRole(token);
                          Role role = JetspeedSecurity.getRole(token);
                          profile.setRole(role);
  
                      } catch (UnknownEntityException e) 
                      {
                          Log.error(e);
                          checkLocatorEntity(token, profile, file);
                      }
                      catch (DataBackendException exc)
                      {
                          throw new InitializationException("Error in accessing backend data!");
                      }
  
                      break;
  
                  case GROUP:
  
                      // if valid group then set to profile object
                      profile = new BaseProfile();
  
                      token = strTok.nextToken();
  
                      try 
                      {
                          //Group group = securityService.getGroup(token);
                          Group group = JetspeedSecurity.getGroup(token);
                          profile.setGroup(group);
  
                      } catch (UnknownEntityException e) 
                      {
                          Log.error(e);
                          checkLocatorEntity(token, profile, file);
                      }
                      catch (DataBackendException exc)
                      {
                          throw new InitializationException("Error in accessing backend data!");
                      }
  
                      break;
  
                  case ANON:
                      profile = new BaseProfile();
                      Log.note("In anon, dumping profile");
                      dumpProfile(profile);
                      profile.setAnonymous(true);
                      break;
  
                  case LOCATOR_ENTITY:
                      Log.note("In checked Token: " + token);
          
                      checkLocatorEntity(token, profile, file);
                      break;
  
                  default:
                      break;
                  
              } //end of switch
        
          } //end of while
         
          Log.note("Returning profile from mapFile method"); 
          dumpProfile(profile);
          return profile;
      }
  
      /**
       * Get state constants depending on resource path 
       */
      private int getState(String resourcePath) 
      {
          Log.note("Resourcepath: " + resourcePath);
  
          if (resourcePath.equals(PATH_USER)) 
          {
              Log.note("Returning: USER");
              return USER;
          } 
          else if (resourcePath.equals(PATH_ROLE)) 
          {
              Log.note("Returning: ROLE");
              return ROLE;
          }
          else if (resourcePath.equals(PATH_GROUP)) 
          {
              Log.note("Returning: GROUP");
              return GROUP;
          }
          else if (resourcePath.equals(PATH_ANON)) 
          {
              Log.note("Returning: ANON");
              return ANON;
          }
          else
          {
              return LOCATOR_ENTITY;
          }
      }
  
      /**
       * Is country name valid? 
       */
      private boolean isCountry(String str) 
      {
          return isoCountries.contains(str);
      }
                              
      /**
       * Is language name valid? 
       */
      private boolean isLanguage(String str) 
      {
          return isoLanguages.contains(str);
      }
  
      /**
       * Is valid PSML resource? 
       */
      private boolean isPSMLResource(String str) 
      {
          return (str.equals(resource));
      }
  
      /**
       * Is entity mediatype, country,language or psml file? 
       */
      private void checkLocatorEntity(String str, Profile profile, File file) 
      {
          Log.note("In checklocatorentiry: " + str);
  
          // if valid media-type 
          if (profile.getMediaType() == null && isMediaType(str)) 
          {
              Log.note("Setting mediatype");
              profile.setMediaType(str);
              return;
          } 
                          
          //check if the country name is present
          if (profile.getCountry() == null && isCountry(str)) 
          {
              Log.note("Setting country");
              profile.setCountry(str);
              return;
          }    
  
          //check if language name is present
          if (profile.getLanguage() == null && isLanguage(str)) 
          {
              Log.note("Setting language");
              profile.setLanguage(str);
              return;
          }
  
          // if not, then check if this is resource
          if (isPSMLResource(str))
          {
              Log.note("Setting page name and profile");
              profile.setName(str);
              PSMLDocument document = loadDocument(file);
              profile.setDocument(document);
              return;
          }
  
      }
  
      /** 
       * Load a PSMLDOcument from disk
       *
       * @param file a file object 
       */
      private PSMLDocument loadDocument(File file)
      {
          PSMLDocument doc = null;
  
          if (file!=null)
          {
              
              // load the document and add it to the watcher
              
              doc = new BasePSMLDocument();
              doc.setName(resource);
  
              // now that we have a file reference, try to load the serialized PSML
              Portlets portlets = null;
              FileReader reader = null;
              try
              {
                  reader = new FileReader(file);
                  
                  portlets = loadPortlet(reader);
                  
                  doc.setPortlets(portlets);
  
              }
              catch (IOException e)
              {
                  Log.error("DatabaseInitializationService: Could not load the file "+file.getAbsolutePath(), e);
              }
              catch (MarshalException e)
              {
                  Log.error("DatabaseInitializationService: Could not unmarshal the file "+file.getAbsolutePath(), e);
              }
              catch (ValidationException e)
              {
                  Log.error("DatabaseInitializationService: document "+file.getAbsolutePath()+" is not valid", e);
              }
              finally
              {
                  try { reader.close(); } catch (IOException e) {}
              }
          }
          
          return doc;
      }
  
      /** 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 loadPortlet(Reader reader)
          throws MarshalException, ValidationException
      {
          return Portlets.unmarshal(reader);        
      }
  
      /**
       * Store the PSML document in DB for the given profile. Traverse the PSML
       * directory structure and import all the found profile files into database
       * with their appropriate profile locators.
       */
      protected void importPSMLFiles() throws InitializationException 
      {
  
          // Before traversing the file system, see, if database is already 
          // initialized. Query the database 
  
          if (query()) 
          {
              return;
          }
           
          Iterator files = traverse(rootDir, new ArrayList(), new ArrayList()); 
  
          while (files.hasNext()) 
          {
              Profile profile = mapFileToProfile((File)files.next()); 
  
              dumpProfile(profile);
  
              // Create document in database
              psmlManager.createDocument(profile);
          }
      }
  
      /**
       * Traverse the file system for PSML files. Locate all the PSML files in
       * Jetspeed configuration and return a iterator for those filenames.
       *
       * @param directory Root Directory to be traversed.
       * @param filelist List to store the files. 
       * @param traversed List to store the traversed directories.
       * @return Iterator Iterator to iterate over the found profiles/psml files.
       */
      private Iterator traverse(File directory, List filelist, List traversed) 
                         throws InitializationException
      {
          try 
          {
              // mark this directory as traversed
              traversed.add(directory.getCanonicalPath());
  
              File[] files = directory.listFiles();
              for (int i = 0; i < files.length; i++) 
              {
                  File file = files[i];
                  if (file.isDirectory() 
                      && !file.getName().equals(".")  // don't traverse "."
                      && !file.getName().equals("..") // don't traverse ".."
                      && !traversed.contains(file.getCanonicalPath()) 
                                                // don't traverse soft links 
                     )
                  {
                      traverse(file, filelist, traversed);
                  }
                  else  if (file.getName().equals(resource))
                  {
                      Log.note("Adding file: " + file.getAbsolutePath());
                      filelist.add(file); 
                  }
              }
          }
          catch (IOException exc)
          {
              throw new InitializationException("Exception during traversing the directory: " + directory);
          }
          return filelist.iterator();
      }
  
      // The logic of checking "admin" can be changed to search all the records 
      // in a particular table
      private boolean query() throws InitializationException
      {
          try 
          {
              //User user = securityService.getUser(admin);
              User user = JetspeedSecurity.getUser(admin);
              QueryLocator ql = new QueryLocator(QueryLocator.QUERY_USER);
              ql.setUser(user);
              //Iterator iterator = psmlManagerService.query(ql);
              Iterator iterator = psmlManager.query(ql);
              while (iterator.hasNext())
              {
                  return true;    // record found
              }
              return false;   // record not found
          }
          catch (UnknownEntityException exc)
          {
              return false;  // record not found
          }
          catch (DataBackendException exc)
          {
              throw new InitializationException("Error in accessing backend data!");
          }
      }
  
      private void dumpProfile(Profile profile) 
      {
          Log.note("--------------Dumping Profile contents--------------");
  
          User user = profile.getUser();
          Role role = profile.getRole();
          Group group = profile.getGroup();
          
          if (user != null)
              Log.note("User: " + user.getUserName()); 
          else if (group != null)
              Log.note("Group: " + group.getName()); 
          else if (role != null)
              Log.note("Role: " + role.getName()); 
          else 
              Log.note("Anon"); 
   
          if (profile.getAnonymous()) 
              Log.note("It's Anonymous"); 
  
          Log.note("MediaType: " + profile.getMediaType());
          Log.note("Page: " + profile.getName());
          Log.note("Language: " + profile.getLanguage());
          Log.note("Country: " + profile.getCountry());
  
          Log.note("--------------Done Dumping Profile contents--------------");
      }
  }
  
  
  1.1                  jakarta-jetspeed/src/java/org/apache/jetspeed/services/psmlmanager/db/DatabasePsmlManagerService.java
  
  Index: DatabasePsmlManagerService.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.db;
  
  // PSML Manager Service interface
  import org.apache.jetspeed.services.psmlmanager.PsmlManagerService;
  
  import org.apache.jetspeed.services.psmlmanager.db.DBOperations;
  import org.apache.jetspeed.services.psmlmanager.db.DatabaseInitializer;
  
  // Jetspeed Security service
  import org.apache.jetspeed.services.JetspeedSecurity;
  
  // Profile and ProfileLocator interface 
  import org.apache.jetspeed.om.profile.Profile;
  import org.apache.jetspeed.om.profile.ProfileLocator;
  import org.apache.jetspeed.om.profile.BaseProfileLocator;
  import org.apache.jetspeed.om.profile.QueryLocator;
  //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;
  import org.apache.turbine.om.security.User;
  import org.apache.turbine.om.security.Group;
  import org.apache.turbine.om.security.Role;
  import org.apache.turbine.util.db.pool.DBConnection;
  import org.apache.turbine.services.db.TurbineDB; 
  
  //Servlet API
  import javax.servlet.ServletConfig;
   
  //castor support
  import org.exolab.castor.xml.MarshalException;
  import org.exolab.castor.xml.ValidationException;
  
  // Torque generated classes
  import org.apache.jetspeed.om.dbpsml.JetspeedUserProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedUserProfilePeer;
  import org.apache.jetspeed.om.dbpsml.JetspeedRoleProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedRoleProfilePeer;
  import org.apache.jetspeed.om.dbpsml.JetspeedGroupProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedGroupProfilePeer;
  import org.apache.jetspeed.om.dbpsml.JetspeedAnonProfile;
  import org.apache.jetspeed.om.dbpsml.JetspeedAnonProfilePeer;
  import org.apache.jetspeed.services.psmlmanager.PsmlImporter;
  
  //standard java stuff
  import java.lang.Thread;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.StringWriter;
  import java.io.ByteArrayInputStream;
  import java.util.List;
  import java.util.Iterator;
  import java.util.StringTokenizer;
  import java.util.ArrayList;
  import java.util.Map;
  import java.util.Set;
  import java.util.Vector;
  import java.util.WeakHashMap;
  import java.io.IOException;
  
  
  /**
   * This service is responsible for loading and saving PSML documents. It uses
   * database to persist the PSML documents.
   *
   * @author <a href="mailto:adambalk@cisco.com">Atul Dambalkar</a>
   * @author <a href="mailto:mvaidya@cisco.com">Medha Vaidya</a>
   * @version 
   */
  public class DatabasePsmlManagerService extends TurbineBaseService 
                                       implements PsmlManagerService, DBOperations
  {
  
      private Map psmlCache = new WeakHashMap();
  
      /** The watcher for the document locations */
      private CacheRefresher refresher = null;
   
      /** the base refresh rate for documents */
      private long refreshRate;  // default will be 8 hours
  
      private final static String REFRESH_RATE = "refresh-rate";
      private final static long DEFAULT_REFRESH_RATE = 60 * 60 * 8 * 1000; //8hrs
  
      /**
       * This is the early initialization method called by the
       * Turbine <code>Service</code> framework
       */
      public void init(ServletConfig conf) throws InitializationException 
      {
          System.out.println("initalizing Dbpsml");
          if (getInit())
          {
              return;
          }
  
          Log.note("Initializing DatabasePsmlManagerService...");
          initConfiguration(conf);
  
          //Mark that we are done
          setInit(true);
          Log.note("Done initializing DatabasePsmlManagerService.");
          System.out.println("done initalizing Dbpsml");
  
          System.out.println("Running Importer");
  
          try
          {
              PsmlImporter importer = new PsmlImporter();
              importer.run();
          }
          catch (Exception e)
          {
              System.out.println("Error importing: " + e.toString());
              Log.error("Error importing: " + e.toString());
              e.printStackTrace();            
          }
          System.out.println("Done Running Importer");
  
      }
  
      /**
       * Loads the configuration parameters for this service from the
       * JetspeedResources.properties file.
       *
       * @exception throws a <code>InitializationException</code> if the service
       * fails to initialize
       */
      private void initConfiguration(ServletConfig conf) 
                              throws InitializationException
      {
          ResourceService serviceConf =
                        ((TurbineServices)TurbineServices.getInstance())
                                .getResources(PsmlManagerService.SERVICE_NAME);
          try
          {
              // get configuration parameters from Turbine Resources
              refreshRate = 
                        serviceConf.getLong(REFRESH_RATE, DEFAULT_REFRESH_RATE);
  
  //            new DatabaseInitializer(this, conf, serviceConf);
  
          }
          catch (Throwable t)
          {
              throw new InitializationException("Missing default refresh rate parameter, during initializing DatabasePsmlManagerService, using defaults");
          }
  
          this.refresher = new CacheRefresher();
          refresher.start();
  
      }
  
      /** 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.refresher.setDone(true);
      }
  
   
      /**
       * A thread implementation of cache refreshing mechanism for database
       * persisted PSMLs. We have to refresh the cache after specific intervals 
       * if someone manually updates the PSML database.
       *
       * @author <a href="mailto:adambalk@cisco.com">Atul Dambalkar</a>
       */ 
      class CacheRefresher extends Thread
      {
          private boolean done = false;
             
          /**
           * Constructor to to set the priority.
           */ 
          CacheRefresher()
          {
              setDaemon(true);
              setPriority(Thread.MIN_PRIORITY+1);
          }
  
          /**
           * We are all done, system is shutting down.
           */ 
          void setDone(boolean done)
          {
              this.done = done;
          }
  
          /**
           * Method as needed for a Thread to run
           */ 
          public void run()
          {
              try
              {
                  while (!done)
                  {
                      Log.note("Cache Refresher thread sleeping now!");
                      sleep (refreshRate);
                      Log.note("Cache Refresher thread woke up!");
                      Log.note("Cache Refresher thread working now!");
  
                      try
                      {
                          synchronized (this)
                         {
                              Iterator i = psmlCache.keySet().iterator();
                 
                              while(i.hasNext())
                              {
                                  String locator = (String)i.next();
   
                                  // do refresh for the locator
                                  PSMLDocument doc = 
                                              refresh(stringToLocator(locator)); 
  
                                  // over write the existing document in cache
                  Log.note("Putting profile in cache, Locator string: " + locator);
                                  psmlCache.put(locator, doc);
                              }
                          }
                      }
                      catch (Exception e)
                      {
                          Log.error("CacheRefresher: Error in cache refresher...", e);
                      }
                  }
              }
              catch (InterruptedException e)
              {
                  Log.note("CacheRefresher: recieved interruption, aborting.");
              }
          }     
      }
  
      /** 
       * Return a unique string identifying this object.
       */
      private String locatorToString(ProfileLocator locator)
      {
          StringBuffer keybuf = new StringBuffer();
   
          User user = locator.getUser();
          Role role = locator.getRole();
          Group group = locator.getGroup();
          boolean anonymous = locator.getAnonymous();
          String name = locator.getName();
          String mediaType = locator.getMediaType();
          String country = locator.getCountry();
          String language = locator.getLanguage();
     
         synchronized (this)
         {
              if (user != null && !anonymous)
              {
                  keybuf.append("User:").append(user.getUserName());
             }
              else if (group != null)
              {
                  keybuf.append("Group:").append(group.getName());
              }
              else if (role != null)
              {
                  keybuf.append("Role:").append(role.getName());
              }
              else if (anonymous)
              {
                  keybuf.append("Anon:").append("Anon");
              }
   
              if (name != null)
              {
                  keybuf.append('$').append("Page:").append(name);
              }
  
              if (mediaType != null)
              {
                  keybuf.append('$').append("MediaType:").append(mediaType);
              }
              if (country != null)
              {
                  keybuf.append('$').append("Country:").append(country);
              }
              if (language != null)
              {
                  keybuf.append('$').append("Language:").append(language);
              }
          }
          Log.note("Returning locator string: " + keybuf.toString());
  
          return keybuf.toString();
      }
  
      private ProfileLocator stringToLocator(String locstr) throws Exception 
      {
          ProfileLocator locator = new BaseProfileLocator();
          String entity = null;
  
          Log.note("Creating locator for string: " + locstr);
  
          StringTokenizer dollarTokens = new StringTokenizer(locstr, "$");
          while (dollarTokens.hasMoreTokens())
          {
              String dollarToken = dollarTokens.nextToken().trim();
  
              StringTokenizer colonTokens = new StringTokenizer(dollarToken, ":");            String colonToken = colonTokens.nextToken();
              if (colonToken.equals("User"))
              {
                  entity = colonTokens.nextToken().trim();
                  locator.setUser(JetspeedSecurity.getUser(entity));
              }
              else if (colonToken.equals("Group"))
              {
                  entity = colonTokens.nextToken().trim();
                  locator.setGroup(JetspeedSecurity.getGroup(entity));
              }
              else if (colonToken.equals("Role"))
              {
                  entity = colonTokens.nextToken().trim();
                  locator.setRole(JetspeedSecurity.getRole(entity));
              }
              else if (colonToken.equals("Anon"))
              {
                  locator.setAnonymous(true);
              }
              else if (colonToken.equals("Page"))
              {
                  entity = colonTokens.nextToken().trim();
                  locator.setName(entity);
              }
              else if (colonToken.equals("MediaType"))
              {
                  entity = colonTokens.nextToken().trim();
                  locator.setMediaType(entity);
              }
              else if (colonToken.equals("Country"))
              {
                  entity = colonTokens.nextToken().trim();
                  locator.setCountry(entity);
              }
              else if (colonToken.equals("Language"))
              {
                  entity = colonTokens.nextToken().trim();
                  locator.setLanguage(entity);
              }
          }
          Log.note("Returning locator for string: " + locatorToString(locator));
      
          return locator;
  
      }
  
      public PSMLDocument getDocument(String name)
      {
          // do nothing, deprecated
          return null;
      }
  
      public boolean saveDocument(String fileOrUrl, PSMLDocument doc)
      {
          // do nothing, deprecated
          return false;
      }
  
      public boolean saveDocument(PSMLDocument doc) 
      {
          // do nothing, will be deprecated 
          return false;
      }
  
  
      /**
       * Returns a PSML document for the given locator
       *
       * @param locator The locator descriptor(ProfileLocator object) of the 
       * document to be retrieved.
       * @return psmldoc The PSMLDocument object
       */
      public PSMLDocument getDocument(ProfileLocator locator) 
      {
          // check the cache for the req'e document if not available in cache
          // get the document from database
  
          if (locator == null)
          {
              String message = "PSMLManager: Must specify a locator";
              Log.error(message);
              throw new IllegalArgumentException(message);
          }
  
          PSMLDocument psmldoc = null;
  
          synchronized (psmlCache)
          {
                  Log.note("Getting profile from cache, Locator string: " + locatorToString(locator));
              psmldoc = (PSMLDocument)psmlCache.get(locatorToString(locator));
          }
  
          if (psmldoc != null)
          {
              return psmldoc;
          }
  
          try
          {
              return refresh(locator);
          }
          catch (Exception e)
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
              Log.error("Unable to get a psml document from the database.", e);
              throw new RuntimeException("Could not get profile from DB");
          }
      }
  
      /**
       * Stores the PSML document in DB for the given profile
       *
       * @param profile The profile that holds the PSMLDocument.
       * @return PSMLDocument The PSMLDocument that got created in DB.
       */
      public PSMLDocument createDocument(Profile profile) 
      {
          return createOrSaveDocument(profile, INSERT);
      }
  
      /**
       * Update the PSML document in DB for the given profile
       *
       * @param profile The profile that holds the PSMLDocument.
       * @return PSMLDocument The PSMLDocument that got created in DB.
       */
      public boolean store(Profile profile) 
      {
          return createOrSaveDocument(profile, UPDATE) != null;
      }
  
      private PSMLDocument createOrSaveDocument(Profile profile, int operation)
      {
          // create record in the database for Portlets for the given 
          // profile/PSMLDocuemnt,use marsheller to create Portlets 
          // object and then put it in database, update the cache
  
          if (profile == null)
          {
              String message = "PSMLManager: Must specify a profile";
              Log.error(message);
              throw new IllegalArgumentException(message);
          }
  
          User user = profile.getUser();
          Role role = profile.getRole();
          Group group = profile.getGroup();
          boolean anonymous = profile.getAnonymous();
          String tableName = null;
  
          try 
          {
              if (user != null && !anonymous)
              {
                  if (operation == INSERT) 
                  {
                      new JetspeedUserProfilePeer().insert(profile);
                  }
                  else if (operation == UPDATE)
                  {
                      new JetspeedUserProfilePeer().update(profile);
                  }
                  tableName = "JETSPEED_USER_PROFILE";
              }
              else if (role != null)
              {
                  if (operation == INSERT) 
                  {
                      new JetspeedRoleProfilePeer().insert(profile);
                  }
                  else if (operation == UPDATE)
                  {
                      new JetspeedRoleProfilePeer().update(profile);
                  }
                  tableName = "JETSPEED_ROLE_PROFILE";
              }  
              else if (group != null)
              {
                  if (operation == INSERT) 
                  {
                      new JetspeedGroupProfilePeer().insert(profile);
                  }
                  else if (operation == UPDATE)
                  {
                      new JetspeedGroupProfilePeer().update(profile);
                  }
                  tableName = "JETSPEED_GROUP_PROFILE";
              }   
              else  // it will be anonymous access
              {
                  if (operation == INSERT) 
                  {
                      new JetspeedAnonProfilePeer().insert(profile);
                  }
                  else if (operation == UPDATE)
                  {
                      new JetspeedAnonProfilePeer().update(profile);
                  }
                  tableName = "JETSPEED_ANON_PROFILE";
              } 
              // insert successful
              synchronized (psmlCache)
              {
                  Log.note("Putting profile in cache, in create document method, Locator string: " + locatorToString(profile));
                  psmlCache.put(locatorToString(profile), profile.getDocument());
              }
              return profile.getDocument();
          }
          catch (Exception e) // insert failed
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
              Log.error("Insert in table " + tableName + " failed");
              throw new RuntimeException("Could not create new profile in DB");
          }
      }
  
      /** 
       * Remove the PSMLDocument/profile for given locator object.
       * 
       * @param locator The profile locator criteria for profile to be removed.
       */
      public void removeDocument(ProfileLocator locator)
      {
          if (locator == null)
          {
              String message = "PSMLManager: Must specify a locator";
              Log.error(message);
              throw new IllegalArgumentException(message);
          }
  
          User user = locator.getUser();
          Role role = locator.getRole();
          Group group = locator.getGroup();
          String tableName = null;
  
          try 
          {  
              if (user != null)
              {   
                  new JetspeedUserProfilePeer().delete(locator);
                  tableName = "JETSPEED_USER_PROFILE";
              }
              else if (role != null)
              {  
                  new JetspeedRoleProfilePeer().delete(locator);
                  tableName = "JETSPEED_ROLE_PROFILE";
              } 
              else if (group != null)
              {
                  new JetspeedGroupProfilePeer().delete(locator);
                  tableName = "JETSPEED_GROUP_PROFILE";
              }  
              else  // it will be anonymous access
              { 
                  new JetspeedAnonProfilePeer().delete(locator);
                  tableName = "JETSPEED_ANON_PROFILE";
              }
              // Delete successful
              synchronized (psmlCache)
              {
                  psmlCache.remove(locatorToString(locator));
              }
          }
          catch (Exception e) // insert failed
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
              Log.error("Insert in table " + tableName + " failed");
              throw new RuntimeException("Could not delete profile for given locator from DB");
          }
      }
  
      /** 
       * Query for a collection of profiles given a profile locator criteria.
       * Use SQL engine to get the required profiles.
       * 
       * @param locator The profile locator criteria.
       * @return Iterator object with the PSMLDocuments satisfying query
       */
      public Iterator query(QueryLocator locator)
      {
          if (locator == null)
          {
              String message = "PSMLManager: Must specify a locator";
              Log.error(message);
              throw new IllegalArgumentException(message);
          }
  
          try 
          {  
              Vector userData = null;
              Vector groupData = null;
              Vector roleData = null;
              Vector anonData = null;
   
              int queryMode = locator.getQueryMode();
              
              List list = new ArrayList();
   
              switch (queryMode)
              {
                  case QueryLocator.QUERY_USER:    
                      userData = new JetspeedUserProfilePeer().select(locator);
                      if (userData != null)
                      {
                          list = getProfiles(userData);
                      }
                      break;
  
                  case QueryLocator.QUERY_GROUP:
                      groupData = new JetspeedGroupProfilePeer().select(locator);
                      if (groupData != null)
                      {
                          list = getProfiles(groupData);
                      }
                      break;
   
                  case QueryLocator.QUERY_ROLE:    
                      roleData = new JetspeedRoleProfilePeer().select(locator);
                      if (roleData != null)
                      {
                          list = getProfiles(roleData);
                      }
                      break;
   
                  case QueryLocator.QUERY_ANON:    
                      anonData = new JetspeedAnonProfilePeer().select(locator);
                      if (anonData != null)
                      {
                          list = getProfiles(anonData);
                      }
                      break;
  
                  default:  //QUERY_ALL
                      userData = new JetspeedUserProfilePeer().select(locator);
                      if (userData != null)
                      {
                          list.addAll(getProfiles(userData));
                      }
  
                      groupData = new JetspeedGroupProfilePeer().select(locator);
                      if (groupData != null)
                      {
                          list.addAll(getProfiles(groupData));
                      }
  
                      roleData = new JetspeedRoleProfilePeer().select(locator);
                      if (roleData != null)
                      {
                          list.addAll(getProfiles(roleData));
                      }
  
                      anonData = new JetspeedAnonProfilePeer().select(locator);
                      if (anonData != null)
                      {
                          list.addAll(getProfiles(anonData));
                      }
                     break;
              }
              
              return list.iterator();
          }
          catch (Exception e)
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
          }
  
          return new ArrayList().iterator();  // return empty non-null iterator
      } 
  
      /**
       * Get profile iterator from given vector of objects.
       *
       * @param data Vector of JetspeedUserProfile, JetspeedGroupProfile, 
       * JetspeedRoleProfile, JetspeedAnonProfile objects
       * @return List of profiles
       */
      private List getProfiles(Vector data)
      {
          List list = new ArrayList();
  
          for (int i = 0; i < data.size(); i++) 
          {
              Object obj = data.get(i);
              Portlets portlets = null;
  
              if (obj instanceof JetspeedUserProfile) 
              {
                  portlets = DBUtils.bytesToPortlets(((JetspeedUserProfile)obj).getProfile());
              }
              else if (obj instanceof JetspeedGroupProfile) 
              {
                  portlets = DBUtils.bytesToPortlets(((JetspeedGroupProfile)obj).getProfile());
  
              }
              else if (obj instanceof JetspeedRoleProfile) 
              {
                  portlets = DBUtils.bytesToPortlets(((JetspeedRoleProfile)obj).getProfile());
   
              }
              else if (obj instanceof JetspeedAnonProfile) 
              {
                  portlets = DBUtils.bytesToPortlets(((JetspeedAnonProfile)obj).getProfile());
              }
   
              list.add(portlets);
          }
          return list;
      }
  
    
      /**
       * Get PSMLDocument object for given pagename and portlets.
       *
       * @param portlets Portlets for the given page name
       * @param page page name for this resource
       * @return PSMLDocument object for given page and portlets 
       */ 
      private PSMLDocument getPSMLDocument(String page, Portlets portlets)
      {
          PSMLDocument psmldoc = new BasePSMLDocument();
          psmldoc.setName(page);
          psmldoc.setPortlets(portlets);
          return psmldoc;
      }  
  
      /** 
       * Given ordered list of locators, find the first document matching
       * a profile locator, starting from the beginning of the list and working
       * to the end.
       *
       * @param locator The ordered list of profile locators.
       * @return PSMLDocument object for the first document matching a locator 
       */
      public PSMLDocument getDocument(List locators)
      {
          if (locators == null)
          {
              String message = "PSMLManager: Must specify a list of locators";
              Log.error(message);
              throw new IllegalArgumentException(message);
          }
  
          // iterate over the list and invoke getDocument(locator) method
          for (int i = 0; i < locators.size(); i++) 
          {
              PSMLDocument psmldoc = getDocument((ProfileLocator)locators.get(i));
              if (psmldoc != null) 
              {
                  return psmldoc;
              }
          }
          return null;
      }
  
      /**
       * Returns a PSML document for the given locator, it is called by the cache
       * refresher
       *   
       * @param locator The locator descriptor(ProfileLocator object) of the 
       * document to be retrieved.
       * @return psmldoc The PSMLDocument object
       */
      private PSMLDocument refresh(ProfileLocator locator)
      {
          // go to database and get the blob, and marshal the Portlets
  
          if (locator == null)
          {
              String message = "PSMLManager: Must specify a locator";
              Log.error(message);
              throw new IllegalArgumentException(message);
          }
  
          User user = locator.getUser();
          Role role = locator.getRole();
          Group group = locator.getGroup();
          String tableName = null;
          Vector records = null;
          Portlets portlets = null;
          PSMLDocument psmldoc = null;
          String page = null;
  
          try
          {
              if (user != null)
              {
                  records = new JetspeedUserProfilePeer().select(locator);
                  Iterator iterator = records.iterator(); 
                  while (iterator.hasNext())
                  {
                      JetspeedUserProfile uprofile = 
                                         (JetspeedUserProfile)iterator.next();
                      page = uprofile.getPage();
                      portlets = DBUtils.bytesToPortlets(uprofile.getProfile());
                  }
                  tableName = "JETSPEED_USER_PROFILE";
              }
              else if (role != null)
              {  
                  records = new JetspeedRoleProfilePeer().select(locator);
                  Iterator iterator = records.iterator(); 
                  while (iterator.hasNext())
                  {
                      JetspeedRoleProfile rprofile = 
                                         (JetspeedRoleProfile)iterator.next();
                      page = rprofile.getPage();
                      portlets = DBUtils.bytesToPortlets(rprofile.getProfile());
                  }
                  tableName = "JETSPEED_ROLE_PROFILE";
              } 
              else if (group != null)
              {
                  records = new JetspeedGroupProfilePeer().select(locator);
                  Iterator iterator = records.iterator(); 
                  while (iterator.hasNext())
                  {
                      JetspeedGroupProfile gprofile = 
                                         (JetspeedGroupProfile)iterator.next();
                      page = gprofile.getPage();
                      portlets = DBUtils.bytesToPortlets(gprofile.getProfile());
                  }
                  tableName = "JETSPEED_GROUP_PROFILE";
              }  
              else  // it will be anonymous access
              { 
                  records = new JetspeedAnonProfilePeer().select(locator);
                  Iterator iterator = records.iterator(); 
                  while (iterator.hasNext())
                  {
                      JetspeedAnonProfile aprofile = 
                                         (JetspeedAnonProfile)iterator.next();
                      page = aprofile.getPage();
                      portlets = DBUtils.bytesToPortlets(aprofile.getProfile());
                  }
                  tableName = "JETSPEED_ANON_PROFILE";
              }
              if (page != null && portlets != null) 
              {
                  psmldoc = getPSMLDocument(page, portlets);
                  synchronized (psmlCache)
                  {
                  Log.note("Putting profile in cache, in refresh method, Locator string: " + locatorToString(locator));
                      psmlCache.put(locatorToString(locator), psmldoc);
                  }
                  return psmldoc;
              } 
          }
          catch (Exception e)
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
              Log.error("Select from table " + tableName + " failed");
              Log.error("Unable to get a psml document from the database.", e);
              Log.error("Refresh failed: " + locatorToString(locator));
              throw new RuntimeException("Could not refresh profile from DB");
          }
          Log.note("DatabasePsmlManagerService: Returning null document");
          return null;
      }
  
      /** Removes all documents for a given user.
       *
       * @param user The user object.
       */
      public void removeUserDocuments(User user)
      {
          try 
          {  
              if (user != null)
              {   
                  new JetspeedUserProfilePeer().delete(user);
              }   
          }
          catch (Exception e) // delete failed
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
              Log.error("Delete from table JETSPEED_USER_PROFILE failed");
              throw new RuntimeException("Could not delete documents for given user from DB");
          }
  
      }
  
      /** Removes all documents for a given role.
       *
       * @param role The role object.
       */
      public void removeRoleDocuments(Role role)
      {
          try
          {
              if (role != null)
              {
                  new JetspeedRoleProfilePeer().delete(role);
              } 
          }
          catch (Exception e) // delete failed
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
              Log.error("Delete from table JETSPEED_ROLE_PROFILE failed");
              throw new RuntimeException("Could not delete documents for given role from DB");
          }
      }
  
      /** Removes all documents for a given group.
       *
       * @param group The group object.
       */
      public void removeGroupDocuments(Group group)
      {
          try
          {
              if (group != null)
              {
                  new JetspeedGroupProfilePeer().delete(group);
              }  
          }
          catch (Exception e) // delete failed
          {
              Log.error("Error occurred in Database PSML Manager: " + e);
              Log.error("Delete from table JETSPEED_GROUP_PROFILE failed");
              throw new RuntimeException("Could not delete documents for given group from DB");
          }
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>