taylor      2002/11/13 22:52:41

  Modified:    build    build.xml
               src/java/org/apache/jetspeed/services/psmlmanager
                        CastorPsmlManagerService.java
               webapp/WEB-INF/conf JetspeedResources.properties
                        JetspeedSecurity.properties
  Added:       src/java/org/apache/jetspeed/cache FileCache.java
                        FileCacheEntry.java FileCacheEventListener.java
                        TestFileCache.java
               test/testdata/psml/user/cachetest default.psml
               webapp/WEB-INF/conf HttpAgentLog4j.properties
  Log:
  Refactored the CastorPSMLManager service.
  After several days of (unplanned) JMeter testing, was seeing that:
   - the weakreferences *Never* worked. The cache was being completely bypassed
   - if the document failed to load for some reason, we had an infinite loop crash in 
the getDocument method
   - still not sure why the document was failing to load, but I can no longer repro 
with refactored impl
  
  The new implementation makes use of some new classes in the 
org.apache.jetspeed.cache package:
  * FileCache - a file cache, used by the CastorPSMLManager, to manager the caching of 
psml resources
  * FileCachEventListener - events are sent back to the CastorPSMLManager when a doc 
is refreshed or evicted
  * The JR.p now supports to more settings:
    - scanRate - in seconds for refreshing the cache
    - cacheSize - the max size of the cache before eviction kicks. Eviction is based 
least used
  * unit test for FileCache
  
  Revision  Changes    Path
  1.167     +6 -1      jakarta-jetspeed/build/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-jetspeed/build/build.xml,v
  retrieving revision 1.166
  retrieving revision 1.167
  diff -u -r1.166 -r1.167
  --- build.xml 7 Nov 2002 20:25:17 -0000       1.166
  +++ build.xml 14 Nov 2002 06:52:36 -0000      1.167
  @@ -261,7 +261,10 @@
                       <include 
name="org/apache/jetspeed/services/security/UserManagement.java"/>
                       <include name="org/apache/jetspeed/util/MetaData.java"/>
   <!--                                              <include 
name="org/apache/jetspeed/services/security/ldap/UnixCrypt.java"/> -->
  -                                                  <include 
name="org.apache/jetspeed/services/security/ldap/JetspeedLDAPSecurityService"/>
  +                    <include 
name="org.apache/jetspeed/services/security/ldap/JetspeedLDAPSecurityService"/>
  +                    <include name="org.apache/jetspeed/cache/FileCache.java"/>
  +                    <include name="org.apache/jetspeed/cache/FileCacheEntry.java"/>
  +                    <include name="org.apache/jetspeed/cache/TestFileCache.java"/>
                   </patternset>
               </fileset>
           </checkstyle>
  @@ -975,6 +978,7 @@
               <test name="org.apache.jetspeed.util.rewriter.FrameRewriterTest"/> 
               <test name="org.apache.jetspeed.services.profiler.TestProfilerService"/>
               <test 
name="org.apache.jetspeed.services.registry.TestRegistryCategories"/>
  +                             <test name="org.apache.jetspeed.cache.TestFileCache"/>
   <!--
               <test 
name="org.apache.jetspeed.services.registry.TestRegistryPersistence"/> 
   -->
  @@ -1212,6 +1216,7 @@
                     </ant>
                   
                   </target>
  +
   
       <!-- =================================================================== -->
       <!-- Include the usage target and the test targets for the different     -->
  
  
  
  1.1                  
