© 1999-2003, Flemming Koch Jensen
Alle rettigheder forbeholdt
Visitor Pattern
Vejledende løsninger

 

 

1 FileNode og FileVisitor klasserne tages fra kapitlet, og StringFileFilter-klassen tages fra den vejledende løsning til opgaven, der er henvist til i opgaveteksten.
Vi skal dernæst til at lave de tre nye visitors. Da de alle har en filter-egenskab, ud over at være FileVisitors, laves der en fælles abstrakt superklasse til denne egenskab.
import java.io.*;

public abstract class FilteredVisitor implements FileVisitor {
  protected FileFilter filter;

  public void setFilter( FileFilter filter ) {
    this.filter = filter;
  }
}
Dernæst lave de enkelte visitors som subklasser til denne klasse:
import java.io.*;

public class DirCountFileVisitor extends FilteredVisitor {
  private int dirs;
  
  public DirCountFileVisitor() {
    dirs = 0;
  }
  
  public int getDirs() {
    return dirs;
  }
  
  public void visit( File f ) {
    if ( filter.accept( f ) ) {
      if ( f.isDirectory() )
        dirs++;
    }
  }
}
import java.io.*;

public class TotalSizeFileVisitor extends FilteredVisitor {
  private long totalSize;
  
  public TotalSizeFileVisitor() {
    totalSize = 0;
  }
  
  public long getTotalSize() {
    return totalSize;
  }
  
  public void visit( File f ) {
    if ( filter.accept( f ) )
      if ( f.isFile() )
        totalSize += f.length();
  }
}
De to første er meget simple, mens den tredie visitor er mere kompliceret - primært pga. arbejdet med filenavne.
import java.io.*;

public class ReplaceCharFileVisitor extends FilteredVisitor {
  private char target, replace;
  
  public ReplaceCharFileVisitor() {
    this( '_', ' ' );
  }
  public ReplaceCharFileVisitor( char target, char replace ) {
    this.target = target;
    this.replace = replace;
  }
  
  public void visit( File f ) {
    if ( filter.accept( f ) ) {
      if ( f.isFile() ) {
        String newName = f.getName().replace( target, replace );

        String path = f.getAbsolutePath();
        path = path.substring( 0, path.lastIndexOf( '\\' ) );
        
        f.renameTo( new File( path + "\\" + newName ) );
      }
    }
  }
}
Dernæst laves en testanvendelse. Bemærk, at denne er opdelt i tre metoder der udgør en testanvendelse for hver af de tre visitors.
import java.io.*;

class Main {
  
  public static void main( String[] argv ) {
    test3();
  }
  
  private static void test1() {
    FileNode root = new FileNode( new File( "." ) );
    StringFileFilter filter = new StringFileFilter();
    filter.add( "*.java" );
    
    TotalSizeFileVisitor visitor = new TotalSizeFileVisitor();
    visitor.setFilter( filter );
    root.accept( visitor );
    
    System.out.println( visitor.getTotalSize() );
  }
  
  private static void test2() {
    FileNode root = new FileNode( new File( ".." ) );
    StringFileFilter filter = new StringFileFilter();
    filter.add( "*" );
    
    DirCountFileVisitor visitor = new DirCountFileVisitor();
    visitor.setFilter( filter );
    root.accept( visitor );
    
    System.out.println( visitor.getDirs() );
  }
  
  private static void test3() {
    FileNode root = new FileNode( new File( "testdir" ) );
    StringFileFilter filter = new StringFileFilter();
    filter.add( "*" );
    
    ReplaceCharFileVisitor visitor =
      new ReplaceCharFileVisitor( 'e', 'ø' );
    visitor.setFilter( filter );
    root.accept( visitor );
  }
}

Kildetekster:

Main.java
FileNode.java
FileVisitor.java
StringFileFilter.java
FilteredVisitor.java
DirCountFileVisitor.java
TotalSizeFileVisitor.java
ReplaceCharFileVisitor.java