KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > turbine > services > intake > model > Group


1 package org.apache.turbine.services.intake.model;
2
3 /*
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License")
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import org.apache.commons.pool.BaseKeyedPoolableObjectFactory;
29
30 import org.apache.turbine.om.Retrievable;
31 import org.apache.turbine.services.intake.IntakeException;
32 import org.apache.turbine.services.intake.TurbineIntake;
33 import org.apache.turbine.services.intake.xmlmodel.AppData;
34 import org.apache.turbine.services.intake.xmlmodel.XmlField;
35 import org.apache.turbine.services.intake.xmlmodel.XmlGroup;
36 import org.apache.turbine.util.TurbineException;
37 import org.apache.turbine.util.parser.ValueParser;
38
39 /**
40  * Holds a group of Fields
41  *
42  * @author <a HREF="mailto:jmcnally@collab.net">John McNally</a>
43  * @author <a HREF="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
44  * @author <a HREF="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
45  * @version $Id: Group.java,v 1.9.2.2 2004/05/20 03:16:39 seade Exp $
46  */

47 public class Group
48 {
49     public static final String JavaDoc EMPTY = "";
50
51     /*
52      * An id representing a new object.
53      */

54     public static final String JavaDoc NEW = "_0";
55
56     private static final Log log;
57     private static final boolean isDebugEnabled;
58
59     static
60     {
61         log = LogFactory.getLog(Group.class);
62         isDebugEnabled = log.isDebugEnabled();
63     }
64
65     /**
66      * The key used to represent this group in a parameter.
67      * This key is usually a prefix as part of a field key.
68      */

69     protected final String JavaDoc gid;
70
71     /**
72      * The name used in templates and java code to refer to this group.
73      */

74     protected final String JavaDoc name;
75
76     /**
77      * The number of Groups with the same name that will be pooled.
78      */

79     private final int poolCapacity;
80
81     /**
82      * A map of the fields in this group mapped by field name.
83      */

84     protected Map JavaDoc fields;
85
86     /**
87      * Map of the fields by mapToObject
88      */

89     protected Map JavaDoc mapToObjectFields;
90
91     /**
92      * An array of fields in this group.
93      */

94     protected Field[] fieldsArray;
95
96     /**
97      * The object id used to associate this group to a bean
98      * for one request cycle
99      */

100     protected String JavaDoc oid;
101
102     /**
103      * The object containing the request data
104      */

105     protected ValueParser pp;
106
107     /**
108      * A flag to help prevent duplicate hidden fields declaring this group.
109      */

110     protected boolean isDeclared;
111
112     /**
113      * Constructs a new Group based on the xml specification. Groups are
114      * instantiated and pooled by the IntakeService and should not
115      * be instantiated otherwise.
116      *
117      * @param group a <code>XmlGroup</code> value
118      * @exception IntakeException if an error occurs in other classes
119      */

120     public Group(XmlGroup group) throws IntakeException
121     {
122         gid = group.getKey();
123         name = group.getName();
124         poolCapacity = Integer.parseInt(group.getPoolCapacity());
125
126         List JavaDoc inputFields = group.getFields();
127         int size = inputFields.size();
128         fields = new HashMap JavaDoc((int) (1.25 * size + 1));
129         mapToObjectFields = new HashMap JavaDoc((int) (1.25 * size + 1));
130         fieldsArray = new Field[size];
131         for (int i = size - 1; i >= 0; i--)
132         {
133             XmlField f = (XmlField) inputFields.get(i);
134             Field field = FieldFactory.getInstance(f, this);
135             fieldsArray[i] = field;
136             fields.put(f.getName(), field);
137
138             // map fields by their mapToObject
139
List JavaDoc tmpFields = (List JavaDoc) mapToObjectFields.get(f.getMapToObject());
140             if (tmpFields == null)
141             {
142                 tmpFields = new ArrayList JavaDoc(size);
143                 mapToObjectFields.put(f.getMapToObject(), tmpFields);
144             }
145             tmpFields.add(field);
146         }
147
148         // Change the mapToObjectFields values to Field[]
149
for (Iterator JavaDoc keys = mapToObjectFields.keySet().iterator(); keys.hasNext();)
150         {
151             Object JavaDoc key = keys.next();
152             List JavaDoc tmpFields = (List JavaDoc) mapToObjectFields.get(key);
153             mapToObjectFields.put(key,
154                     tmpFields.toArray(new Field[tmpFields.size()]));
155         }
156     }
157
158     /**
159      * Initializes the default Group using parameters.
160      *
161      * @param pp a <code>ValueParser</code> value
162      * @return this Group
163      */

164     public Group init(ValueParser pp) throws TurbineException
165     {
166         return init(NEW, pp);
167     }
168
169     /**
170      * Initializes the Group with parameters from RunData
171      * corresponding to key.
172      *
173      * @param pp a <code>ValueParser</code> value
174      * @return this Group
175      */

176     public Group init(String JavaDoc key, ValueParser pp) throws IntakeException
177     {
178         this.oid = key;
179         this.pp = pp;
180         for (int i = fieldsArray.length - 1; i >= 0; i--)
181         {
182             fieldsArray[i].init(pp);
183         }
184         return this;
185     }
186
187     /**
188      * Initializes the group with properties from an object.
189      *
190      * @param obj a <code>Persistent</code> value
191      * @return a <code>Group</code> value
192      */

193     public Group init(Retrievable obj)
194     {
195         this.oid = obj.getQueryKey();
196
197         Class JavaDoc cls = obj.getClass();
198         while (cls != null)
199         {
200             Field[] flds = (Field[]) mapToObjectFields.get(cls.getName());
201             if (flds != null)
202             {
203                 for (int i = flds.length - 1; i >= 0; i--)
204                 {
205                     flds[i].init(obj);
206                 }
207             }
208
209             cls = cls.getSuperclass();
210         }
211
212         return this;
213     }
214
215     /**
216      * Gets a list of the names of the fields stored in this object.
217      *
218      * @return A String array containing the list of names.
219      */

220     public String JavaDoc[] getFieldNames()
221     {
222         String JavaDoc nameList[] = new String JavaDoc[fieldsArray.length];
223         for (int i = 0; i < nameList.length; i++)
224         {
225             nameList[i] = fieldsArray[i].name;
226         }
227         return nameList;
228     }
229
230     /**
231      * Return the name given to this group. The long name is to
232      * avoid conflicts with the get(String key) method.
233      *
234      * @return a <code>String</code> value
235      */

236     public String JavaDoc getIntakeGroupName()
237     {
238         return name;
239     }
240
241     /**
242      * Get the number of Group objects that will be pooled.
243      *
244      * @return an <code>int</code> value
245      */

246     public int getPoolCapacity()
247     {
248         return poolCapacity;
249     }
250
251     /**
252      * Get the part of the key used to specify the group.
253      * This is specified in the key attribute in the xml file.
254      *
255      * @return a <code>String</code> value
256      */

257     public String JavaDoc getGID()
258     {
259         return gid;
260     }
261
262     /**
263      * Get the part of the key that distinguishes a group
264      * from others of the same name.
265      *
266      * @return a <code>String</code> value
267      */

268     public String JavaDoc getOID()
269     {
270         return oid;
271     }
272
273     /**
274      * Concatenation of gid and oid.
275      *
276      * @return a <code>String</code> value
277      */

278     public String JavaDoc getObjectKey()
279     {
280         return gid + oid;
281     }
282
283     /**
284      * Describe <code>getObjects</code> method here.
285      *
286      * @param pp a <code>ValueParser</code> value
287      * @return an <code>ArrayList</code> value
288      * @exception IntakeException if an error occurs
289      */

290     public ArrayList JavaDoc getObjects(ValueParser pp) throws IntakeException
291     {
292         ArrayList JavaDoc objs = null;
293         String JavaDoc[] oids = pp.getStrings(gid);
294         if (oids != null)
295         {
296             objs = new ArrayList JavaDoc(oids.length);
297             for (int i = oids.length - 1; i >= 0; i--)
298             {
299                 objs.add(TurbineIntake.getGroup(name).init(oids[i], pp));
300             }
301         }
302         return objs;
303     }
304
305     /**
306      * Get the Field .
307      * @return Field.
308      * @throws IntakeException indicates the field could not be found.
309      */

310     public Field get(String JavaDoc fieldName)
311             throws IntakeException
312     {
313         if (fields.containsKey(fieldName))
314         {
315             return (Field) fields.get(fieldName);
316         }
317         else
318         {
319             throw new IntakeException("Intake Field name: " + fieldName +
320                     " not found!");
321         }
322     }
323
324     /**
325      * Performs an AND between all the fields in this group.
326      *
327      * @return a <code>boolean</code> value
328      */

329     public boolean isAllValid()
330     {
331         boolean valid = true;
332         for (int i = fieldsArray.length - 1; i >= 0; i--)
333         {
334             valid &= fieldsArray[i].isValid();
335             if (isDebugEnabled && !fieldsArray[i].isValid())
336             {
337                 log.debug("Group(" + oid + "): " + name + "; Field: "
338                         + fieldsArray[i].name + "; value=" +
339                         fieldsArray[i].getValue() + " is invalid!");
340             }
341         }
342         return valid;
343     }
344
345     /**
346      * Calls a setter methods on obj, for fields which have been set.
347      *
348      * @param obj Object to be set with the values from the group.
349      * @throws IntakeException indicates that a failure occurred while
350      * executing the setter methods of the mapped object.
351      */

352     public void setProperties(Object JavaDoc obj) throws IntakeException
353     {
354         Class JavaDoc cls = obj.getClass();
355
356         while (cls != null)
357         {
358             if (isDebugEnabled)
359             {
360                 log.debug("setProperties(" + cls.getName() + ")");
361             }
362
363             Field[] flds = (Field[]) mapToObjectFields.get(cls.getName());
364             if (flds != null)
365             {
366                 for (int i = flds.length - 1; i >= 0; i--)
367                 {
368                     flds[i].setProperty(obj);
369                 }
370             }
371
372             cls = cls.getSuperclass();
373         }
374         log.debug("setProperties() finished");
375     }
376
377     /**
378      * Calls a setter methods on obj, for fields which pass validity tests.
379      * In most cases one should call Intake.isAllValid() and then if that
380      * test passes call setProperties. Use this method when some data is
381      * known to be invalid, but you still want to set the object properties
382      * that are valid.
383      */

384     public void setValidProperties(Object JavaDoc obj)
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                     try
395                     {
396                         flds[i].setProperty(obj);
397                     }
398                     catch (Exception JavaDoc e)
399                     {
400                         // just move on to next field
401
}
402                 }
403             }
404
405             cls = cls.getSuperclass();
406         }
407     }
408
409     /**
410      * Calls getter methods on objects that are known to Intake
411      * so that field values in forms can be initialized from
412      * the values contained in the intake tool.
413      *
414      * @param obj Object that will be used to as a source of data for
415      * setting the values of the fields within the group.
416      * @throws IntakeException indicates that a failure occurred while
417      * executing the setter methods of the mapped object.
418      */