jakarta-jetspeed/src/java/org/apache/jetspeed/cache/FileCache.java
  
  Index: FileCache.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 [EMAIL PROTECTED]
   *
   * 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.cache;
  
  import java.util.Collections;
  import java.util.Date;
  import java.util.Map;
  import java.util.HashMap;
  import java.util.List;
  import java.util.LinkedList;
  import java.util.Iterator;
  import java.io.File;
  
  import org.apache.turbine.util.Log;
  
  /**
   * FileCache keeps a cache of files up-to-date with a most simple eviction policy.
   * The eviction policy will keep n items in the cache, and then start evicting
   * the items ordered-by least used first. The cache runs a thread to check for
   * both evictions and refreshes.
   *
   *  @author David S. Taylor <a href="mailto:taylor@;apache.org">David Sean Taylor</a>
   *  @version $Id: FileCache.java,v 1.1 2002/11/14 06:52:36 taylor Exp $
   */
  
  public class FileCache implements java.util.Comparator
  {
      protected long scanRate = 300;  // every 5 minutes
      protected int maxSize = 100; // maximum of 100 items
      protected List listeners = new LinkedList();
  
      private FileCacheScanner scanner = null;
      private Map cache = null;
  
      /**
       * Default constructor. Use default values for scanReate and maxSize
       *
       */
      public FileCache()
      {
          cache = new HashMap();
          this.scanner = new FileCacheScanner();
          this.scanner.setDaemon(true);
      }
  
      /**
       * Set scanRate and maxSize
       *
       * @param scanRate how often in seconds to refresh and evict from the cache
       * @param maxSize the maximum allowed size of the cache before eviction starts
       */
      public FileCache(long scanRate, 
                       int maxSize)
      {
          cache = new HashMap();
  
          this.scanRate = scanRate;
          this.maxSize = maxSize;
          this.scanner = new FileCacheScanner();
          this.scanner.setDaemon(true);
      }
  
      /**
       * Set all parameters on the cache
       *
       * @param initialCapacity the initial size of the cache as passed to HashMap
       * @param loadFactor how full the hash table is allowed to get before increasing
       * @param scanRate how often in seconds to refresh and evict from the cache
       * @param maxSize the maximum allowed size of the cache before eviction starts
       */
      public FileCache(int initialCapacity, 
                       int loadFactor, 
                       long scanRate, 
                       int maxSize)
      {
          cache = new HashMap(initialCapacity, loadFactor);
  
          this.scanRate = scanRate;
          this.maxSize = maxSize;
          this.scanner = new FileCacheScanner();
          this.scanner.setDaemon(true);
      }
  
      /**
       * Set the new refresh scan rate on managed files.
       *
       * @param scanRate the new scan rate in seconds
       */
      public void setScanRate(long scanRate)
      {
          this.scanRate= scanRate;
      }
  
      /**
       * Get the refresh scan rate 
       *
       * @return the current refresh scan rate in seconds
       */
      public long getScanRate()
      {
          return scanRate;
      }
  
      /**
       * Set the new maximum size of the cache 
       *
       * @param maxSize the maximum size of the cache
       */
      public void setMaxSize(int maxSize)
      {
          this.maxSize = maxSize;
      }
  
      /**
       * Get the maximum size of the cache 
       *
       * @return the current maximum size of the cache
       */
      public int getMaxSize()
      {
          return maxSize;
      }
  
      /**
       * Gets an entry from the cache given a key
       *
       * @param key the key to look up the entry by
       * @return the entry
       */
      public FileCacheEntry get(String key)
      {
          return (FileCacheEntry) cache.get(key);
      }
  
      /**
       * Gets an entry from the cache given a key
       *
       * @param key the key to look up the entry by
       * @return the entry
       */
      public Object getDocument(String key)
      {
          FileCacheEntry entry = (FileCacheEntry) cache.get(key);
          if (entry != null)
          {
              return entry.getDocument();
          }
          return null;
      }
  
      /**
       * Puts a file entry in the file cache
       *
       * @param file The file to be put in the cache
       * @param document the cached document
       */
      public void put(File file, Object document)
          throws java.io.IOException
      {
          FileCacheEntry entry = new FileCacheEntry(file, document);
          cache.put(file.getCanonicalPath(), entry);
      }
  
      /**
       * Puts a file entry in the file cache
       *
       * @param path the full path name of the file
       * @param document the cached document
       */
      public void put(String key, Object document)
          throws java.io.IOException
      {
          File file = new File(key);
          FileCacheEntry entry = new FileCacheEntry(file, document);
          cache.put(file.getCanonicalPath(), entry);
      }
  
      /**
       * Removes a file entry from the file cache
       *
       * @param key the full path name of the file
       * @return the entry removed
       */
      public Object remove(String key)
      {
          return cache.remove(key);
      }
  
  
      /**
       * Add a File Cache Event Listener 
       *
       * @param listener the event listener
       */
      public void addListener(FileCacheEventListener listener)
      {
          listeners.add(listener);
      }
  
      /**
       * Start the file Scanner running at the current scan rate.
       *
       */
      public void startFileScanner()
      {
          try
          {
  
              this.scanner.start();
          }
          catch (java.lang.IllegalThreadStateException e)
          {
              Log.error("Exception starting scanner", e);
          }
      }
  
      /**
       * Stop the file Scanner 
       *
       */
      public void stopFileScanner()
      {
          this.scanner.setStopping(true);
      }
  
      /**
       * Evicts entries based on last accessed time stamp
       *
       */
      protected void evict()        
      {
          synchronized (cache)
          {
              if (this.getMaxSize() >= cache.size())
              {
                  return;
              }
      
              List list = new LinkedList(cache.values());
              Collections.sort(list, this);
      
              int count = 0;
              int limit = cache.size() - this.getMaxSize();
      
              for (Iterator it = list.iterator(); it.hasNext(); )
              {
                  if (count >= limit)
                  {
                      break;
                  }
      
                  FileCacheEntry entry = (FileCacheEntry) it.next();
                  String key = null;
                  try
                  {
                      key = entry.getFile().getCanonicalPath();
                  }                    
                  catch (java.io.IOException e)
                  {
                      Log.error("Exception getting file path: ", e);
                  }
                  // notify that eviction will soon take place
                  for (Iterator lit = this.listeners.iterator(); lit.hasNext(); )
                  {
                      FileCacheEventListener listener = 
                          (FileCacheEventListener) lit.next();
                      listener.evict(entry);                                    
                  }
                  cache.remove(key);
      
                  count++;
              }        
          }
      }
  
      /**
       * Comparator function for sorting by last accessed during eviction
       *
       */
      public int compare(Object o1, Object o2)
      {
          FileCacheEntry e1 = (FileCacheEntry)o1;
          FileCacheEntry e2 = (FileCacheEntry)o2;
  
          if (e1.getLastAccessed() < e2.getLastAccessed())
          {
              return -1;
          }
          else if (e1.getLastAccessed() == e2.getLastAccessed())
          {
              return 0;
          }
          return 1;
      }
  
      /**
       * inner class that runs as a thread to scan the cache for updates or evictions
       *
       */
      protected class FileCacheScanner extends Thread
      {
          private boolean stopping = false;
  
          public void setStopping(boolean flag)
          {
              this.stopping = flag;
          }
  
          /**
           * Run the file scanner thread
           *
           */
          public void run()
          {
              boolean done = false;
      
              try
              {
                  while(!done)
                  {
                      try
                      {
                          int count = 0;
                          for (Iterator it = FileCache.this.cache.values().iterator(); 
it.hasNext(); )
                          {
                              FileCacheEntry entry = (FileCacheEntry) it.next();
                              Date modified = new Date(entry.getFile().lastModified());
      
                              if (modified.after(entry.getLastModified()))
                              {                            
                                  for (Iterator lit = 
FileCache.this.listeners.iterator(); lit.hasNext(); )
                                  {
                                      FileCacheEventListener listener = 
                                          (FileCacheEventListener) lit.next();
                                      listener.refresh(entry);                         
           
                                      entry.setLastModified(modified);
                                  }
                              }
                              count++;
                          }
                          if (count > FileCache.this.getMaxSize())
                          {
                              FileCache.this.evict();
                          }
                      }
                      catch (Exception e)
                      {
                          Log.error("FileCache Scanner: Error in iteration...", e);
                      }
      
                      sleep(FileCache.this.getScanRate() * 1000);                
  
                      if (this.stopping)
                      {
                          this.stopping = false;
                          done = true;
                      }
                  }
              }
              catch (InterruptedException e)
              {
                  Log.error("FileCacheScanner: recieved interruption, exiting.", e);
              }
          }
      } // end inner class:  FileCacheScanner
  
  
      /**
       * get an iterator over the cache values
       *
       * @return iterator over the cache values
       */
      public Iterator getIterator()
      {
          return cache.values().iterator();
      }
  
      /**
        * get the size of the cache
        *
        * @return the size of the cache
        */
      public int getSize()
      {
          return cache.size();
      }
  }
  
  
  
  
  1.1                  
