KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > idaremedia > antx > condition > solo > RuleType


1 /**
2  * $Id: RuleType.java 180 2007-03-15 12:56:38Z ssmc $
3  * Copyright 2003-200 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 as published by the
8  * Free Software Foundation; either version 2.1 of the License, or (at your option) any
9  * 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 (GNU Lesser General Public License) 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 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.condition.solo;
30
31 import java.util.Iterator JavaDoc;
32 import java.util.Stack JavaDoc;
33 import java.util.Hashtable JavaDoc;
34
35 import org.apache.tools.ant.BuildException;
36 import org.apache.tools.ant.Location;
37 import org.apache.tools.ant.taskdefs.condition.Condition;
38
39 import com.idaremedia.antx.AntX;
40 import com.idaremedia.antx.FixtureComponent;
41 import com.idaremedia.antx.NoiseLevel;
42 import com.idaremedia.antx.apis.BuildAssertionException;
43 import com.idaremedia.antx.apis.Requester;
44 import com.idaremedia.antx.starters.Quiet;
45
46
47 /**
48  * Base AntX shareable rule type. Rule types are always embedded and accessed from their
49  * thread-safe evaluation APIs. This class implements support for the following:<ul>
50  * <li>Multi-thread support for evaluation and property updates.</li>
51  * <li>Enforcement of access through shareable APIs (not execute)</li>
52  * <li>Cloning (sort-of) for copying to child projects</li>
53  * </ul>
54  *
55  * @since JWare/AntX 0.3
56  * @author ssmc, &copy;2003-2004 <a HREF="http://www.jware.info">iDare&nbsp;Media,&nbsp;Inc.</a>
57  * @version 0.5
58  * @.safety single
59  * @.group impl,infra
60  * @see RuleTask
61  **/

