OSDN Git Service

38aa9a216b9f3b7d239eb94c4d6c632c213993b2
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / result / RoundRobinComparisonResultSet.java
1 package jp.sourceforge.stigmata.result;
2
3 /*
4  * $Id$
5  */
6
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.HashMap;
10 import java.util.Iterator;
11 import java.util.List;
12 import java.util.Map;
13
14 import jp.sourceforge.stigmata.BirthmarkContext;
15 import jp.sourceforge.stigmata.BirthmarkEnvironment;
16 import jp.sourceforge.stigmata.BirthmarkSet;
17 import jp.sourceforge.stigmata.ComparisonPair;
18 import jp.sourceforge.stigmata.ExtractionResultSet;
19 import jp.sourceforge.stigmata.ExtractionTarget;
20
21 /**
22  * Concrete class for ComparisonResultSet. This instance compare class files by round robin.
23  *
24  * @author  Haruaki TAMADA
25  * @version  $Revision$ 
26  */
27 public class RoundRobinComparisonResultSet extends AbstractComparisonResultSet{
28     private int compareCount = -1;
29     private boolean tableType;
30     private boolean samePair = false;
31
32     /**
33      * constructor.  if user gives { a, b, c, } as holders1, then
34      * the instance (created by this constructor) compares { a<->b, a<->c,
35      * b<->c, }.
36      */
37     public RoundRobinComparisonResultSet(ExtractionResultSet resultset){
38         this(resultset, false);
39     }
40
41     /**
42      * constructor.  if user gives { a, b, c, } as holders1, then the
43      * instance (created by this constructor when samePair is true)
44      * compares { a<->a, b<->a, b<->b, c<->a, c<->b, c<->c, }.
45      * Otherwise, the instance compares { a<->b, a<->c, b<->c, } when
46      * samePair is false.
47      */
48     public RoundRobinComparisonResultSet(ExtractionResultSet resultset, boolean samePair){
49         super(resultset);
50         this.tableType = resultset.isTableType();
51         setCompareSamePair(samePair);
52     }
53
54     /**
55      * @return  environment
56      */
57     public BirthmarkEnvironment getEnvironment(){
58         return extraction.getEnvironment();
59     }
60
61     public BirthmarkContext getContext(){
62         return extraction.getContext();
63     }
64
65     /**
66      * update same pair comparing flag unless two birthmark array is setted.
67      */
68     public void setCompareSamePair(boolean flag){
69         samePair = flag;
70         if(!extraction.isTableType()){
71             int size = extraction.getBirthmarkSetSize(ExtractionTarget.TARGET_XY);
72             if(flag){
73                 if(size > 1)       compareCount = (size - 1) * (size - 2) + 1;
74                 else if(size == 1) compareCount = 0;
75                 else throw new IllegalStateException("no extraction result");
76             }
77             else{
78                 if(size > 1)       compareCount = (size - 1) * (size - 2) + 1 + size;
79                 else if(size == 1) compareCount = 1;
80                 else throw new IllegalStateException("no extraction result");
81             }
82         }
83         else if(compareCount == -1){
84             compareCount = extraction.getBirthmarkSetSize(ExtractionTarget.TARGET_X)
85                     * extraction.getBirthmarkSetSize(ExtractionTarget.TARGET_Y); 
86         }
87     }
88
89     public boolean isCompareSamePair(){
90         return samePair;
91     }
92
93     /**
94      * returns the compare count of birthmark sets.
95      */
96     public int getPairCount(){
97         return compareCount;
98     }
99
100     /**
101      * return a iterator of whole comparison.
102      */
103     public Iterator<ComparisonPair> iterator(){
104         if(tableType){
105             return new CompareTableIterator();
106         }
107         else{
108             return new CompareTriangleIterator();
109         }
110     }
111
112     public BirthmarkSet[] getPairSources(){
113         List<BirthmarkSet> list = new ArrayList<BirthmarkSet>();
114         for(Iterator<BirthmarkSet> i = pairSources(); i.hasNext(); ){
115             list.add(i.next());
116         }
117
118         return list.toArray(new BirthmarkSet[list.size()]);
119     }
120
121     public Iterator<BirthmarkSet> pairSources(){
122         Map<URL, BirthmarkSet> map = new HashMap<URL, BirthmarkSet>();
123         if(extraction.isTableType()){
124             for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_X); i.hasNext(); ){
125                 BirthmarkSet bs = i.next();
126                 map.put(bs.getLocation(), bs);
127             }
128             for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_Y); i.hasNext(); ){
129                 BirthmarkSet bs = i.next();
130                 map.put(bs.getLocation(), bs);
131             }
132         }
133         else{
134             for(Iterator<BirthmarkSet> i = extraction.birthmarkSets(ExtractionTarget.TARGET_XY); i.hasNext(); ){
135                 BirthmarkSet bs = i.next();
136                 map.put(bs.getLocation(), bs);
137             }
138         }
139         return map.values().iterator();
140     }
141
142     private class CompareTableIterator implements Iterator<ComparisonPair>{
143         private Iterator<BirthmarkSet> ix = extraction.birthmarkSets(ExtractionTarget.TARGET_X);
144         private Iterator<BirthmarkSet> iy = extraction.birthmarkSets(ExtractionTarget.TARGET_Y);
145         private BirthmarkSet x = ix.next();
146
147         public boolean hasNext(){
148             return ix.hasNext() || iy.hasNext();
149         }
150
151         public ComparisonPair next(){
152             if(!iy.hasNext()){
153                 iy = extraction.birthmarkSets(ExtractionTarget.TARGET_Y);
154                 x = ix.next();
155             }
156             BirthmarkSet y = iy.next();
157
158             return new ComparisonPair(x, y, extraction.getContext());
159         }
160
161         public void remove(){
162         }
163     }
164
165     /**
166      * iterator class.
167      */
168     private class CompareTriangleIterator implements Iterator<ComparisonPair>{
169         private List<String> names = new ArrayList<String>();
170         private Iterator<BirthmarkSet> iterator;
171         private int index = 0;
172         private BirthmarkSet bs;
173         private ComparisonPair next;
174
175         public CompareTriangleIterator(){
176             iterator = extraction.birthmarkSets(ExtractionTarget.TARGET_XY);
177             next = findNext();
178         }
179         public boolean hasNext(){
180             return next != null;
181         }
182
183         public ComparisonPair next(){
184             ComparisonPair returnValue = next;
185             next = findNext();
186             return returnValue;
187         }
188
189         private ComparisonPair findNext(){
190             if(bs == null && iterator.hasNext()){
191                 bs = iterator.next();
192                 names.add(bs.getName());
193             }
194             if((isCompareSamePair() && index == names.size()) || (!isCompareSamePair() && index == (names.size() - 1))){
195                 index = 0;
196                 if(iterator.hasNext()){
197                     bs = iterator.next();
198                     names.add(bs.getName());
199                 }
200                 else{
201                     return null;
202                 }
203             }
204             String name = names.get(index);
205             BirthmarkSet bsX = extraction.getBirthmarkSet(ExtractionTarget.TARGET_XY, name);
206             ComparisonPair pair = null;
207             if(bsX != null){
208                 pair = new ComparisonPair(bsX, bs, extraction.getContext());
209             }
210             index++;
211
212             if(pair == null){
213                 pair = findNext();
214             }
215             
216             return pair;
217         }
218
219         public void remove(){
220         }
221     }
222 }