jakarta-jetspeed/src/java/org/apache/jetspeed/cache/FileCacheEntry.java
  
  Index: FileCacheEntry.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 [EMAIL PROTECTED]
   *
   * 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.cache;
  
  import java.util.Date;
  import java.util.HashMap;
  import java.io.File;
  
  /**
   * FileCache entry keeps the cached content along with last access information.
   *
   *  @author David S. Taylor <a href="mailto:taylor@;apache.org">David Sean Taylor</a>
   *  @version $Id: FileCacheEntry.java,v 1.1 2002/11/14 06:52:36 taylor Exp $
   */
  
  public class FileCacheEntry
  {
      protected File file;
      protected Object document;
  
      protected long lastAccessed;
      protected Date lastModified;
  
      private FileCacheEntry()
      {
      }
  
      /**
       * Constructs a FileCacheEntry object
       *
       * @param document The user specific content being cached
       * @param lastModified The document's last modified stamp
       */
      public FileCacheEntry(File file, Object document)
      {
          this.file = file;
          this.document = document;
          this.lastModified = new Date(file.lastModified());
          this.lastAccessed = new Date().getTime();
      }
  
      /**
       * Get the file descriptor
       *
       * @return the file descriptor
       */
      public File getFile()
      {
          return this.file;
      }
  
      /**
       * Set the file descriptor
       *
       * @param file the new file descriptor
       */
      public void setFile(File file)
      {
          this.file = file;
      }
  
      /**
       * Set the cache's last accessed stamp
       *
       * @param lastAccessed the cache's last access stamp
       */
      public void setLastAccessed(long lastAccessed)
      {
          this.lastAccessed = lastAccessed;
      }
  
      /**
       * Get the cache's lastAccessed stamp
       *
       * @return the cache's last accessed stamp
       */
      public long getLastAccessed()
      {
          return this.lastAccessed;
      }
  
      /**
       * Set the cache's last modified stamp
       *
       * @param lastModified the cache's last modified stamp
       */
      public void setLastModified(Date lastModified)
      {
          this.lastModified = lastModified;
      }
  
      /**
       * Get the entry's lastModified stamp (which may be stale compared to file's 
stamp)
       *
       * @return the last modified stamp
       */
      public Date getLastModified()
      {
          return this.lastModified;
      }
  
      /**
       * Set the Document in the cache
       *
       * @param document the document being cached
       */
      public void setDocument(Object document)
      {
          this.document = document;
      }
  
      /**
       * Get the Document
       *
       * @return the document being cached
       */
      public Object getDocument()
      {
          return this.document;
      }
  
  }
  
  
  
  
  
  1.1                  
