/Users/lyon/j4p/src/classUtils/pack/util/LineSet.java

1    package classUtils.pack.util; 
2     
3    import java.io.PrintWriter; 
4    import java.io.StringWriter; 
5    import java.util.ArrayList; 
6    import java.util.HashSet; 
7    import java.util.Iterator; 
8    import java.util.List; 
9    import java.util.ListIterator; 
10   import java.util.Set; 
11   import java.util.StringTokenizer; 
12    
13   /** 
14    * An ordered set of Strings, to which filters can be applied 
15    *  
16    * @author cris 
17    */ 
18   public class LineSet { 
19                
20       /** 
21        * A Filter for matching certain lines in the set. 
22        *  
23        * @author cris 
24        */ 
25       public interface Filter { 
26            
27           /** 
28            * Must return <b>true</b> if the given line (at the given position) 
29            * is to be accepted. 
30            *  
31            * @param line the line to be checked 
32            * @param index the position of the line, from the top of the list 
33            * @return boolean <b>true</b> if the given line (at the given position) 
34            *                  is to be accepted. 
35            */ 
36           public boolean match(String line, int index, Set info); 
37            
38           public void onMatch(Set info); 
39        
40       } 
41        
42       public static Filter NULL_FILTER = new NullFilter(); 
43        
44       public abstract static class BaseFilter implements Filter { 
45            
46           /** 
47            * @see classUtils.pack.util.LineSet.Filter#onMatch(java.util.Set) 
48            */ 
49           public void onMatch(Set info) { 
50           } 
51    
52       } 
53        
54       /** 
55        * A constant filter, which always matches or not matches 
56        *  
57        * @author cris 
58        */ 
59       public static class ConstantFilter extends BaseFilter implements Filter { 
60            
61           private boolean toMatch; 
62            
63            
64           public ConstantFilter(boolean toMatch, boolean toCut) { 
65               this.toMatch=toMatch; 
66           } 
67    
68           /** 
69            * @see classUtils.pack.util.LineSet.Filter#match(java.lang.String, int, java.util.Set) 
70            */ 
71           public boolean match(String line, int index, Set info) { 
72               return toMatch; 
73           } 
74       } 
75        
76       /** 
77        * A null line filter, which always matches. 
78        *  
79        * @author cris 
80        */ 
81       private static final class NullFilter extends ConstantFilter{ 
82    
83           /** 
84            * Constructor for NullFilter. 
85            * @param toMatch 
86            */ 
87           private NullFilter() { 
88               super(true, false); 
89           } 
90    
91       } 
92        
93       /** 
94        * A Filter which matches lines containing one or more 
95        * substring. 
96        *  
97        * @author cris 
98        */ 
99       public static final class ContainsStringFilter extends BaseFilter implements Filter { 
100           
101          private  boolean acceptIfYes; 
102          private boolean toCut; 
103          private String [] toCheck; 
104          private int lastMatchIndex=-1; 
105           
106          /** 
107           * Create a filter checking for one or more of the given strings 
108           * being contained.  
109           *  
110           * @param toCheck the strings to be used for matching 
111           * @param toCut indicates whether further lines should be checked 
112           */ 
113          public ContainsStringFilter(String [] toCheck, boolean acceptIfYes, boolean toCut) { 
114              this.acceptIfYes=acceptIfYes; 
115              this.toCheck=toCheck; 
116          } 
117           
118          /** 
119           * Create a filter checking for one or more of the given strings 
120           * being contained; when a matches occurs, the check continues. 
121           *  
122           * @param toCheck the strings to be used for matching 
123           * @param toCut indicates whether further lines should be checked 
124           */ 
125          public ContainsStringFilter(String [] toCheck) { 
126              this(toCheck, true, false); 
127          } 
128           
129          /** 
130           * Create a filter checking for one given string 
131           * being contained. 
132           *  
133           * @param toCheck the string to be used for matching 
134           */ 
135          public ContainsStringFilter(String toCheck, boolean acceptIfYes, boolean toCut) { 
136              this(new String[] { toCheck}, acceptIfYes, toCut); 
137          } 
138           
139          /** 
140           * Create a filter checking for one given string 
141           * being contained; when a matches occurs, the check continues. 
142           *  
143           * @param toCheck the string to be used for matching 
144           */ 
145          public ContainsStringFilter(String toCheck) { 
146              this(toCheck, true, false); 
147          } 
148   
149           
150          /** 
151           * @see classUtils.pack.util.LineSet.Filter#match(java.lang.String, int, java.util.Set) 
152           */ 
153          public boolean match(String line, int index, Set info) { 
154              if (toCut) 
155                  if (info.contains(getClass())) return !acceptIfYes; 
156              for(int i=0;i<toCheck.length;i++) { 
157                  if ((lastMatchIndex=line.indexOf(toCheck[i]))!=-1) return acceptIfYes; 
158              } 
159              return false; 
160          } 
161   
162          /** 
163           * Returns the last match index. 
164           * @return int the last match index, or -1 
165           */ 
166          public int getLastMatchIndex() { 
167              return lastMatchIndex; 
168          } 
169   
170       
171          /** 
172           * @see classUtils.pack.util.LineSet.Filter#onMatch(java.util.Set) 
173           */ 
174          public void onMatch(Set info) { 
175              info.add(getClass()); 
176          } 
177   
178      } 
179       
180      private List lines=new ArrayList(); 
181   
182      /** 
183       * Constructor for LineSet. 
184       */ 
185      public LineSet() { 
186          this(new String[0]); 
187      } 
188       
189      /** 
190       * Constructor for LineSet. 
191       */ 
192      public LineSet(String [] lines) { 
193          for(int i=0;i<lines.length;i++) 
194              add(lines[i]); 
195      } 
196       
197      /** 
198       * Add a line to the set. 
199       *  
200       * @param line 
201       */ 
202      public void add(String line) { 
203          lines.add(line); 
204      } 
205       
206      /** 
207       * Count the lines matching the filter. A {@link #NULL_FILTER NULL_FILTER}  
208       * can be used. 
209       *  
210       * @param filter the filter to match 
211       * @return int the number of lines matching the filter 
212       */ 
213      public int count(Filter filter) { 
214          if (filter==NULL_FILTER) return lines.size(); 
215          else return countFiltered(filter); 
216      } 
217       
218      private int countFiltered(Filter filter) { 
219          synchronized(lines) { 
220              Set info=new HashSet(); 
221              int c=0; 
222              int mc=0; 
223              for(Iterator i=lines.iterator();i.hasNext();) { 
224                  if (filter.match((String)i.next(), c++, info)) mc++; 
225              } 
226              return mc; 
227          } 
228      } 
229       
230      private List applyFilter0(Filter filter) { 
231          if (filter==NULL_FILTER) return lines; 
232          synchronized(lines) { 
233              int c=0; 
234              List lines2=new ArrayList(); 
235              Iterator i = lines.iterator(); 
236              Set info=new HashSet(); 
237              while(i.hasNext()) { 
238                  String s=(String)i.next(); 
239                  if (filter.match(s, c++, info)) { 
240                      lines2.add(s); 
241                      filter.onMatch(info); 
242                  }  
243              } 
244              return lines2; 
245          } 
246      } 
247       
248      public List getLinesList(Filter filter) { 
249          return applyFilter0(filter); 
250      } 
251       
252      public String [] getLines(Filter filter) { 
253          List l = applyFilter0(filter); 
254          String [] result = new String[l.size()]; 
255          l.toArray(result); 
256          return result; 
257      } 
258       
259      public String toString(Filter filter) { 
260          synchronized(lines) { 
261              List l = applyFilter0(filter); 
262              StringWriter sw=new StringWriter(); 
263              PrintWriter pw = new PrintWriter(sw); 
264              for(Iterator i=l.iterator();i.hasNext();) { 
265                  pw.println(i.next()); 
266              } 
267              return sw.toString(); 
268          } 
269      } 
270       
271      public String toString() { 
272          return toString(NULL_FILTER); 
273      } 
274       
275      public static LineSet create(String text, String lineSeparator) { 
276          StringTokenizer st = new StringTokenizer(text, lineSeparator); 
277          LineSet ls = new LineSet(); 
278          while(st.hasMoreTokens()) { 
279              ls.add(st.nextToken()); 
280          } 
281          return ls; 
282      } 
283       
284      public static LineSet create(String text) { 
285          return LineSet.create(text, System.getProperty("line.separator")); 
286      } 
287   
288  } 
289