62
63 public abstract class RuleType extends BooleanRule
64     implements FixtureComponent, ShareableCondition, Quiet, Cloneable JavaDoc
65 {
66
67     /**
68      * Initializes a new embedded RuleType instance.
69      * @param iam CV-label (non-null)
70      **/

71     protected RuleType(String JavaDoc iam)
72     {
73         super(iam,true);
74     }
75
76
77     /**
78      * Returns a clone of this rule type. Supports copying of
79      * rules types between parent and child projects.
80      **/

81     public Object JavaDoc clone()
82     {
83         try {
84             RuleType copy = (RuleType)super.clone();
85             cloneInternals(copy);
86             return copy;
87         } catch(CloneNotSupportedException JavaDoc clnx) {
88             throw new Error JavaDoc(uistrs().get(AntX.CLONE_BROKEN_MSGID));
89         }
90     }
91
92 // ---------------------------------------------------------------------------------------
93
// Parameters, Nested Elements:
94
// ---------------------------------------------------------------------------------------
95

96     /**
97      * Capture our identifier for feedback since Ant types aren't
98      * updated with correct location information.
99      **/

100     public void setId(String JavaDoc id)
101     {
102         m_Id= id;
103     }
104
105
106     /**
107      * Tries to return an unique identifier for this type. Looks
108      * for a build-script identifier; if none found creates a
109      * unique string based on type's class name and instance
110      * reference.
111      **/

112     public final String JavaDoc getId()
113     {
114         if (m_Id!=null) {
115             return m_Id;
116         }
117         return super.getId();
118     }
119
120
121     /**
122      * Returns the supposed effect if this rule evaluates <i>false</i>.
123      * Should be called after this rule is fully configured. Returns
124      * <i>null</i> by default (meaning unknown).
125      **/

126     public NoiseLevel getFailureEffect()
127     {
128         return null;
129     }
130
131
132 // ---------------------------------------------------------------------------------------
133
// Multi-thread Support:
134
// ---------------------------------------------------------------------------------------
135

136     /**
137      * Our factories of thread-specific update-information handles. Each
138      * factory is associated with a class <em>instance</em>.
139      **/

140     private static final Hashtable JavaDoc sm_updateJunkFactories= new Hashtable JavaDoc(11,0.9f);
141
142     private static final RuleUserHandle.Factory getUpdateJunkFactory(Class JavaDoc c)
143     {
144         if (c==null) {
145             throw new IllegalArgumentException JavaDoc("getUPJFactory- NULL class");
146         }
147         synchronized(c) {//!eyow!
148
RuleUserHandle.Factory f= (RuleUserHandle.Factory)
149                 sm_updateJunkFactories.get(c);
150             if (f==null) {
151                 f = new RuleUserHandle.Factory();
152                 sm_updateJunkFactories.put(c,f);
153             }
154             return f;
155         }
156     }
157
158
159     /**
160      * The getter method for class-specific, thread-specific
161      * update-information handle used by a rule's eval() methods.
162      * Currently only accessible to our types.
163      * @.safety guarded (class)
164      **/

165     private static final RuleUserHandle getUpdatePropertyJunkHandle(Class JavaDoc c)
166     {
167         return (RuleUserHandle)getUpdateJunkFactory(c).get();
168     }
169
170
171     /**
172      * The getter method for thread-specific update-information used
173      * by a build rule's eval method. Should never return <i>null</i>.
174      * @.safety guarded (class)
175      **/

176     protected static final ShareableConditionUser getUpdatePropertyJunk(Class JavaDoc c)
177     {
178         return ((RuleUserHandle)getUpdateJunkFactory(c).get()).getCaller();
179     }
180
181
182     /**
183      * Returns the current thread's update msgId. Returns this rule's
184      * msgid if update msgId not set by caller.
185      **/

186     public final String JavaDoc getMsgId()
187     {
188         ShareableConditionUser upj= getUpdatePropertyJunk(getClass());
189         String JavaDoc msgid = upj!=null ? upj.getMsgId() : null;
190         return (msgid!=null) ? msgid : super.getMsgId();
191     }
192
193
194     /**
195      * Returns the current thread's update Location. Returns this
196      * rule's location if not set by caller.
197      **/

198     public final Location getLocation()
199     {
200         ShareableConditionUser upj= getUpdatePropertyJunk(getClass());
201         Location l = upj!=null ? upj.getLocation() : null;
202         return (l!=null) ? l : super.getLocation();
203     }
204
205
206     /**
207      * Returns the current thread's update property. Returns
208      * <i>null</i> if update property not set by caller.
209      **/

210     protected final String JavaDoc getUpdateProperty()
211     {
212         ShareableConditionUser upj= getUpdatePropertyJunk(getClass());
213         return upj!=null ? upj.getUpdateProperty() : super.getUpdateProperty();
214     }
215
216
217     /**
218      * Returns the current thread's update value. Returns
219      * "<i>true</i>" if update value not set by caller.
220      **/

221     protected final String JavaDoc getUpdatePropertyValue()
222     {
223         ShareableConditionUser upj= getUpdatePropertyJunk(getClass());
224         String JavaDoc upv = upj!=null ? upj.getUpdateValue() : null;
225         return (upv==null) ? super.getUpdatePropertyValue() : upv;
226     }
227
228
229     /**
230      * Returns the current thread's update variable. Returns
231      * <i>null</i> if update variable not set by caller.
232      **/

233     protected final String JavaDoc getUpdateVariable()
234     {
235         ShareableConditionUser upj= getUpdatePropertyJunk(getClass());
236         return upj!=null ? upj.getUpdateVariable() : super.getUpdateVariable();
237     }
238
239
240 // ---------------------------------------------------------------------------------------
241
// Evaluation:
242
// ---------------------------------------------------------------------------------------
243

244     /**
245      * Freezes this rule definition from further modification. First ensures
246      * this rule was fully configured. Cannot be called from a constructor.
247      * @.safety guarded
248      **/

249     public final synchronized void freezeDefinition()
250     {
251         if (!isFrozen()) {
252             maybeConfigure();
253             super.freezeDefinition();
254
255             if (!m_circularityChecked) {
256                 Stack JavaDoc stk = new Stack JavaDoc();
257                 stk.push(this);
258                 verifyNoCircularDependency(stk, new Requester.ForComponent(this));
259                 m_circularityChecked=true;
260             }
261         }
262     }
263
264
265     /**
266      * The evaluation bits that each type might need to customize. Seems
267      * to work for both tallysets and buildrules. The thread-based fixture
268      * has been configured by caller.
269      **/

270     protected boolean safeEvalImpl()
271     {
272         boolean stopQuik= isStopQuickEvaluation();
273         boolean istrue= true;
274         int N= 0;
275         boolean stop= false;//NB:used to ensure N is incremented(ssmc)
276

277         if (!isEmpty()) {
278             Iterator JavaDoc itr= getConditions().iterator();
279             while (!stop && itr.hasNext()) {
280                 try {
281                     boolean condTrue = ((Condition)itr.next()).eval();
282                     if (!condTrue) {
283                         istrue = false;
284                         if (stopQuik) {
285                             stop = true;
286                         }
287                     }
288                 } catch(BuildAssertionException aX) {
289                     istrue = false;
290                     stop = true;
291                 }
292                 N++;
293             }
294         }
295
296         setEvalResult(istrue,getConditionNames(N));
297         return istrue;
298     }
299
300
301     /**
302      * Evaluates this rule type. Warning: the first time this rule is
303      * evaluated it locks itself from further modification.
304      * @param calr rule user source (non-null)
305      * @.safety threadlocal after guarded freeze-check
306      * @throws BuildException if error occurs during evaluation
307      **/

308     public boolean eval(ShareableConditionUser calr)
309         throws BuildException
310     {
311         require_(calr!=null, "eval- nonzro calr information");
312
313         // Ensure we're configured and then frozen first time.
314
freezeDefinition();
315
316         // Enforce what gets updated on a failed evaluation.
317
RuleUserHandle upj = getUpdatePropertyJunkHandle(getClass());
318         final ShareableConditionUser previous = upj.setCaller(calr);
319
320         // Evaluate the conditions until a failure or all done.
321
try {
322             return safeEvalImpl();
323         }
324         // HouseKeep the thread-local holder back to entry-state.
325
finally {
326             upj.setCaller(previous);
327         }
328     }
329
330
331     /**
332      * By default assume rule types can be nested within each other
333      * so its possible a rule will be called by another. Subclasses
334      * should no-op this eval() if this is not the case. Warning:
335      * the first time this rule is evaluated it locks itself from
336      * further modification.
337      * @.safety multiple after guarded freeze-check
338      * @.sideeffect Will freeze this rule from further modification.
339      **/

340     public boolean eval()
341     {
342         // Ensure we're configured and then frozen first time.
343
freezeDefinition();
344
345         //Evaluate the conditions until a failure or all done.
346
return safeEvalImpl();
347     }
348
349
350 // ---------------------------------------------------------------------------------------
351

352     /**
353      * No-op; rules types must be explicitly evaluated by other
354      * tasks not executed as a task by the parsing process.
355      **/

356     public final void execute()
357     {
358         //burp...quietly
359
}
360
361
362 // ---------------------------------------------------------------------------------------
363
protected boolean m_circularityChecked;//NB:nope
364
private String JavaDoc m_Id;//NB:needed for feedback
365
}
366
367 /* end-of-RuleType.java */
368
Popular Tags