jakarta-jetspeed/src/java/org/apache/jetspeed/cache/FileCacheEventListener.java
  
  Index: FileCacheEventListener.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 [EMAIL PROTECTED]
   *
   * 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.cache;
  
  import java.util.Date;
  import java.util.HashMap;
  
  /**
   * FileCacheEventListener on notifications sent when FileCache events occur
   *
   *  @author David S. Taylor <a href="mailto:taylor@;apache.org">David Sean Taylor</a>
   *  @version $Id: FileCacheEventListener.java,v 1.1 2002/11/14 06:52:36 taylor Exp $
   */
  
  public interface FileCacheEventListener
  {
  
      /**
       * Refresh event, called when the entry is being refreshed from file system.
       *
       * @param entry the entry being refreshed.
       */
      void refresh(FileCacheEntry entry);
  
      /**
       * Evict event, called when the entry is being evicted out of the cache
       *
       * @param entry the entry being refreshed.
       */
      void evict(FileCacheEntry entry);
  
  }
  
  
  
  
  
  
  1.1                  
jakarta-jetspeed/src/java/org/apache/jetspeed/cache/TestFileCache.java
  
  Index: TestFileCache.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 [EMAIL PROTECTED]
   *
   * 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.cache;
  
  import java.util.Iterator;
  import java.io.File;
  import java.util.Date;
  import java.io.BufferedInputStream;
  import java.io.FileInputStream;
  
  // Junit imports
  import junit.framework.Test;
  import junit.framework.TestSuite;
  import junit.framework.TestCase;
  
  import org.apache.jetspeed.util.FileCopy;
  import org.apache.jetspeed.util.Streams;
  import org.apache.turbine.util.StringUtils;
  
  
  /**
   * Unit test for FileCache 
   * 
   * @author <a href="mailto:david@;bluesunrise.com">David Sean Taylor</a>
   * @version $Id: TestFileCache.java,v 1.1 2002/11/14 06:52:37 taylor Exp $
   */
  
  public class TestFileCache extends TestCase implements FileCacheEventListener
  {    
      String refreshedEntry = null;
  
      /**
       * Defines the testcase name for JUnit.
       *
       * @param name the testcase's name.
       */
      public TestFileCache( String name ) {
          super( name );
      }
      
      /**
       * Start the tests.
       *
       * @param args the arguments. Not used
       */
      public static void main(String args[]) 
      {
          junit.awtui.TestRunner.main( new String[] { TestFileCache.class.getName() } 
);
      }
   
      /**
       * Creates the test suite.
       *
       * @return a test suite (<code>TestSuite</code>) that includes all methods
       *         starting with "test"
       */
      public static Test suite() 
      {
          // All methods starting with "test" will be executed in the test suite.
          return new TestSuite( TestFileCache.class );
      }
  
      /**
       * Tests loading the cache
       * @throws Exception
       */
  
      public void testLoadCache() throws Exception 
      {
          String templateFile = "../test/testdata/psml/user/cachetest/default.psml";
          try
          {
              File file = new File(templateFile);            
              assertTrue(file.exists());
  
              createTestFiles(templateFile);
  
              // create the Cache  wake up after 10 seconds, cache size 20
              FileCache cache = new FileCache(10, 20);
  
              // load the Cache
              File directory = new File("../test/testdata/psml/user/cachetest/");
              File[] files = directory.listFiles();
              for (int ix=0; ix < files.length; ix++)
              {
                  String testData = readFile(files[ix]);
                  cache.put(files[ix], testData);
              }
  
              assertTrue(cache.getSize() == 31);
  
              dumpCache(cache.getIterator());
  
              cache.addListener(this);
              // start the cache's scanner
              cache.startFileScanner();
  
              Thread.currentThread().sleep(2000);
  
              assertTrue(cache.getSize() == 20);
  
              dumpCache(cache.getIterator());
  
              String stuff = (String) cache.getDocument(files[18].getCanonicalPath());
              assertNotNull(stuff);
  
              files[18].setLastModified(new Date().getTime());
  
  
              Thread.currentThread().sleep(9000);
  
              assertNotNull(refreshedEntry);
              System.out.println("refreshed entry = " + refreshedEntry);
  
              cache.stopFileScanner();
  
              removeTestFiles();
          }
          catch (Exception e)
          {
              fail(StringUtils.stackTrace(e));
          }
  
          System.out.println("Completed loadCache Test OK ");
  
      }
  
      private void createTestFiles(String templateFile)
          throws java.io.IOException
      {
          for (int ix=1; ix < 31; ix++)
          {
              String testFile = "../test/testdata/psml/user/cachetest/testFile-" + ix 
+ ".psml";
              FileCopy.copy(templateFile, testFile);
          }
      }
  
      private void removeTestFiles()
      {
          for (int ix=1; ix < 31; ix++)
          {
              String testFile = "../test/testdata/psml/user/cachetest/testFile-" + ix 
+ ".psml";
              File file = new File(testFile);
              file.delete();
          }
      }
  
      private String readFile(File file)
          throws java.io.IOException, java.io.FileNotFoundException
      {
          BufferedInputStream input;
  
          input = new BufferedInputStream(new FileInputStream(file));
          String result = Streams.getAsString(input);
          input.close();
          return result;
      }
  
      /**
       * Refresh event, called when the entry is being refreshed from file system.
       *
       * @param entry the entry being refreshed.
       */
      public void refresh(FileCacheEntry entry)
      {
          System.out.println("entry is refreshing: " + entry.getFile().getName());
          this.refreshedEntry = entry.getFile().getName();
      }
  
      /**
       * Evict event, called when the entry is being evicted out of the cache
       *
       * @param entry the entry being refreshed.
       */
      public void evict(FileCacheEntry entry)
      {
          System.out.println("entry is evicting: " + entry.getFile().getName());
      }
  
      private void dumpCache(Iterator it)
      {
          for ( ; it.hasNext(); )
          {
              FileCacheEntry entry = (FileCacheEntry) it.next();
              System.out.println(entry.getFile().getName());
          }
      }
  }
  
  
  
  
  
  
  
  
  
  1.35      +105 -196  
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.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- CastorPsmlManagerService.java     8 Nov 2002 10:05:18 -0000       1.34
  +++ CastorPsmlManagerService.java     14 Nov 2002 06:52:37 -0000      1.35
  @@ -115,9 +115,13 @@
   import java.util.LinkedList;
   import java.util.Map;
   import java.util.HashMap;
  -import java.lang.ref.WeakReference;
   import javax.servlet.ServletConfig;
   
  +import org.apache.jetspeed.cache.FileCache;
  +import org.apache.jetspeed.cache.FileCacheEventListener;
  +import org.apache.jetspeed.cache.FileCacheEntry;
  +
  +
   /**
    * This service is responsible for loading and saving PSML documents.
    *
  @@ -126,8 +130,9 @@
    * @author <a href="mailto:sgala@;apache.org">Santiago Gala</a>
    * @version $Id$
    */
  -public class CastorPsmlManagerService extends TurbineBaseService
  -    implements PsmlManagerService
  +public class CastorPsmlManagerService extends TurbineBaseService 
  +                                      implements FileCacheEventListener,
  +                                                 PsmlManagerService
   {
       // resource path constants
       protected static final String PATH_GROUP              = "group";
  @@ -137,6 +142,8 @@
       // configuration keys
       protected final static String CONFIG_ROOT             = "root";
       protected final static String CONFIG_EXT              = "ext";
  +    protected final static String CONFIG_SCAN_RATE        = "scanRate";
  +    protected final static String CONFIG_CACHE_SIZE       = "cacheSize";
   
       // default configuration values
       public final static String DEFAULT_ROOT             = "/WEB-INF/psml";
  @@ -153,16 +160,16 @@
       protected String ext;
   
       /** The documents loaded by this manager */
  -    protected Map documents = new HashMap();
  -
  -    /** The watcher for the document locations */
  -    protected DocumentWatcher watcher = null;
  +    protected FileCache documents = null;
   
       /** the output format for pretty printing when saving registries */
       protected OutputFormat format = null;
   
       /** the base refresh rate for documents */
  -    protected long scanRate = 1000 * 60;
  +    protected long scanRate = 1000 * 60; // every minute
  +
  +    /** the default cache size */
  +    protected int cacheSize = 100;
   
       /** the import/export consumer service **/
       protected PsmlManagerService consumer = null;
  @@ -233,8 +240,13 @@
           mapFile = TurbineServlet.getRealPath( mapFile );
           loadMapping();
   
  -        this.watcher = new DocumentWatcher();
  -        this.watcher.start();
  +        this.scanRate = serviceConf.getLong(CONFIG_SCAN_RATE, this.scanRate);
  +        this.cacheSize= serviceConf.getInt(CONFIG_CACHE_SIZE, this.cacheSize);
  +
  +        documents = new FileCache(this.scanRate, this.cacheSize);
  +        documents.addListener(this);
  +        documents.startFileScanner();
  +
   
           //Mark that we are done
           setInit(true);
  @@ -269,7 +281,7 @@
        */
       public void shutdown()
       {
  -        this.watcher.setDone(true);
  +        documents.stopFileScanner();
       }
   
       /**
  @@ -295,17 +307,8 @@
           }
   
           PSMLDocument doc = null;
  -        WeakReference ref = null;
  -
  -        synchronized (documents)
  -        {
  -            ref = (WeakReference)documents.get(name);
  -        }
   
  -        if (ref != null)
  -        {
  -            doc = (PSMLDocument)ref.get();
  -        }
  +        doc = (PSMLDocument)documents.getDocument(name);
   
           if (doc == null)
           {
  @@ -314,7 +317,14 @@
               synchronized (documents)
               {
                   // store the document in the hash and reference it to the watcher
  -                documents.put(name, new WeakReference(doc));
  +                try
  +                {
  +                    documents.put(name, doc);
  +                }
  +                catch (java.io.IOException e)
  +                {
  +                    Log.error("Error puttin document: " + e);
  +                }
               }
           }
   
  @@ -354,31 +364,9 @@
           }
   
           PSMLDocument doc = null;
  -        WeakReference ref = null;
           Profile profile = null;
   
  -        synchronized (documents)
  -        {
  -            ref = (WeakReference)documents.get(name);
  -        }
  -
  -        if (ref != null)
  -        {
  -            /**
  -             * Christophe Mestrallet ([EMAIL PROTECTED])
  -             * detected problems here.
  -             * Since there is a fallback (reloading) I (SGP) will
  -             * just catch the exception. The real problem is down, when
  -             * we used a null profile as a key (profile --> newProfile)
  -             */
  -            try
  -            {
  -                profile = (Profile)ref.get();
  -            } catch ( ClassCastException e )
  -            {
  -                Log.error( e );
  -            }
  -        }
  +        profile = (Profile)documents.getDocument(name);
   
           if (profile == null)
           {
  @@ -397,11 +385,20 @@
                   // store the document in the hash and reference it to the watcher
                   Profile newProfile = createProfile(locator);
                   newProfile.setDocument(doc);
  -                documents.put(name, new WeakReference(newProfile));
  +                try
  +                {
  +                    documents.put(name, newProfile);
  +                }
  +                catch (IOException e)
  +                {
  +                    Log.error("Error putting document: " + e);
  +                }
               }
           }
           else
  +        {
               doc = profile.getDocument();
  +        }
   
           return doc;
       }
  @@ -444,26 +441,26 @@
   
                   doc.setPortlets(portlets);
   
  -                if (this.watcher != null)
  -                {
  -                    this.watcher.addFile(fileOrUrl,f);
  -                }
               }
               catch (IOException e)
               {
                   Log.error("PSMLManager: Could not load the file 
"+f.getAbsolutePath(), e);
  +                doc = null;
               }
               catch (MarshalException e)
               {
                   Log.error("PSMLManager: Could not unmarshal the file 
"+f.getAbsolutePath(), e);
  +                doc = null;
               }
               catch (MappingException e)
               {
                   Log.error("PSMLManager: Could not unmarshal the file 
"+f.getAbsolutePath(), e);
  +                doc = null;
               }
               catch (ValidationException e)
               {
                   Log.error("PSMLManager: document "+f.getAbsolutePath()+" is not 
valid", e);
  +                doc = null;
               }
               finally
               {
  @@ -474,57 +471,6 @@
           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("PSMLManager: 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);
  -    }
  -
       /** Store the PSML document on disk, using its locator
        *
        * @param profile the profile locator description.
  @@ -554,7 +500,14 @@
           // update it in cache
           synchronized (documents)
           {
  -            documents.put(fullpath, new WeakReference(profile));
  +            try
  +            {
  +                documents.put(fullpath, profile);
  +            }
  +            catch (IOException e)
  +            {
  +                Log.error("Error storing document: " + e);
  +            }
           }
   
           return ok;
  @@ -739,83 +692,6 @@
           return null;
       }
   
  -    protected class DocumentWatcher extends Thread
  -    {
  -        protected Map fileToName = new HashMap();
  -        protected Map fileToDate = new HashMap();
  -        protected 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.info("DocumentWatcher: recieved interruption, aborting.");
  -            }
  -        }
  -
  -    }
  -
       /** Create a new document.
        *
        * @param profile The description and default value for the new document.
  @@ -923,7 +799,6 @@
           {
               documents.remove(name);
           }
  -// TODO:   this.watcher.removeFile(file);
   
           file.delete();
   
  @@ -965,16 +840,19 @@
           synchronized (documents)
           {
               DirectoryUtils.rmdir(name);
  -            Iterator it = documents.entrySet().iterator();
  +            Iterator it = documents.getIterator();
               while (it.hasNext())
               {
  -                Map.Entry entry = (Map.Entry)it.next();
  -                WeakReference ref = (WeakReference)entry.getValue();
  -                if (null == ref)
  +                FileCacheEntry entry = (FileCacheEntry)it.next();
  +                if (null == entry)
  +                {
                       continue;
  -                Profile profile = (Profile)ref.get();
  +                }
  +                Profile profile = (Profile)entry.getDocument();
                   if (null == profile)
  +                {
                       continue;
  +                }
                   JetspeedUser pUser = profile.getUser();
                   if (null != pUser && pUser.getUserName().equals(user.getUserName()))
                   {
  @@ -1021,16 +899,19 @@
           synchronized (documents)
           {
               DirectoryUtils.rmdir(name);
  -            Iterator it = documents.entrySet().iterator();
  +            Iterator it = documents.getIterator();
               while (it.hasNext())
               {
  -                Map.Entry entry = (Map.Entry)it.next();
  -                WeakReference ref = (WeakReference)entry.getValue();
  -                if (null == ref)
  +                FileCacheEntry entry = (FileCacheEntry)it.next();
  +                if (null == entry)
  +                {
                       continue;
  -                Profile profile = (Profile)ref.get();
  +                }
  +                Profile profile = (Profile)entry.getDocument();
                   if (null == profile)
  +                {
                       continue;
  +                }
                   Role pRole = profile.getRole();
                   if (null != pRole && pRole.getName().equals(role.getName()))
                   {
  @@ -1076,16 +957,19 @@
           synchronized (documents)
           {
               DirectoryUtils.rmdir(name);
  -            Iterator it = documents.entrySet().iterator();
  +            Iterator it = documents.getIterator();
               while (it.hasNext())
               {
  -                Map.Entry entry = (Map.Entry)it.next();
  -                WeakReference ref = (WeakReference)entry.getValue();
  -                if (null == ref)
  +                FileCacheEntry entry = (FileCacheEntry)it.next();
  +                if (null == entry)
  +                {
                       continue;
  -                Profile profile = (Profile)ref.get();
  +                }
  +                Profile profile = (Profile)entry.getDocument();
                   if (null == profile)
  +                {
                       continue;
  +                }
                   Group pGroup = profile.getGroup();
                   if (null != pGroup && pGroup.getName().equals(group.getName()))
                   {
  @@ -1653,6 +1537,31 @@
           }
   
           System.out.println("----------------------");
  +    }
  +
  +    /**
  +     * Refresh event, called when the entry is being refreshed from file system.
  +     *
  +     * @param entry the entry being refreshed.
  +     */
  +    public void refresh(FileCacheEntry entry)
  +    {
  +        System.out.println("entry is refreshing: " + entry.getFile().getName());
  +        Profile profile = (Profile) entry.getDocument();
  +        if (profile != null)
  +        {
  +            profile.setDocument(loadDocument(entry.getFile().getName()));
  +        }
  +    }
  +
  +    /**
  +     * Evict event, called when the entry is being evicted out of the cache
  +     *
  +     * @param entry the entry being refreshed.
  +     */
  +    public void evict(FileCacheEntry entry)
  +    {
  +        System.out.println("entry is evicting: " + entry.getFile().getName());
       }
   
   }
  
  
  
  1.1                  jakarta-jetspeed/test/testdata/psml/user/cachetest/default.psml
  
  Index: default.psml
  ===================================================================
  <?xml version="1.0" encoding="iso-8859-1"?>
  <portlets id="100" xmlns="http://xml.apache.org/jetspeed/2000/psml";>
      <metainfo>
        <title>Default Jetspeed Page</title>
      </metainfo>
  
    <control name="TabControl"/>
  
    <controller name="CardPortletController">
      <parameter name="parameter" value="pane"/>
    </controller>
  
    <skin name="orange-grey"/>
  
    <portlets id="101">
      <controller name="RowController">
        <parameter name="sizes" value="66%,34%"/>
      </controller>
  
      <metainfo>
        <title>Home Page</title>
      </metainfo>
  
      <portlets id="102">
        <entry id="103" parent="JetspeedContent"/>
      </portlets>
  
      <portlets id="104">
        <entry id="105" parent="Jetspeed"/>
        <entry id="106" parent="Welcome"/>
      </portlets>
  
    </portlets>
  
    <portlets id="107">
      <metainfo>
        <title>RSS</title>
      </metainfo>
  
      <portlets id="108">
        <control name="TabControl"/>
        <controller name="CardPortletController">
          <parameter name="defaultcard" value="0"/>
          <parameter name="parameter" value="channel"/>
          <parameter name="ruler-size" value="0"/>
        </controller>      
  
        <entry id="109" 
parent="http://jakarta.apache.org/jetspeed/channels/jetspeed.rss";>
          <control name="ClearPortletControl"/>
        </entry>
  
        <entry id="110" 
parent="http://jakarta.apache.org/jetspeed/channels/turbine.rss";>
          <control name="ClearPortletControl"/>
        </entry>
  
        <entry id="111" parent="http://www.mozilla.org/news.rdf";>
          <control name="ClearPortletControl"/>
          <parameter name="itemdisplayed" value="5"/>
        </entry>
  
        <entry id="112" 
parent="http://www.apacheweek.com/issues/apacheweek-headlines.xml";>
          <control name="ClearPortletControl"/>
          <parameter name="showtitle" value="false"/>
          <parameter name="showdescription" value="false"/>
        </entry>
  
        <entry id="113" parent="http://www.xmlhack.com/rsscat.php";>
          <control name="ClearPortletControl"/>
        </entry>
  
        <entry id="123" parent="BBCFrontPage">
          <control name="ClearPortletControl"/>
        </entry>
  
      </portlets>
    </portlets>
  
    <portlets id="114">
      <controller name="TwoColumns"/>
  
      <metainfo>
        <title>Dynamic</title>
      </metainfo>
  
      <portlets id="115">
        <entry id="116" parent="JetspeedContent"/>
        <layout>
                <property name="row" value="0"/>
                <property name="column" value="0"/>
        </layout>
      </portlets>
  
      <portlets id="117">
        <entry id="118" parent="HelloVelocity"/>
        <layout>
                <property name="row" value="0"/>
                <property name="column" value="1"/>
        </layout>
      </portlets>
  
      <portlets id="119">
        <entry id="120" parent="HelloVelocityCached"/>
        <entry id="808" parent="InstanceExample">
            <parameter name="country" value="Brazil"/>
        </entry>
        <entry id="809" parent="InstanceExample">
            <parameter name="country" value="Germany"/>
        </entry>
        <layout>
                <property name="row" value="1"/>
                <property name="column" value="1"/>
        </layout>
      </portlets>
  
      <portlets id="121">
        <entry id="122" parent="HelloJSP"/>
        <layout>
                <property name="row" value="1"/>
                <property name="column" value="0"/>
        </layout>
      </portlets>
      
    </portlets>
  </portlets>
  
  
  
  1.92      +7 -1      
jakarta-jetspeed/webapp/WEB-INF/conf/JetspeedResources.properties
  
  Index: JetspeedResources.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-jetspeed/webapp/WEB-INF/conf/JetspeedResources.properties,v
  retrieving revision 1.91
  retrieving revision 1.92
  diff -u -r1.91 -r1.92
  --- JetspeedResources.properties      30 Oct 2002 15:55:50 -0000      1.91
  +++ JetspeedResources.properties      14 Nov 2002 06:52:41 -0000      1.92
  @@ -357,6 +357,12 @@
   #services.PsmlManager.media-types=html:wml
   #services.PsmlManager.admin=admin
   
  +## only used by Castor(File) PSML Manager 
  +# scan rate in seconds (every 2 minutes)
  +services.PsmlManager.scanRate=120
  +# cache size - number of PSML pages to cache
  +services.PsmlManager.cacheSize=100
  +
   #########################################
   # Portlet Factory                       #
   #########################################
  
  
  
  1.42      +0 -0      jakarta-jetspeed/webapp/WEB-INF/conf/JetspeedSecurity.properties
  
  Index: JetspeedSecurity.properties
  ===================================================================
  RCS file: 
/home/cvs/jakarta-jetspeed/webapp/WEB-INF/conf/JetspeedSecurity.properties,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -r1.41 -r1.42
  
  
  
  1.1                  jakarta-jetspeed/webapp/WEB-INF/conf/HttpAgentLog4j.properties
  
  Index: HttpAgentLog4j.properties
  ===================================================================
  # log4j.rootLogger=debug, stdout, AgentFile
  log4j.rootLogger=debug, AgentFile
  
  log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  
  # Pattern to output the caller's file name and line number.
  log4j.appender.stdout.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} %5p [%t] 
(%C.%M:%L) - %m%n
  
  log4j.appender.AgentFile=org.apache.log4j.RollingFileAppender
  log4j.appender.AgentFile.File=httpAgent.log
  
  log4j.appender.AgentFile.MaxFileSize=100KB
  # Keep 10 backup files
  log4j.appender.AgentFile.MaxBackupIndex=10
  
  log4j.appender.AgentFile.layout=org.apache.log4j.PatternLayout
  log4j.appender.AgentFile.layout.ConversionPattern=%d{dd MMM yyyy HH:mm:ss} %5p [%t] 
(%C.%M:%L) - %m%n
  
  
  

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

Reply via email to