KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > idaremedia > antx > ownhelpers > PropertiesIterator


1 /**
2  * $Id: PropertiesIterator.java 180 2007-03-15 12:56:38Z ssmc $
3  * Copyright 2004 iDare Media, Inc. All rights reserved.
4  *
5  * Originally written by iDare Media, Inc. for release into the public domain. This
6  * library, source form and binary form, is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License (LGPL) as published
8  * by the Free Software Foundation; either version 2.1 of the License, or (at your option)
9  * any later version.<p>
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU LGPL for more details.<p>
14  *
15  * You should have received a copy of the GNU Lesser General Public License along with this
16  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite
17  * 330, Boston, MA 02111-1307 USA. The GNU LGPL can be found online at
18  * http://www.fsf.org/copyleft/lesser.html<p>
19  *
20  * This product has been influenced by several projects within the open-source community.
21  * The JWare developers wish to acknowledge the open-source community's support. For more
22  * information regarding the open-source products used within JWare, please visit the
23  * JWare website.
24  *----------------------------------------------------------------------------------------*
25  * WEBSITE- http://www.jware.info EMAIL- inquiries@jware.info
26  *----------------------------------------------------------------------------------------*
27  **/

28
29 package com.idaremedia.antx.ownhelpers;
30
31 import java.util.Iterator JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.NoSuchElementException JavaDoc;
34
35 import org.apache.tools.ant.Project;
36 import org.apache.tools.ant.types.RegularExpression;
37 import org.apache.tools.ant.util.regexp.Regexp;
38
39 import com.idaremedia.antx.AntX;
40 import com.idaremedia.antx.FixtureExaminer;
41 import com.idaremedia.antx.parameters.IgnoreCaseEnabled;
42 import com.idaremedia.antx.parameters.PropertySource;
43
44 /**
45  * Iterator that will iterate a project's properties according to some
46  * application-defined selection criteria. This iterator does not support
47  * any mutative operation (like remove) to the project's properties. If a properties
48  * iterator's selection criteria are modified during an iteration, the effect
49  * on the iteration's results are undefined. <span class="src">PropertiesIterator</span>s
50  * return standard <span class="src">Map.Entry</span> items.
51  *
52  * @since JWare/AntX 0.4
53  * @author ssmc, &copy;2004 <a HREF="http://www.jware.info">iDare&nbsp;Media,&nbsp;Inc.</a>
54  * @version 0.5
55  * @.safety single
56  * @.group impl,helper
57  * @.pattern GoF.Iterator
58  * @see InnerProperties
59  * @see PropertyExaminer
60  * @see UnresolvedProperty
61  **/

