View Javadoc

1   package rydeen.io;
2   
3   import java.io.IOException;
4   import java.util.ArrayList;
5   import java.util.Iterator;
6   import java.util.List;
7   import java.util.NoSuchElementException;
8   
9   import rydeen.ProcessTarget;
10  import rydeen.TargetSource;
11  import rydeen.utils.NullIterator;
12  
13  /**
14   * <p>
15   * 複数のTargetSourceを1つのTargetSourceとして扱うクラスです.
16   * </p>
17   * @author Haruaki Tamada
18   */
19  public class MultipleTargetSource implements TargetSource{
20      private List<TargetSource> list = new ArrayList<TargetSource>();
21  
22      /**
23       * 指定されたTargetSourceのリストをまとめるTargetSourceを構築します.
24       */
25      public MultipleTargetSource(TargetSource... sources){
26          for(TargetSource source: sources){
27              list.add(source);
28          }
29      }
30  
31      /**
32       * このTargetSourceの名前を返します.
33       * このオブジェクトが保持する全てのTargetSourceの名前をコンマ「,」
34       * で区切った文字列がこのオブジェクトの名前になります.
35       */
36      @Override
37      public String getName(){
38          StringBuilder sb = new StringBuilder();
39          for(int i = 0; i < list.size(); i++){
40              if(i != 0){
41                  sb.append(", ");
42              }
43              sb.append(list.get(i).getName());
44          }
45          return new String(sb);
46      }
47  
48      /**
49       * このオブジェクトが保持するProcessTargetの列挙を返します.
50       * 全てのTargetSourceから順にProcessTargetを取り出す列挙を返します.
51       */
52      @Override
53      public Iterator<ProcessTarget> iterator(){
54          return new MultipleTargetSourceIterator(this, list);
55      }
56  
57      /**
58       * このオブジェクトが保持する全てのTargetSourceのcloseメソッドを呼び出します.
59       */
60      @Override
61      public void close() throws IOException{
62          for(TargetSource target: list){
63              target.close();
64          }
65      }
66  
67      /**
68       * このTargetSourceが指定された文字列が表すデータを保持していればtrueを返します.
69       */
70      @Override
71      public boolean contains(String target){
72          boolean flag = false;
73          for(TargetSource source: list){
74              if(source.contains(target)){
75                  flag = true;
76                  break;
77              }
78          }
79          return flag;
80      }
81  
82      private static final class MultipleTargetSourceIterator implements Iterator<ProcessTarget>{
83          private List<TargetSource> list;
84          private Iterator<ProcessTarget> currentIterator;
85          private int current = 1;
86          private TargetSource source;
87  
88          public MultipleTargetSourceIterator(TargetSource source, List<TargetSource> list){
89              this.source = source;
90              this.list = list;
91              if(list.size() > 0){
92                  currentIterator = list.get(0).iterator();
93              }
94              else{
95                  currentIterator = new NullIterator<ProcessTarget>();
96              }
97          }
98  
99          @Override
100         public boolean hasNext(){
101             while(current < list.size()){
102                 boolean next = currentIterator.hasNext();
103                 if(next){
104                     return true;
105                 }
106                 currentIterator = list.get(current).iterator();
107                 current++;
108             }
109             return false;
110         }
111 
112         @Override
113         public ProcessTarget next(){
114             if(!currentIterator.hasNext()){
115                 while(current < list.size()){
116                     currentIterator = list.get(current).iterator();
117                     if(currentIterator.hasNext()){
118                         return buildProcessTarget(source, currentIterator.next());
119                     }
120                     current++;
121                 }
122                 throw new NoSuchElementException();
123             }
124             return buildProcessTarget(source, currentIterator.next());
125         }
126 
127         @Override
128         public void remove(){
129         }
130 
131         private ProcessTarget buildProcessTarget(TargetSource source, ProcessTarget target){
132             if(target.getTargetSource() != source){
133                 if(target instanceof DelegateProcessTarget){
134                     ((DelegateProcessTarget)target).setTargetSource(source);
135                 }
136                 else{
137                     target = new DelegateProcessTarget(source, target);
138                 }
139             }
140             return target;
141         }
142     }
143 }