You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by do...@apache.org on 2002/09/08 04:30:48 UTC

cvs commit: jakarta-avalon-excalibur/monitor/src/test/org/apache/avalon/excalibur/monitor/test DirectoryTestCase.java DirectoryTestCaseListener.java

donaldp     2002/09/07 19:30:48

  Added:       monitor/src/java/org/apache/avalon/excalibur/monitor
                        DirectoryResource.java
               monitor/src/test/org/apache/avalon/excalibur/monitor/test
                        DirectoryTestCase.java
                        DirectoryTestCaseListener.java
  Log:
  Add a class to represent a Directory resource. It will send messages whenever a file is added, removed or modified in a directory.
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/monitor/src/java/org/apache/avalon/excalibur/monitor/DirectoryResource.java
  
  Index: DirectoryResource.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.monitor;
  
  import java.io.File;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  
  /**
   * This is a Resource that monitors a directory. If any files
   * are added, removed or modified in directory then it will
   * send an event indicating the change.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/09/08 02:30:48 $
   */
  public class DirectoryResource
      extends Resource
  {
      public static final String ADDED = "AddedFiles";
      public static final String REMOVED = "DeletedFiles";
      public static final String MODIFIED = "ModifiedFiles";
  
      private final File m_dir;
      private Set m_files;
      private Map m_times;
  
      public DirectoryResource( final String resourceKey )
          throws Exception
      {
          super( resourceKey );
          m_dir = new File( resourceKey );
          if( !m_dir.isDirectory() )
          {
              final String message = m_dir + " is not a directory.";
              throw new IllegalArgumentException( message );
          }
  
          m_files = new HashSet();
          m_times = new HashMap();
  
          final File[] files = m_dir.listFiles();
          for( int i = 0; i < files.length; i++ )
          {
              final File file = files[ i ];
              m_files.add( file );
              m_times.put( file, new Long( file.lastModified() ) );
          }
          setPreviousModified( System.currentTimeMillis() );
      }
  
      /**
       * Test whether this has been modified since time X
       */
      public void testModifiedAfter( final long time )
      {
          if( getPreviousModified() > time )
          {
              return;
          }
  
          final HashSet existingFiles = new HashSet();
          final HashSet modifiedFiles = new HashSet();
          final HashSet addedFiles = new HashSet();
  
          final File[] files = m_dir.listFiles();
          for( int i = 0; i < files.length; i++ )
          {
              final File file = files[ i ];
              final long newModTime = file.lastModified();
              if( m_files.contains( file ) )
              {
                  existingFiles.add( file );
  
                  final Long oldModTime = (Long)m_times.get( file );
                  if( oldModTime.longValue() != newModTime )
                  {
                      modifiedFiles.add( file );
                  }
              }
              else
              {
                  addedFiles.add( file );
              }
              m_times.put( file, new Long( newModTime ) );
          }
  
          final int lastCount = m_files.size();
          final int addedCount = addedFiles.size();
          final int modifiedCount = modifiedFiles.size();
  
          //If no new files have been added and
          //none deleted then nothing to do
          if( files.length == lastCount &&
              0 == addedCount &&
              0 == modifiedCount )
          {
              return;
          }
  
          final HashSet deletedFiles = new HashSet();
  
          //If only new files were added and none were changed then
          //we don't have to scan for deleted files
          if( files.length != lastCount + addedCount )
          {
              //Looks like we do have to scan for deleted files
              final Iterator iterator = m_files.iterator();
              while( iterator.hasNext() )
              {
                  final File file = (File)iterator.next();
                  if( !existingFiles.contains( file ) )
                  {
                      deletedFiles.add( file );
                      m_times.remove( file );
                  }
              }
          }
  
          final int deletedCount = deletedFiles.size();
          if( 0 != deletedCount )
          {
              getEventSupport().firePropertyChange( REMOVED,
                                                    Collections.EMPTY_SET,
                                                    deletedFiles );
          }
          if( 0 != addedCount )
          {
              getEventSupport().firePropertyChange( ADDED,
                                                    Collections.EMPTY_SET,
                                                    addedFiles );
          }
  
          if( 0 != modifiedCount )
          {
              getEventSupport().firePropertyChange( MODIFIED,
                                                    Collections.EMPTY_SET,
                                                    modifiedFiles );
          }
  
          m_files = existingFiles;
      }
  
      public long lastModified()
      {
          return getPreviousModified();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/monitor/src/test/org/apache/avalon/excalibur/monitor/test/DirectoryTestCase.java
  
  Index: DirectoryTestCase.java
  ===================================================================
  /*
   * Copyright (c) The Apache Software Foundation.  All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.avalon.excalibur.monitor.test;
  
  import java.io.File;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.util.Collections;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Set;
  import junit.framework.TestCase;
  import org.apache.avalon.excalibur.monitor.DirectoryResource;
  import org.apache.avalon.framework.logger.ConsoleLogger;
  
  /**
   * Junit TestCase for the directory resource.
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Id: DirectoryTestCase.java,v 1.1 2002/09/08 02:30:48 donaldp Exp $
   */
  public class DirectoryTestCase
      extends TestCase
  {
      public DirectoryTestCase( String name )
      {
          super( name );
      }
  
      public void testDirectoryEvents()
          throws Exception
      {
          final File dir = createDir();
  
          try
          {
              final Set added1 = new HashSet();
              added1.add( "file1.txt" );
              added1.add( "file2.txt" );
              added1.add( "file3.txt" );
              testChanges( added1,
                           Collections.EMPTY_SET,
                           Collections.EMPTY_SET,
                           dir );
  
              final Set mods2 = new HashSet();
              mods2.add( "file2.txt" );
              final Set added2 = new HashSet();
              added2.add( "file4.txt" );
              testChanges( added2,
                           Collections.EMPTY_SET,
                           mods2,
                           dir );
  
              final Set dels = new HashSet();
              dels.add( "file2.txt" );
              testChanges( Collections.EMPTY_SET,
                           dels,
                           Collections.EMPTY_SET,
                           dir );
          }
          finally
          {
              final File[] files = dir.listFiles();
              for( int i = 0; i < files.length; i++ )
              {
                  files[ i ].delete();
              }
          }
      }
  
      private File createDir()
      {
          final File dir = new File( "testDir" );
          dir.mkdir();
          dir.setLastModified( System.currentTimeMillis() );
          return dir;
      }
  
      private void testChanges( final Set added,
                                final Set removed,
                                final Set modified,
                                final File dir )
          throws Exception
      {
          final DirectoryResource resource =
              new DirectoryResource( dir.getCanonicalPath() );
  
          final DirectoryTestCaseListener listener = new DirectoryTestCaseListener();
          listener.enableLogging( new ConsoleLogger() );
          resource.addPropertyChangeListener( listener );
  
          final Iterator adds = added.iterator();
          while( adds.hasNext() )
          {
              final String add = (String)adds.next();
              touchFile( dir, add );
          }
  
          final Iterator mods = modified.iterator();
          while( mods.hasNext() )
          {
              final String mod = (String)mods.next();
              touchFile( dir, mod );
          }
  
          final Iterator rems = removed.iterator();
          while( rems.hasNext() )
          {
              final String rem = (String)rems.next();
              deleteFile( dir, rem );
          }
  
          longDelay();
  
          resource.testModifiedAfter( System.currentTimeMillis() );
          testExpected( "Add", added, listener.getAdded() );
          testExpected( "Remove", removed, listener.getRemoved() );
          testExpected( "Modify", modified, listener.getModified() );
  
          listener.reset();
      }
  
      private void testExpected( final String name,
                                 final Set expected,
                                 final Set actual )
      {
          assertEquals( name + " results count(" +
                        expected + " vs (actual) " +
                        actual,
                        expected.size(),
                        actual.size() );
          final Iterator iterator = actual.iterator();
          while( iterator.hasNext() )
          {
              final File file = (File)iterator.next();
              if( !expected.contains( file.getName() ) )
              {
                  fail( "Missing " + file.getName() +
                        " from expected set " + expected );
              }
          }
      }
  
      private void touchFile( final File dir,
                              final String filename )
          throws IOException
      {
          final File file = new File( dir, filename );
          file.createNewFile();
          final FileWriter writer = new FileWriter( file );
          writer.write( "Meep!" );
          writer.flush();
          writer.close();
          file.setLastModified( System.currentTimeMillis() );
      }
  
      private void deleteFile( final File dir,
                               final String filename )
      {
          final File file = new File( dir, filename );
          if( !file.delete() )
          {
              fail( "Failed to delete file " + file );
          }
      }
  
      /**
       * Some filesystems are not sensitive enough so you need
       * to delay for a long enough period of time (ie 1 second).
       */
      private void longDelay()
      {
          delay( 1000 );
      }
  
      private void delay( final int time )
      {
          try
          {
              Thread.sleep( time ); // sleep 10 millis at a time
          }
          catch( final InterruptedException ie )
          {
              // ignore and keep waiting
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/monitor/src/test/org/apache/avalon/excalibur/monitor/test/DirectoryTestCaseListener.java
  
  Index: DirectoryTestCaseListener.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.monitor.test;
  
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyChangeListener;
  import java.util.Collections;
  import java.util.Set;
  import org.apache.avalon.excalibur.monitor.DirectoryResource;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  class DirectoryTestCaseListener
      extends AbstractLogEnabled
      implements PropertyChangeListener
  {
      private Set m_added = Collections.EMPTY_SET;
      private Set m_removed = Collections.EMPTY_SET;
      private Set m_modified = Collections.EMPTY_SET;
  
      void reset()
      {
          m_added = Collections.EMPTY_SET;
          m_removed = Collections.EMPTY_SET;
          m_modified = Collections.EMPTY_SET;
      }
  
      public Set getAdded()
      {
          return m_added;
      }
  
      public Set getRemoved()
      {
          return m_removed;
      }
  
      public Set getModified()
      {
          return m_modified;
      }
  
      public void propertyChange( final PropertyChangeEvent event )
      {
          final String name = event.getPropertyName();
          final Set newValue = (Set)event.getNewValue();
          if( name.equals( DirectoryResource.ADDED ) )
          {
              m_added = newValue;
          }
          else if( name.equals( DirectoryResource.REMOVED ) )
          {
              m_removed = newValue;
          }
          else
          {
              m_modified = newValue;
          }
      }
  }
  
  
  

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