62
63 public final class PropertiesIterator extends ProjectDependentSkeleton
64     implements Iterator JavaDoc, IgnoreCaseEnabled
65 {
66     private static final String JavaDoc IAM_ = AntX.utilities+"PropertiesIterator:";
67
68
69     /**
70      * Initializes a new unattached iterator. Before it is used,
71      * this iterator's project must be set.
72      * @see #setProject
73      * @see #setRE(RegularExpression) setRE(&#8230;)
74      **/

75     public PropertiesIterator()
76     {
77     }
78
79
80     /**
81      * Initializes a new iterator for a particular project
82      * and properties type.
83      * @param P the project (non-null)
84      * @param domain which properties (non-null)
85      **/

86     public PropertiesIterator(Project P, PropertySource domain)
87     {
88         setProject(P);
89         setDomain(domain);
90     }
91
92
93     /**
94      * Initializes a new iterator for a particular
95      * script declaration. The bean's project will be used.
96      **/

97     public PropertiesIterator(InnerProperties bean)
98     {
99         setProject(bean.getProject());
100         setDomain(bean.getDomain());
101         setIgnoreCase(bean.isIgnoreCase());
102         setPrefix(bean.getPrefixFilterPattern());
103         String JavaDoc pattern = bean.getLikeFilterPattern();
104         if (pattern==null) {
105             pattern = bean.getNotLikeFilterPattern();
106             if (pattern!=null) {
107                 setExclude(true);
108             }
109         }
110         if (pattern!=null) {
111             RegularExpression re = new RegularExpression();
112             re.setPattern(pattern);
113             setRE(re);
114         }
115     }
116
117
118     /**
119      * Call to mark this iterator as no longer in use.
120      * A GC-helper.
121      **/

122     public void dispose()
123     {
124         m_entryItr = null;
125         m_re = null;
126         m_nextEntry = null;
127         m_formCheck = null;
128         m_prefix = null;
129     }
130
131
132     /**
133      * Initializes this iterator's target project. This iterator
134      * extracts properties (and patterns) from this project.
135      * @param P the project (non-null)
136      **/

137     public void setProject(Project P)
138     {
139         AntX.require_(P!=null,IAM_,"setProject- nonzro project");
140         super.setProject(P);
141     }
142
143
144     /**
145      * Initializes this iterator's properties domain to a specific
146      * (sub)set of properties.
147      * @param domain properties domain (non-null)
148      **/

149     public void setDomain(PropertySource domain)
150     {
151         AntX.require_(domain!=null,IAM_,"setDomain- nonzro domain");
152         m_domain = domain;
153     }
154
155
156     /**
157      * Returns this iterator's properties domain. Will never return
158      * <i>null</i>; returns {@linkplain PropertySource#ALL ALL} if
159      * never defined.
160      **/

161     public PropertySource getDomain()
162     {
163         return m_domain;
164     }
165
166
167     /**
168      * Sets or clears a filtering regular expression for this
169      * iterator.
170      * @param re the regular expression filter (can be <i>null</i>)
171      **/

172     public void setRE(RegularExpression re)
173     {
174         m_re = re;
175     }
176
177
178     /**
179      * Sets or clears a filtering regular expression for this
180      * iterator.
181      * @param re the regular expression filter (can be <i>null</i>)
182      **/

183     public void setRE(Regexp re)
184     {
185         m_re = re;
186     }
187
188
189     /**
190      * Returns <i>true</i> if this iterator includes a filtering
191      * regular expression.
192      * @see #setRE(RegularExpression) setRE(&#8230;)
193      **/

194     public boolean willCheckRE()
195     {
196         return m_re!=null;
197     }
198
199
200     /**
201      * Sets or clears a filtering property name prefix for this
202      * iterator.
203      * @param prefix the filter prefix (can be <i>null</i>)
204      **/

205     public void setPrefix(String JavaDoc prefix)
206     {
207         m_prefix = prefix;
208         m_prefixLocal = null;
209     }
210
211
212     /**
213      * Returns this iterator's filtering prefix. Returns
214      * <i>null</i> if not set.
215      **/

216     public String JavaDoc getPrefix()
217     {
218         return m_prefix;
219     }
220
221
222     /**
223      * Returns <i>true</i> if this iterator includes a filtering
224      * prefix.
225      * @see #setPrefix(String) setPrefix(&#8230;)
226      **/

227     public boolean willCheckPrefix()
228     {
229         return m_prefix!=null;
230     }
231
232
233     /**
234      * Tells this iterator to ignore case (or not) in regular
235      * expression or prefix matches.
236      * @param ignore <i>true</i> to ignore
237      **/

238     public void setIgnoreCase(boolean ignore)
239     {
240         m_reOptions = ignore ? Regexp.MATCH_CASE_INSENSITIVE : 0/*?*/;
241     }
242
243
244     /**
245      * Returns <i>true</i> if this iterator will do case-insensitive
246      * regular expression or prefix matches. Is <i>false</i> by default.
247      **/

248     public boolean isIgnoreCase()
249     {
250         return m_reOptions!=0;
251     }
252
253
254
255     /**
256      * Tells this iterator to exclude items matching this iterator's
257      * regular expression. Exclusion does <em>not</em> apply to
258      * prefix matching. If exclusion is turned on, this iterator will
259      * return items that <em>do not match</em> its pattern.
260      * @param exclude <i>true</i> if is exclusion
261      **/

262     public final void setExclude(boolean exclude)
263     {
264         m_exclude = exclude;
265     }
266
267
268
269     /**
270      * Returns <i>true</i> if this iterator will return items that
271      * do <em>not</em> match its prefix and/or regular expression.
272      **/

273     public final boolean isExclusion()
274     {
275         return m_exclude;
276     }
277
278
279     /**
280      * Tells this iterator to check each property for an all-in-one
281      * failed variable substitution. If called, this iterator will either
282      * skip bad properties or return a proxy if one defined.
283      * @see #setBrokenSubstitutionProxy setBrokenSubstitutionProxy(String)
284      **/

285     public void setCheckSimpleBrokenSubstitution()
286     {
287         getFormCheck().setCheckSimpleBrokenSubstitution();
288     }
289
290
291     /**
292      * Tells this iterator to thoroughly check each property for any
293      * bad (failed) variable substitution. If called, this iterator will either
294      * skip bad properties or return a proxy if one defined.
295      * @see #setBrokenSubstitutionProxy setBrokenSubstitutionProxy(String)
296      **/

297     public void setCheckBrokenSubstitution()
298     {
299         getFormCheck().setCheckBrokenSubstitution();
300     }
301
302
303     /**
304      * Define a proxy value string for failed substitution
305      * properties. If this iterator is not already setup to check
306      * for unresolved property values, this method will turn
307      * checking on.
308      * @param valueProxy string to use for property value (non-null)
309      * @see UnresolvedProperty#VALUE
310      * @.sideeffect Will turn property definition checking on.
311      **/

312     public void setBrokenSubstitutionProxy(String JavaDoc valueProxy)
313     {
314         AntX.require_(valueProxy!=null,IAM_,"setProxy- nonzro valu");
315         getFormCheck().setBrokenSubstitutionProxy(valueProxy);
316     }
317
318
319     /**
320      * Returns <i>true</i> if this iterator will filter
321      * unresolved properties from list of returned items.
322      **/

323     public boolean willCheckForm()
324     {
325         return m_formCheck!=null;
326     }
327
328
329     /**
330      * Determine what is to be iterated and how the selections
331      * should be filtered. Called once, when iterator's public
332      * iteration API has been triggered.
333      **/

334     private void prepareToIterate()
335     {
336         Project P = getProjectNoNull();
337
338         Map JavaDoc mp = FixtureExaminer.copyOfProperties(getDomain(),P);
339         m_itemCount = mp.size();
340         m_entryItr = mp.entrySet().iterator();
341         mp = null;
342
343         if (m_re instanceof RegularExpression) {
344             m_re = ((RegularExpression)m_re).getRegexp(P);
345         }
346         if (isIgnoreCase() && m_prefix!=null) {
347             m_prefixLocal= m_prefix.toLowerCase();
348         }
349     }
350
351
352     /**
353      * Returns the total number of items this iterator can return.
354      * However, this number does not exclude items filtered by each
355      * call to {@linkplain #next}, so the actual number of
356      * iterations can be less than this value.
357      **/

358     public int candidateCount()
359     {
360         return m_itemCount;
361     }
362
363
364     /**
365      * Returns <i>true</i> if this iterator has at least one
366      * more property to return.
367      **/

368     public boolean hasNext()
369     {
370         if (m_entryItr==null) {
371             prepareToIterate();
372         }
373
374         boolean gotOne = (m_nextEntry!=null);
375
376         if (!gotOne) {
377             while (m_entryItr.hasNext()) {
378                 Map.Entry JavaDoc candidate = (Map.Entry JavaDoc)m_entryItr.next();
379                 boolean match;
380
381                 if (willCheckPrefix()) {
382                     String JavaDoc name = (String JavaDoc)candidate.getKey();
383                     if (m_prefixLocal!=null) {
384                         name = name.toLowerCase();
385                         match = name.startsWith(m_prefixLocal);
386                     } else {
387                         match = name.startsWith(m_prefix);
388                     }
389                     //NB: -exclusion does not apply to prefix (ssmc)
390
if (!match) {
391                         continue;
392                     }
393                 }
394
395                 if (willCheckRE()) {
396                     String JavaDoc name = (String JavaDoc)candidate.getKey();
397                     match = ((Regexp)m_re).matches(name, m_reOptions);
398                     if (m_exclude) {
399                         if (match) {
400                             continue;
401                         }
402                     } else if (!match) {
403                         continue;
404                     }
405                 }
406
407                 if (willCheckForm()) {
408                     candidate = m_formCheck.verifiedPropertyValue
409                         (candidate, getProject());
410                 }
411
412                 if (candidate!=null) {
413                     m_nextEntry = candidate;
414                     gotOne = true;
415                     break;
416                 }
417             }
418         }
419
420         return gotOne;
421     }
422
423
424     /**
425      * Returns the next project property key-value pair as a
426      * <span class="src">Map.Entry</span>.
427      * @throws NoSuchElementException if nothing more to iterate
428      **/

429     public Object JavaDoc next()
430     {
431         if (m_nextEntry==null) {
432             throw new NoSuchElementException JavaDoc();
433         }
434         Object JavaDoc result = m_nextEntry;
435         m_nextEntry = null;
436         return result;
437     }
438
439
440
441     /**
442      * Always generates an
443      * <span class="src">UnsupportedOperationException</span>.
444      * @throws UnsupportedOperationException always
445      **/

446     public final void remove()
447     {
448         throw new UnsupportedOperationException JavaDoc();
449     }
450
451
452
453     /**
454      * Resets this iterator for reuse. You can alter the selection
455      * criteria before the next call to <span class="src">hasNext</span>.
456      * The set of candidate properties will be recalculated.
457      **/

458     public void reset()
459     {
460         m_entryItr = null;
461         m_nextEntry = null;
462         m_itemCount = 0;
463         m_prefixLocal = null;
464     }
465
466
467
468     /**
469      * Returns this iterator's property definition checker,
470      * allocating the object if necessary.
471      **/

472     private PropertyExaminer getFormCheck()
473     {
474         if (m_formCheck==null) {
475             m_formCheck = new PropertyExaminer();
476         }
477         return m_formCheck;
478     }
479
480
481     private Iterator JavaDoc m_entryItr;
482     private Map.Entry JavaDoc m_nextEntry;
483     private int m_itemCount;
484
485     private PropertySource m_domain= PropertySource.ALL;
486     private String JavaDoc m_prefix, m_prefixLocal;
487     private Object JavaDoc m_re;
488     private int m_reOptions;//NB:=> case-sensitive matches
489
private PropertyExaminer m_formCheck;//lazy-inited
490
private boolean m_exclude;//NB:=> include not exclude
491
}
492
493 /* end-of-PropertiesIterator.java */
494
Popular Tags