1 /** 
   2  * VisitorPattern example
   3  */
   4 
   5 import java.util.Iterator;
   6 import java.util.Vector;
   7 
   8 abstract class Visitor {
   9     public abstract void visit(File file);
  10     public abstract void visit(Directory directory);
  11 }
  12 
  13 interface Acceptor {
  14     public abstract void accept(Visitor v);
  15 }
  16 
  17 abstract class Entry implements Acceptor {
  18     public abstract String getName();
  19     public abstract int getSize();
  20     public Entry add(Entry entry) throws FileTreatmentException {
  21         throw new FileTreatmentException();
  22     }
  23     public Iterator iterator() throws FileTreatmentException {
  24         throw new FileTreatmentException();
  25     }
  26     public String toString() {
  27         return getName() + " (" + getSize() + ")";
  28     }
  29 }
  30 
  31 class File extends Entry {
  32     private String name;
  33     private int size;
  34     public File(String name, int size) {
  35         this.name = name;
  36         this.size = size;
  37     }
  38     public String getName() {
  39         return name;
  40     }
  41     public int getSize() {
  42         return size;
  43     }
  44     public void accept(Visitor v) {
  45         v.visit(this);
  46     }
  47 }
  48 
  49 class Directory extends Entry {
  50     private String name;
  51     private Vector dir = new Vector();
  52     public Directory(String name) {
  53         this.name = name;
  54     }
  55     public String getName() {
  56         return name;
  57     }
  58     public int getSize() {
  59         int size = 0;
  60         Iterator it = dir.iterator();
  61         while(it.hasNext()) {
  62             Entry entry = (Entry)it.next();
  63             size += entry.getSize();
  64         }
  65         return size;
  66     }
  67     public Entry add(Entry entry) {
  68         dir.add(entry);
  69         return this;
  70     }
  71     public Iterator iterator() {
  72         return dir.iterator();
  73     }
  74     public void accept(Visitor v) {
  75         v.visit(this);
  76     }
  77 }
  78 
  79 class ListVisitor extends Visitor {
  80     private String currentdir = "";
  81     public void visit(File file) {
  82         System.out.println(currentdir + "/" + file);
  83     }
  84     public void visit(Directory directory) {
  85         System.out.println(currentdir + "/" + directory);
  86         String savedir = currentdir;
  87         currentdir = currentdir + "/" + directory.getName();
  88         Iterator it = directory.iterator();
  89         while(it.hasNext()) {
  90             Entry entry = (Entry)it.next();
  91             entry.accept(this);
  92         }
  93         currentdir = savedir;
  94     }
  95 }
  96 
  97 class FileTreatmentException extends RuntimeException {
  98     public FileTreatmentException() {
  99     }
 100     public FileTreatmentException(String msg) {
 101         super(msg);
 102     }
 103 }
 104 
 105 public class VisitorDirectory {
 106     public static void main(String[] args) {
 107         try {
 108             System.out.println("Making root entries...");
 109             Directory root = new Directory("root");
 110             Directory bin = new Directory("bin");
 111             Directory usr = new Directory("usr");
 112             root.add(bin);
 113             root.add(usr);
 114             bin.add(new File("vi",10000));
 115             bin.add(new File("latex",20000));
 116             root.accept(new ListVisitor());
 117         } catch(FileTreatmentException e) {
 118             e.printStackTrace();
 119         }
 120     }
 121 }
web biohackers.net