419     public void getProperties(Object JavaDoc obj) throws IntakeException
420     {
421         Class JavaDoc cls = obj.getClass();
422         while (cls != null)
423         {
424             Field[] flds = (Field[]) mapToObjectFields.get(cls.getName());
425             if (flds != null)
426             {
427                 for (int i = flds.length - 1; i >= 0; i--)
428                 {
429                     flds[i].getProperty(obj);
430                 }
431             }
432
433             cls = cls.getSuperclass();
434         }
435     }
436
437     /**
438      * Removes references to this group and its fields from the
439      * query parameters
440      */

441     public void removeFromRequest()
442     {
443         if (pp != null)
444         {
445             String JavaDoc[] groups = pp.getStrings(gid);
446             if (groups != null)
447             {
448                 pp.remove(gid);
449                 for (int i = 0; i < groups.length; i++)
450                 {
451                     if (groups[i] != null && !groups[i].equals(oid))
452                     {
453                         pp.add(gid, groups[i]);
454                     }
455                 }
456                 for (int i = fieldsArray.length - 1; i >= 0; i--)
457                 {
458                     fieldsArray[i].removeFromRequest();
459                 }
460             }
461         }
462     }
463
464     /**
465      * To be used in the event this group is used within multiple
466      * forms within the same template.
467      */

