KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fulcrum > intake > model > Group


1 package org.apache.fulcrum.intake.model;
2
3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" and
29  * "Apache Turbine" must not be used to endorse or promote products
30  * derived from this software without prior written permission. For
31  * written permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * "Apache Turbine", nor may "Apache" appear in their name, without
35  * prior written permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 import java.util.ArrayList JavaDoc;
58 import java.util.HashMap JavaDoc;
59 import java.util.Iterator JavaDoc;
60 import java.util.List JavaDoc;
61 import java.util.Map JavaDoc;
62
63 import org.apache.commons.pool.BaseKeyedPoolableObjectFactory;
64 import org.apache.fulcrum.ServiceException;
65 import org.apache.fulcrum.intake.Retrievable;
66 import org.apache.fulcrum.intake.TurbineIntake;
67 import org.apache.fulcrum.intake.xmlmodel.AppData;
68 import org.apache.fulcrum.intake.xmlmodel.XmlField;
69 import org.apache.fulcrum.intake.xmlmodel.XmlGroup;
70 import org.apache.fulcrum.parser.ValueParser;
71 import org.apache.log4j.Category;
72
73 /** Holds a group of Fields */
74 public class Group
75 {
76     public static final String JavaDoc EMPTY = "";
77
78     /*
79      * An id representing a new object.
80      */

81     public static final String JavaDoc NEW = "_0";
82
83     private static final Category log;
84     private static final boolean isDebugEnabled;
85
86     static
87     {
88         log = Category.getInstance(Group.class.getName());
89         isDebugEnabled = log.isDebugEnabled();
90     }
91
92     /**
93      * The key used to represent this group in a parameter.
94      * This key is usually a prefix as part of a field key.
95      */

96     protected final String JavaDoc gid;
97
98     /**
99      * The name used in templates and java code to refer to this group.
100      */

101     protected final String JavaDoc name;
102
103     /**
104      * The number of Groups with the same name that will be pooled.
105      */

106     private final int poolCapacity;
107
108     /**
109      * A map of the fields in this group mapped by field name.
110      */

111     protected Map JavaDoc fields;
112
113     /**
114      * Map of the fields by mapToObject
115      */

116     protected Map JavaDoc mapToObjectFields;
117
118     /**
119      * An array of fields in this group.
120      */

121     protected Field[] fieldsArray;
122
123     /**
124      * The object id used to associate this group to a bean
125      * for one request cycle
126      */

127     protected String JavaDoc oid;
128
129     /**
130      * The object containing the request data
131      */

132     protected ValueParser pp;
133
134     /**
135      * A flag to help prevent duplicate hidden fields declaring this group.
136      */

137     protected boolean isDeclared;
138
139     /**
140      * Constructs a new Group based on the xml specification. Groups are
141      * instantiated and pooled by the IntakeService and should not
142      * be instantiated otherwise.
143      *
144      * @param group a <code>XmlGroup</code> value
145      * @exception Exception if an error occurs in other classes
146      */

147     public Group(XmlGroup group)
148         throws Exception JavaDoc
149     {
150         gid = group.getKey();
151         name = group.getName();
152         poolCapacity = Integer.parseInt(group.getPoolCapacity());
153
154         List JavaDoc inputFields = group.getFields();
155         int size = inputFields.size();
156         fields = new HashMap JavaDoc((int)(1.25*size + 1));
157         mapToObjectFields = new HashMap JavaDoc((int)(1.25*size + 1));
158         fieldsArray = new Field[size];
159         for (int i=size-1; i>=0; i--)
160         {
161             XmlField f = (XmlField)inputFields.get(i);
162             Field field = FieldFactory.getInstance(f, this);
163             fieldsArray[i]= field;
164             fields.put(f.getName(), field);
165
166             // map fields by their mapToObject
167
List JavaDoc tmpFields = (List JavaDoc)mapToObjectFields.get(f.getMapToObject());
168             if ( tmpFields == null )
169             {
170                 tmpFields = new ArrayList JavaDoc(size);
171                 mapToObjectFields.put(f.getMapToObject(), tmpFields);
172             }
173             tmpFields.add(field);
174         }
175
176         // Change the mapToObjectFields values to Field[]
177
Iterator JavaDoc keys = mapToObjectFields.keySet().iterator();
178         while ( keys.hasNext() )
179         {
180             Object JavaDoc key = keys.next();
181             List JavaDoc tmpFields = (List JavaDoc)mapToObjectFields.get(key);
182             mapToObjectFields.put(key,
183                 tmpFields.toArray(new Field[tmpFields.size()]));
184         }
185     }
186
187     /**
188      * Initializes the default Group using parameters.
189      *
190      * @param pp a <code>ValueParser</code> value
191      * @return this Group
192      */

193     public Group init(ValueParser pp) throws ServiceException
194     {
195         return init(NEW, pp);
196     }
197
198     /**
199      * Initializes the Group with parameters from RunData
200      * corresponding to key.
201      *
202      * @param data a <code>RunData</code> value
203      * @return this Group
204      */

205     public Group init(String JavaDoc key, ValueParser pp)
206         throws ServiceException
207     {
208         this.oid = key;
209         this.pp = pp;
210         for (int i=fieldsArray.length-1; i>=0; i--)
211         {
212             fieldsArray[i].init(pp);
213         }
214         return this;
215     }
216
217
218     /**
219      * Initializes the group with properties from an object.
220      *
221      * @param obj a <code>Persistent</code> value
222      * @return a <code>Group</code> value
223      */

224     public Group init(Retrievable obj)
225     {
226         this.oid = obj.getQueryKey();
227
228         Class JavaDoc cls = obj.getClass();
229         while ( cls != null )
230         {
231             Field[] flds = (Field[])mapToObjectFields.get(cls.getName());
232             if ( flds != null )
233             {
234                 for (int i=flds.length-1; i>=0; i--)
235                 {
236                     flds[i].init(obj);
237                 }
238             }
239
240             cls = cls.getSuperclass();
241         }
242
243         return this;
244     }
245
246
247     /**
248      * Gets a list of the names of the fields stored in this object.
249      *
250      * @return A String array containing the list of names.
251      */

252     public String JavaDoc[] getFieldNames()
253     {
254         String JavaDoc nameList[] = new String JavaDoc[fieldsArray.length];
255         for(int i = 0; i < nameList.length; i++)
256         {
257             nameList[i] = fieldsArray[i].name;
258         }
259         return nameList;
260     }
261
262
263     /**
264      * Return the name given to this group. The long name is to
265      * avoid conflicts with the get(String key) method.
266      *
267      * @return a <code>String</code> value
268      */

269     public String JavaDoc getIntakeGroupName()
270     {
271         return name;
272     }
273
274     /**
275      * Get the number of Group objects that will be pooled.
276      *
277      * @return an <code>int</code> value
278      */

279     public int getPoolCapacity()
280     {
281         return poolCapacity;
282     }
283
284     /**
285      * Get the part of the key used to specify the group.
286      * This is specified in the key attribute in the xml file.
287      *
288      * @return a <code>String</code> value
289      */

290     public String JavaDoc getGID()
291     {
292         return gid;
293     }
294
295     /**
296      * Get the part of the key that distinguishes a group
297      * from others of the same name.
298      *
299      * @return a <code>String</code> value
300      */

301     public String JavaDoc getOID()
302     {
303         return oid;
304     }
305
306     /**
307      * Concatenation of gid and oid.
308      *
309      * @return a <code>String</code> value
310      */

311     public String JavaDoc getObjectKey()
312     {
313         return gid + oid;
314     }
315
316     /**
317      * Describe <code>getObjects</code> method here.
318      *
319      * @param pp a <code>ValueParser</code> value
320      * @return an <code>ArrayList</code> value
321      * @exception ServiceException if an error occurs
322      */

323     public ArrayList JavaDoc getObjects(ValueParser pp)
324         throws ServiceException
325     {
326         ArrayList JavaDoc objs = null;
327         String JavaDoc[] oids = pp.getStrings(gid);
328         if (oids != null)
329         {
330             objs = new ArrayList JavaDoc(oids.length);
331             for (int i=oids.length-1; i>=0; i--)
332             {
333                 objs.add( TurbineIntake.getGroup(name).init(oids[i], pp) );
334             }
335         }
336         return objs;
337     }
338
339     /**
340      * Get the Field .
341      * @return Field.
342      */

343     public Field get(String JavaDoc fieldName)
344         throws ServiceException
345     {
346         if (fields.containsKey(fieldName))
347         {
348             return (Field)fields.get(fieldName);
349         }
350         else
351         {
352             throw new ServiceException ("Intake Field name: " + fieldName +
353                                         " not found!");
354         }
355     }
356
357     /**
358      * Performs an AND between all the fields in this group.
359      *
360      * @return a <code>boolean</code> value
361      */

362     public boolean isAllValid()
363     {
364         boolean valid = true;
365         for (int i=fieldsArray.length-1; i>=0; i--)
366         {
367             valid &= fieldsArray[i].isValid();
368             if ( isDebugEnabled && !fieldsArray[i].isValid())
369             {
370                 log.debug("[Intake] Group(" + oid + "): " + name + "; Field: "
371                           + fieldsArray[i].name + "; value=" +
372                           fieldsArray[i].getValue() + " is invalid!");
373             }
374         }
375         return valid;
376     }
377
378     /**
379      * Calls a setter methods on obj, for fields which have been set.
380      * @exception throws up any exceptions resulting from failure to
381      * check input validity.
382      */

383     public void setProperties(Object JavaDoc obj)
384         throws ServiceException
385     {
386         Class JavaDoc cls = obj.getClass();
387         while ( cls != null )
388         {
389             Field[] flds = (Field[])mapToObjectFields.get(cls.getName());
390             if ( flds != null )
391             {
392                 for (int i=flds.length-1; i>=0; i--)
393                 {
394                     flds[i].setProperty(obj);
395                 }
396             }
397
398             cls = cls.getSuperclass();
399         }
400     }
401     /**
402      * Calls a setter methods on obj, for fields which pass validity tests.
403      * In most cases one should call Intake.isAllValid() and then if that
404      * test passes call setProperties. Use this method when some data is
405      * known to be invalid, but you still want to set the object properties
406      * that are valid.
407      */

408     public void setValidProperties(Object JavaDoc obj)
409     {
410         Class JavaDoc cls = obj.getClass();
411         while ( cls != null )
412         {
413             Field[] flds = (Field[])mapToObjectFields.get(cls.getName());
414             if ( flds != null )
415             {
416                 for (int i=flds.length-1; i>=0; i--)
417                 {
418                     try
419                     {
420                         flds[i].setProperty(obj);
421                     }
422                     catch(ServiceException e)
423                     {
424                         // just move on to next field
425
}
426                 }
427             }
428
429             cls = cls.getSuperclass();
430         }
431     }
432
433     /**
434      * Calls getter methods on objects that are known to Intake
435      * so that field values in forms can be initialized from
436      * the values contained in the intake tool.
437      */

438     public void getProperties(Object JavaDoc obj)
439         throws Exception JavaDoc
440     {
441         Class JavaDoc cls = obj.getClass();
442         while (cls != null)
443         {
444             Field[] flds = (Field[])mapToObjectFields.get(cls.getName());
445             if( flds != null )
446             {
447                 for (int i=flds.length-1; i>=0; i--)
448                 {
449                     flds[i].getProperty(obj);
450                 }
451             }
452
453             cls = cls.getSuperclass();
454         }
455     }
456
457     /**
458      * Removes references to this group and its fields from the
459      * query parameters
460      */

461     public void removeFromRequest()
462     {
463         if (pp != null)
464         {
465             String JavaDoc[] groups = pp.getStrings(gid);
466             if ( groups != null )
467             {
468                 pp.remove(gid);
469                 for (int i=0; i<groups.length; i++)
470                 {
471                     if ( groups[i] != null && !groups[i].equals(oid) )
472                     {
473                         pp.add(gid,groups[i]);
474                     }
475                 }
476                 for (int i=fieldsArray.length-1; i>=0; i--)
477                 {
478                     fieldsArray[i].removeFromRequest();
479                 }
480             }
481         }
482     }
483
484     /**
485      * To be used in the event this group is used within multiple
486      * forms within the same template.
487      */

488     public void resetDeclared()
489     {
490         isDeclared = false;
491     }
492
493     /**
494      * A xhtml valid hidden input field that notifies intake of the
495      * group's presence.
496      *
497      * @return a <code>String</code> value
498      */

499     public String JavaDoc getHtmlFormInput()
500     {
501         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(64);
502         appendHtmlFormInput(sb);
503         return sb.toString();
504     }
505
506     /**
507      * A xhtml valid hidden input field that notifies intake of the
508      * group's presence.
509      */

510     public void appendHtmlFormInput(StringBuffer JavaDoc sb)
511     {
512         if ( !isDeclared )
513         {
514             isDeclared = true;
515             sb.append("<input type=\"hidden\" name=\"")
516               .append(gid)
517               .append("\" value=\"")
518               .append(oid)
519               .append("\"/>\n");
520         }
521     }
522
523     // ********** PoolableObjectFactory implementation ******************
524

525     public static class GroupFactory
526         extends BaseKeyedPoolableObjectFactory
527     {
528         private AppData appData;
529
530         public GroupFactory(AppData appData)
531         {
532             this.appData = appData;
533         }
534
535         /**
536          * Creates an instance that can be returned by the pool.
537          * @return an instance that can be returned by the pool.
538          */

539         public Object JavaDoc makeObject(Object JavaDoc key)
540             throws Exception JavaDoc
541         {
542             return new Group(appData.getGroup((String JavaDoc)key));
543         }
544         
545         /**
546          * Uninitialize an instance to be returned to the pool.
547          * @param obj the instance to be passivated
548          */

549         public void passivateObject(Object JavaDoc key, Object JavaDoc obj)
550             throws Exception JavaDoc
551         {
552             Group group = (Group)obj;
553             group.oid = null;
554             group.pp = null;
555             for (int i=group.fieldsArray.length-1; i>=0; i--)
556             {
557                 group.fieldsArray[i].dispose();
558             }
559             group.isDeclared = false;
560         }
561     }
562 }
563
564
565
Popular Tags