468     public void resetDeclared()
469     {
470         isDeclared = false;
471     }
472
473     /**
474      * A xhtml valid hidden input field that notifies intake of the
475      * group's presence.
476      *
477      * @return a <code>String</code> value
478      */

479     public String JavaDoc getHtmlFormInput()
480     {
481         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(64);
482         appendHtmlFormInput(sb);
483         return sb.toString();
484     }
485
486     /**
487      * A xhtml valid hidden input field that notifies intake of the
488      * group's presence.
489      */

490     public void appendHtmlFormInput(StringBuffer JavaDoc sb)
491     {
492         if (!isDeclared)
493         {
494             isDeclared = true;
495             sb.append("<input type=\"hidden\" name=\"")
496                     .append(gid)
497                     .append("\" value=\"")
498                     .append(oid)
499                     .append("\"/>\n");
500         }
501     }
502
503     // ********** PoolableObjectFactory implementation ******************
504

505     public static class GroupFactory
506             extends BaseKeyedPoolableObjectFactory
507     {
508         private AppData appData;
509
510         public GroupFactory(AppData appData)
511         {
512             this.appData = appData;
513         }
514
515         /**
516          * Creates an instance that can be returned by the pool.
517          * @return an instance that can be returned by the pool.
518          * @throws IntakeException indicates that the group could not be retreived
519          */

520         public Object JavaDoc makeObject(Object JavaDoc key) throws IntakeException
521         {
522             return new Group(appData.getGroup((String JavaDoc) key));
523         }
524
525         /**
526          * Uninitialize an instance to be returned to the pool.
527          * @param obj the instance to be passivated
528          */

529         public void passivateObject(Object JavaDoc key, Object JavaDoc obj)
530         {
531             Group group = (Group) obj;
532             group.oid = null;
533             group.pp = null;
534             for (int i = group.fieldsArray.length - 1; i >= 0; i--)
535             {
536                 group.fieldsArray[i].dispose();
537             }
538             group.isDeclared = false;
539         }
540     }
541 }
542
543
544
Popular Tags