KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > services > controller > ui > DefaultAutoElement


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64 package com.jcorporate.expresso.services.controller.ui;
65
66 import com.jcorporate.expresso.core.ExpressoSchema;
67 import com.jcorporate.expresso.core.controller.Block;
68 import com.jcorporate.expresso.core.controller.ControllerException;
69 import com.jcorporate.expresso.core.controller.ControllerRequest;
70 import com.jcorporate.expresso.core.controller.ControllerResponse;
71 import com.jcorporate.expresso.core.controller.ErrorCollection;
72 import com.jcorporate.expresso.core.controller.Input;
73 import com.jcorporate.expresso.core.controller.Output;
74 import com.jcorporate.expresso.core.dataobjects.DataException;
75 import com.jcorporate.expresso.core.dataobjects.DataField;
76 import com.jcorporate.expresso.core.dataobjects.DataFieldMetaData;
77 import com.jcorporate.expresso.core.dataobjects.DataObject;
78 import com.jcorporate.expresso.core.dataobjects.DataObjectMetaData;
79 import com.jcorporate.expresso.core.dataobjects.NestableDataObject;
80 import com.jcorporate.expresso.core.db.DBException;
81 import com.jcorporate.expresso.core.dbobj.DBObject;
82 import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
83 import com.jcorporate.expresso.core.dbobj.ValidValue;
84 import com.jcorporate.expresso.core.misc.ConfigManager;
85 import com.jcorporate.expresso.core.misc.DateTime;
86 import com.jcorporate.expresso.core.misc.Format;
87 import com.jcorporate.expresso.core.misc.StringUtil;
88 import com.jcorporate.expresso.kernel.util.FastStringBuffer;
89 import com.jcorporate.expresso.services.dbobj.MediaDBObject;
90 import com.jcorporate.expresso.services.dbobj.MimeTypes;
91 import org.apache.log4j.Logger;
92
93 import java.text.DateFormat JavaDoc;
94 import java.text.ParseException JavaDoc;
95 import java.text.SimpleDateFormat JavaDoc;
96 import java.util.Date JavaDoc;
97 import java.util.HashMap JavaDoc;
98 import java.util.Iterator JavaDoc;
99 import java.util.Locale JavaDoc;
100 import java.util.Map JavaDoc;
101 import java.util.Vector JavaDoc;
102
103
104 /**
105  * Default implementation of the AutoController Element. Provides a default
106  * unified method for rendering/parsing Inputs from DBObjects
107  *
108  * @author Michael Rimov, portions from Adam Rossi, Michael Nash, Shash
109  * Chatterjee
110  * @since Expresso 5.0
111  */

112 public class DefaultAutoElement implements AutoControllerElement {
113     /**
114      * singleton instance
115      */

116     protected static AutoControllerElement theDefault = null;
117
118     /**
119      *
120      */

121     public static final String JavaDoc CLASS_HANDLER_NAME = "AutoControllerElement";
122
123     /**
124      *
125      */

126     public static final String JavaDoc DEFAULT_CLASS_HANDLER = DefaultAutoElement.class.getName();
127
128     /**
129      *
130      */

131     public static final String JavaDoc DEFAULT_STYLE = "jc-formfield";
132
133     /**
134      *
135      */

136     public static final String JavaDoc REQUIRED_STYLE = "jc-required-field";
137
138     /**
139      *
140      */

141     public static final String JavaDoc ERROR_STYLE = "jc-error-field";
142
143     /**
144      *
145      */

146     protected static Logger log = Logger.getLogger(DefaultAutoElement.class);
147
148     /**
149      *
150      */

151     public static final String JavaDoc SESSION_KEY = "expresso.services.controller.ui.dbobjList";
152     private static final String JavaDoc EXPRESSO_SCHEMA = ExpressoSchema.class.getName();
153     public static final String JavaDoc DBOBJECT_LABEL = "dbobject";
154     public static final String JavaDoc BLOCK_TITLE = "block-title";
155
156     /**
157      * The constructor here is protected. Use getAutoControllerElement()
158      * instead to get the instance of this class.
159      */

160     protected DefaultAutoElement() {
161     }
162
163     /**
164      * Constructor. Allows for a classHandler to be used from the
165      * expresso-config.xml if you really need something completely different.
166      *
167      * @return an instantiated AutoControllerElement
168      * @throws ControllerException upon error
169      */

170     public static synchronized AutoControllerElement getAutoControllerElement()
171             throws ControllerException {
172         if (theDefault == null) {
173             String JavaDoc classHandler = ConfigManager.getClassHandler("AutoControllerElement");
174
175             if (classHandler == null) {
176                 classHandler = DEFAULT_CLASS_HANDLER;
177             }
178
179             try {
180                 theDefault = (AutoControllerElement) Class.forName(classHandler)
181                         .newInstance();
182             } catch (Exception JavaDoc e) {
183                 log.error("Unable to instantiate controller renderer", e);
184                 throw new ControllerException("Error instantiating controller renderer",
185                         e);
186             }
187         }
188
189         return theDefault;
190     }
191
192     /**
193      * Returns the style to be used if the Input field has an error with it.
194      *
195      * @return java.lang.String a Stylesheet class to render to
196      */

197     public String JavaDoc getErrorStyle() {
198         return ERROR_STYLE;
199     }
200
201     /**
202      * Returns the style to be used if the input has normal non-required
203      * characteristics
204      *
205      * @return java.lang.String a Stylesheet class to render to
206      */

207     public String JavaDoc getNormalStyle() {
208         return DEFAULT_STYLE;
209     }
210
211     /**
212      * Returns the string to append to a field label if it is required.
213      * Default is an &quot;&quot;
214      *
215      * @return java.lang.String a Stylesheet class to render to
216      */

217     public String JavaDoc getRequiredDecorator() {
218         return "*";
219     }
220
221     /**
222      * Returns the style to be used if the Input is required
223      *
224      * @return java.lang.String a Stylesheet class to render to
225      */

226     public String JavaDoc getRequiredStyle() {
227         return REQUIRED_STYLE;
228     }
229
230     /**
231      * Creates a DBObject Block that contains all the non-secret fields for the
232      * DBObject. The Block will have a nested Output that matches DBObject's
233      * description unless one is not supplied in which case the nested Output
234      * will have the title "Untitled"
235      *
236      * @param response The ControllerResponse object
237      * @param request The ControllerRequest Object
238      * @param dbobj The dbObject to automatically render.
239      * @return a rendered block
240      * @throws ControllerException if there's an error rendering the DBObject
241      */

242     public Block createDBObjectBlock(ControllerRequest request, ControllerResponse response, DataObject dbobj) throws ControllerException {
243         return createDBObjectBlock(request, response,
244                 dbobj.getMetaData().getDescription(request.getLocale()), dbobj);
245     }
246
247     /**
248      * Creates a DBObject Block that contains all the non-secret fields for the
249      * DBObject.
250      *
251      * @param response The ControllerResponse object
252      * @param request The ControllerRequest Object
253      * @param title The title to give this block. The system renders a nested
254      * Output called "block-title" for the block that contains this
255      * data.
256      * @param dbobj The dbObject to automatically render.
257      * @return a rendered Block object
258      * @throws ControllerException if there's an error rendering the DBObject
259      */

260     public Block createDBObjectBlock(ControllerRequest request,
261                                      ControllerResponse response,
262                                      String JavaDoc title, DataObject dbobj)
263             throws ControllerException {
264         Block b = new Block(DBOBJECT_LABEL);
265         b.add(new Output(BLOCK_TITLE, title));
266
267         Map JavaDoc map = (Map JavaDoc) request.getSession().getAttribute(SESSION_KEY);
268         DataObject dbobj2 = dbobj;
269
270         if (map != null) {
271             DBObject temp = (DBObject) map.get(dbobj.getClass()
272                     .getName());
273
274             if (temp != null) {
275                 dbobj2 = temp;
276             }
277         }
278
279         request.getSession().removeAttribute(SESSION_KEY);
280
281         try {
282             String JavaDoc oneFieldName = null;
283             DataObjectMetaData objMetaData = dbobj2.getMetaData();
284
285             for (Iterator JavaDoc e = objMetaData.getFieldListArray().iterator();
286                  e.hasNext();) {
287                 oneFieldName = (String JavaDoc) e.next();
288
289                 if (!objMetaData.isSecret(oneFieldName)) {
290                     Input i = renderDBObjectField(response, dbobj2,
291                             oneFieldName, dbobj2.getField(oneFieldName), false);
292                     if (i != null) {
293                         b.add(i);
294                     }
295
296                     // provide hook for subclass to reset value to what user typed in
297
retrieveCachedValueInForm(response, oneFieldName, i);
298                 }
299
300
301             }
302             /* for each field */
303
304             return b;
305         } catch (DBException de) {
306             throw new ControllerException(de);
307         }
308     }
309
310     /**
311      * Used to set values in created db objects to the values found (if any)
312      * in the form cache. (the form cache is what people type into an HTML form,
313      * and if there is an error, we cache those values in order to send back the
314      * form (with error message) and have their typing preserved for the next try.)
315      *
316      * @param response ?
317      * @param oneFieldName ?
318      * @param i The Input to retrieve.
319      * @see CacheAutoElement
320      */

321     protected void retrieveCachedValueInForm(ControllerResponse response, String JavaDoc oneFieldName, Input i) throws ControllerException {
322     }
323
324
325     /**
326      * Convienence method if you only expect one DBObject to be returned from a
327      * particular form.
328      *
329      * @param request The ControllerRequest object handed down by the framework
330      * @param oneObject a single dbobject ro dumpt the parsed values into.
331      * @param ec An instantiated ErrorCollection that is filled in with any
332      * error
333      * @return a filled out DBObject
334      * @throws ControllerException if there's an error parsing the block or
335      * communicating with the underlying DBObject
336      */

337     public DataObject parseBlock(ControllerRequest request,
338                                  DataObject oneObject, ErrorCollection ec) throws ControllerException {
339         DataObject[] objs = parseBlocks(request,
340                 new DataObject[]{oneObject}, ec);
341
342         if ((objs == null) || (objs.length == 0)) {
343             return null;
344         } else {
345             return objs[0];
346         }
347     }
348
349     /**
350      * Parses the appropriate DBObject from the block. Returns the fully
351      * constructed DBOBject including any errors in the DBObject
352      *
353      * @param request The ControllerRequest object handed down by the framework
354      * @param theObjects A pre-instantiated group of DBObjects in which you
355      * expect to have the fields overwritten/filled. By using
356      * instantiated DBObjects, you can pre-fill any potentially blank
357      * fields and thus remove any Errors.
358      * @param ec An instantiated ErrorCollection that is filled in with any
359      * error
360      * @return An array of parsed DBObjects
361      * @throws ControllerException if there's an error parsing the block or
362      * communicating with the underlying DBObject
363      * @throws IllegalArgumentException if request, theObjects, or ec is null
364      */

365     public DataObject[] parseBlocks(ControllerRequest request,
366                                     DataObject[] theObjects, ErrorCollection ec) throws ControllerException {
367         if (request == null) {
368             throw new IllegalArgumentException JavaDoc("parseBlocks - request cannot be null");
369         }
370
371         if (ec == null) {
372             throw new IllegalArgumentException JavaDoc("parseBlocks - ec cannot be null");
373         }
374
375         if (theObjects == null) {
376             throw new IllegalArgumentException JavaDoc("parseBlocks - theObjects cannot be null");
377         }
378
379         String JavaDoc[] dbobjPrefixes = new String JavaDoc[theObjects.length];
380
381         //First construct the DBObjects
382
for (int i = 0; i < theObjects.length; i++) {
383             dbobjPrefixes[i] = theObjects[i].getClass().getName() +
384                     ".";
385         }
386
387         for (int i = 0; i < theObjects.length; i++) {
388             DataObject oneObject = theObjects[i];
389
390             //
391
//We have to guard against checkboxes because if they are left blank,
392
//their value is simply not submitted.
393
//
394
try {
395                 for (Iterator JavaDoc it = oneObject.getMetaData().getFieldListArray()
396                         .iterator(); it.hasNext();) {
397                     String JavaDoc fieldName = (String JavaDoc) it.next();
398                     DataFieldMetaData metadata = oneObject.getFieldMetaData(fieldName);
399
400                     if (metadata.getAttribute("checkbox") != null) {
401                         DataField dataField = oneObject.getDataField(fieldName);
402
403                         if (dataField.getFieldMetaData().isBooleanType()) {
404                             oneObject.set(fieldName, new Boolean JavaDoc(false));
405                         } else {
406                             oneObject.set(fieldName, "N");
407                         }
408                     }
409                 }
410             } catch (DBException ex) {
411                 log.error("Error checking boolean fields", ex);
412             }
413         }
414
415         //
416
//Now iterate through all the parameters to find matching parameter
417
//patterns and load them into the appropriate DBObject by calling
418
//parseSingleInput for each matching paramter.
419
//
420
for (Iterator JavaDoc e = request.getParameters().keySet().iterator();
421              e.hasNext();) {
422             String JavaDoc oneParameterName = (String JavaDoc) e.next();
423
424             for (int i = 0; i < dbobjPrefixes.length; i++) {
425                 if (oneParameterName.startsWith(dbobjPrefixes[i]) &&
426                         (oneParameterName.length() > dbobjPrefixes[i].length())) {
427                     String JavaDoc fieldName = oneParameterName.substring(dbobjPrefixes[i].length());
428
429                     // String oneParameter = request.getParameter(oneParameterName);
430
parseSingleInput(request, theObjects[i], fieldName,
431                             oneParameterName, ec);
432                 }
433             }
434         }
435
436         //
437
//Ok, we successfully parsed things without bombing, now save that parsed
438
//entity onto the Session so that we can grab it for rendering
439
//
440
Map JavaDoc dbobjList = (Map JavaDoc) request.getSession().getPersistentAttribute(SESSION_KEY);
441
442         if (dbobjList == null) {
443             dbobjList = new HashMap JavaDoc(theObjects.length);
444         }
445
446         for (int i = 0; i < theObjects.length; i++) {
447             //Now we make sure that there are no blank fields floating around
448
//that are required.
449
try {
450                 theObjects[i].setFieldsWithDefaults();
451             } catch (DataException ex1) {
452                 ec.addError(ex1.getMessage());
453                 continue;
454             }
455
456             for (Iterator JavaDoc it = theObjects[i].getMetaData().getFieldListArray()
457                     .iterator(); it.hasNext();) {
458                 String JavaDoc fieldName = (String JavaDoc) it.next();
459
460                 try {
461                     String JavaDoc fieldValue = theObjects[i].getField(fieldName);
462
463                     if ((fieldValue == null) || (fieldValue.length() == 0)) {
464                         theObjects[i].checkField(fieldName, fieldValue);
465                     }
466                 } catch (DBException dbe) {
467                     ec.addError(dbe.getMessage());
468                 }
469             }
470
471             dbobjList.put(theObjects[i].getClass().getName(), theObjects[i]);
472         }
473
474         //WE don't need session, just request scope.
475
request.getSession().setAttribute(SESSION_KEY, dbobjList);
476
477         return theObjects;
478     }
479
480     /**
481      * Parses a dbobject
482      *
483      * @param request The ControllerRequest that contains all the parameters
484      * for parsing.
485      * @param oneObject The DBObject to populate.
486      * @param ec An error Collection to send in for any parsing errors to be
487      * saved to.
488      * @param validate Set to true if you want the DBObject validated.
489      * Sometimes, like for the DBMaint search form, this is not a
490      * desired feature.
491      * @return The parsed DBObject [Although oneObject gets populated since no
492      * assignment takes place.] So you can ignore this return value
493      * if you desire.
494      * @throws IllegalArgumentException upon data exception.
495      * @throws ControllerException upon controller-related error.
496      */

497     public DataObject parseDBObject(ControllerRequest request,
498                                     DataObject oneObject, ErrorCollection ec, boolean validate)
499             throws ControllerException {
500         if (request == null) {
501             throw new IllegalArgumentException JavaDoc("parseBlocks - request cannot be null");
502         }
503
504         if (ec == null) {
505             throw new IllegalArgumentException JavaDoc("parseBlocks - ec cannot be null");
506         }
507
508         if (oneObject == null) {
509             throw new IllegalArgumentException JavaDoc("parseBlocks - theObjects cannot be null");
510         }
511
512         //
513
//We have to guard against checkboxes because if they are left blank,
514
//their value is simply not submitted.
515
//
516
try {
517             for (Iterator JavaDoc it = oneObject.getMetaData().getFieldListArray()
518                     .iterator(); it.hasNext();) {
519                 String JavaDoc fieldName = (String JavaDoc) it.next();
520                 DataFieldMetaData metadata = oneObject.getFieldMetaData(fieldName);
521
522                 if (metadata.getAttribute("checkbox") != null) {
523                     DataField dataField = oneObject.getDataField(fieldName);
524
525                     if (dataField.getFieldMetaData().isBooleanType()) {
526                         oneObject.set(fieldName, new Boolean JavaDoc(false));
527                     } else {
528                         oneObject.set(fieldName, "N");
529                     }
530                 }
531             }
532         } catch (DBException ex) {
533             log.error("Error checking boolean fields", ex);
534         }
535
536         //
537
//Now iterate through all the parameters to find matching parameter
538
//patterns and load them into the appropriate DBObject by calling
539
//parseSingleInput for each matching paramter.
540
//
541
for (Iterator JavaDoc i = oneObject.getMetaData().getFieldListArray().iterator();
542              i.hasNext();) {
543             String JavaDoc oneFieldName = (String JavaDoc) i.next();
544             String JavaDoc oneParameterValue = request.getParameter(oneFieldName);
545
546             if (oneParameterValue != null) {
547                 parseSingleInput(request, oneObject, oneFieldName, null, ec);
548             }
549         }
550
551         if (validate) {
552             for (Iterator JavaDoc it = oneObject.getMetaData().getFieldListArray()
553                     .iterator(); it.hasNext();) {
554                 String JavaDoc fieldName = (String JavaDoc) it.next();
555
556                 try {
557                     String JavaDoc fieldValue = oneObject.getField(fieldName);
558
559                     if (((fieldValue == null) || (fieldValue.length() == 0)) &&
560                             !oneObject.getFieldMetaData(fieldName).isReadOnly()) {
561                         oneObject.checkField(fieldName, fieldValue);
562                     }
563                 } catch (DBException dbe) {
564                     ec.addError(dbe.getMessage());
565                 }
566             }
567         }
568
569         //
570
//Ok, we successfully parsed things without bombing, now save that parsed
571
//entity onto the Request so that we can grab it for rendering
572
// NOTE: this is the REQUEST SCOPE, not session scope
573
//
574
Map JavaDoc dbobjList = (Map JavaDoc) request.getSession().getAttribute(SESSION_KEY);
575
576         if (dbobjList == null) {
577             dbobjList = new HashMap JavaDoc(1);
578         }
579
580         dbobjList.put(oneObject.getClass().getName(), oneObject);
581
582         request.getSession().setAttribute(SESSION_KEY, dbobjList);
583
584         return oneObject;
585     }
586
587     /**
588      * Convienence method if you only expect one DBObject to be returned from a
589      * particular form, and unlike the ParseBlock, there is no DBOBject name
590      * prefix attached to the parameter names. This is similar to the
591      * ControllerRequest validateDBObject functionality, but we're
592      * consolodating things here.
593      *
594      * @param request The ControllerRequest object handed down by the framework
595      * @param oneObject A DBObject to fill in.
596      * @param ec An instantiated ErrorCollection that is filled in with any
597      * error
598      * @return a parsed DBObject
599      * @throws ControllerException if there's an error parsing the block or
600      * communicating with the underlying DBObject
601      */

602     public DataObject parseDBObject(ControllerRequest request,
603                                     DataObject oneObject, ErrorCollection ec) throws ControllerException {
604         return parseDBObject(request, oneObject, ec, true);
605     }
606
607     /**
608      * Takes the Controller Request and appropriately parses a string for a
609      * particular field. If the field is a Date, then it parses it as such,
610      * if it is money, then it perses it as such. Etc.
611      * <h4>
612      * <p/>
613      * <p/>
614      * As of Expresso 5.1, the system properly parses multi-part request data.
615      * If a parameter is a file parameter, then it sets the following field
616      * attributes that can be retrieved by:<br/
617      * ><code> DataObject.getFieldData(fieldName).getAttribute(attribName);
618      * </code>
619      * </p>
620      * <p/>
621      * <p/>
622      * <p/>
623      * <ul>
624      * <li>
625      * Attribute: fileName - The locally accessible file name to be used for
626      * most likely saving to the database. Use <code>new
627      * File(fileName)</code> to actually access the uploaded file
628      * </li>
629      * <li>
630      * Attribute: origFileName - The original file name (without path) that was
631      * uploaded to the server through the web browser. This will be different
632      * from the attribute fileName since Expresso will rename the local file
633      * name to prevent naming collisions
634      * </li>
635      * <li>
636      * Attribute: MimeType - The system will make a guess as to the mime type
637      * of the file that was uploaded based upon the file name.
638      * </li>
639      * </ul>
640      * </p>
641      * <p/>
642      * <p/>
643      * Finally, if the target dbobj is of type MediaDBObject the fields:
644      * 'fieldName + &quot;_mimeType&quot;' and 'fieldName +
645      * &quot;_fileName&quot;' will be set with the corresponding mimeType and
646      * origFileName values
647      * </p>
648      *
649      * @param request The ControllerRequest object
650      * @param dbobj The DBObject for which we're going to put the field to
651      * @param fieldName The name of the field to parse
652      * @param parameterName The name of the http paramter to parse May be null
653      * in which case, the funciton will by default use the fieldName as
654      * the parameter name.
655      * @param ec An instantiated ErrorCollection object that will be filled
656      * with any parsing errors that may be encountered.
657      * @return java.lang.String for the value.
658      * @throws ControllerException upon parsing error
659      * @since Expresso 5.0; Multipart Request Handling since Expresso 5.1
660      */

661     public String JavaDoc parseSingleInput(ControllerRequest request, DataObject dbobj,
662                                    String JavaDoc fieldName, String JavaDoc parameterName, ErrorCollection ec)
663             throws ControllerException {
664         DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
665         Locale JavaDoc currentLocale = request.getLocale();
666
667         if (parameterName == null) {
668             parameterName = fieldName;
669         }
670
671         String JavaDoc oneParameter = request.getParameter(parameterName);
672
673         if (oneParameter == null) {
674             ec.addError("Missing field: " + fieldName);
675
676             return null;
677         }
678
679         //
680
//Check for multipart request handling.
681
//
682
if (request.isFileParameter(fieldName)) {
683             try {
684                 String JavaDoc fileName = request.getFileName(fieldName);
685                 String JavaDoc param = request.getParameter(fieldName);
686                 dbobj.getDataField(fieldName).setAttribute("fileName", fileName);
687
688                 String JavaDoc origFileName = null;
689                 String JavaDoc mimeType = null;
690
691                 if (param != null) {
692                     origFileName = getOriginalFileName(param);
693                     dbobj.getDataField(fieldName).setAttribute("origFileName",
694                             origFileName);
695                     mimeType = MimeTypes.getMimeType(fileName,
696                             request.getDataContext()).getField(MimeTypes.FLD_MIMENUMBER);
697
698                     // mimeType = MimeTypes.getFileMap(request.getDataContext())
699
// .getContentType(origFileName);
700
dbobj.getDataField(fieldName).setAttribute("mimeType",
701                             mimeType);
702                 }
703
704                 if (dbobj instanceof MediaDBObject) {
705                     MediaDBObject mediaObject = (MediaDBObject) dbobj;
706                     mediaObject.setField(fieldName + "_mimeType", mimeType);
707                     mediaObject.setField(fieldName + "_fileName", origFileName);
708                 }
709
710                 return param;
711             } catch (DBException ex) {
712                 log.warn("Validation error for field:", ex);
713                 ec.addError(ex.getMessage());
714
715                 return null;
716             }
717         }
718
719         if (!metaData.isVirtual() && !metaData.isBinaryObjectType()) {
720             try {
721                 //
722
//If we have date, or time let's try to parse it.
723
//
724
if (metaData.isDateOnlyType()) {
725                     try {
726                         DateFormat JavaDoc df = DateFormat.getDateInstance(DateFormat.SHORT,
727                                 currentLocale);
728                         df.setLenient(true);
729
730                         Date JavaDoc dt = df.parse(oneParameter);
731                         dbobj.set(fieldName,
732                                 DateTime.getDateForDB(dt, request.getDataContext()));
733
734                         // dbobj.setField(fieldName, DateTime.getDateForDB(dt,request.getDBName()));
735
} catch (ParseException JavaDoc ex) {
736                         //We try to set the field anyway, since all those > 1988-10-1
737
//type of queries need to be allowed through.
738
dbobj.set(fieldName, oneParameter);
739
740                         // dbobj.setField(fieldName, oneParameter);
741
}
742                 } else if (metaData.isTimeType()) {
743                     try {
744                         DateFormat JavaDoc df = DateFormat.getTimeInstance(DateFormat.SHORT,
745                                 currentLocale);
746                         df.setLenient(true);
747
748                         Date JavaDoc dt = df.parse(oneParameter);
749                         dbobj.set(fieldName,
750                                 DateTime.getTimeForDB(dt, request.getDataContext()));
751
752                         // dbobj.setField(fieldName, DateTime.getTimeForDB(dt,request.getDBName()));
753
} catch (ParseException JavaDoc ex) {
754                         dbobj.set(fieldName, oneParameter);
755
756                         // dbobj.setField(fieldName, oneParameter);
757
}
758                 } else if (metaData.isDateTimeType()) {
759                     try {
760                         DateFormat JavaDoc df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
761                                 DateFormat.SHORT, currentLocale);
762                         df.setLenient(true);
763
764                         Date JavaDoc dt = df.parse(oneParameter);
765                         dbobj.set(fieldName,
766                                 DateTime.getDateTimeForDB(dt,
767                                         request.getDataContext()));
768
769                         // dbobj.setField(fieldName, DateTime.getDateTimeForDB(dt,request.getDBName()));
770
} catch (ParseException JavaDoc ex) {
771                         dbobj.set(fieldName, oneParameter);
772                     }
773                 } else if (metaData.isNumericType()) {
774                     /*
775                     Numeric fields are a bit special, because DBObject.getFieldInt()
776                     will return zero if the field is null, and will throw an exception
777                     for "". getFieldInt() javadoc tells people to check
778                     DBObject.isFieldNull() for a numeric field to know whether the zero
779                     is real or not.
780
781                     DBObject.isFieldNull() will NOT return true after the empty string
782                     is put into a field.
783
784                     */

785
786                     if (oneParameter != null && oneParameter.length() == 0) {
787                         dbobj.set(fieldName, null);
788                     } else {
789                         dbobj.set(fieldName, oneParameter);
790                     }
791
792                 } else {
793 // String lookupObject = metaData.getLookupObject();
794
// String lookupField = metaData.getLookupField();
795

796                     // if (lookupObject != null && lookupObject.length() > 0 && isMappable(lookupObject)) {
797
// oneParameter = parseLookupValue(ec,dbobj,oneParameter,fieldName);
798
// }
799
dbobj.set(fieldName, oneParameter);
800                 }
801             } catch (DBException de) {
802                 if (log.isInfoEnabled()) {
803                     log.info("Validation error for field:", de);
804                 }
805
806                 ec.addError(de.getMessage());
807             }
808         }
809
810         return null;
811     }
812
813     /**
814      * Renders a DBOBject Field as either an Input or an Output. For example,
815      * if we're talking updating, then all key fields are outputs and not
816      * inputs. This function auto-detects whether we are dealing with a add()
817      * or update() situation by checking the DBObject's status. If it's NEW,
818      * then we treat this as an add form, if it is
819      *
820      * @param response The ControllerResponse object
821      * @param dbobj The parameter to render
822      * @param fieldName The name of the field to render
823      * @param cachedValue Any cached form value to put in the field.
824      * @param readOnly - If set to true, then this is automatically a read-only
825      * field... if set to false, this function might still render the
826      * field as read-only if, for example, it's a key field.
827      * @return a created Input
828      * @throws ControllerException if there's an error creating the Input Field
829      */

830     public Input renderDBObjectField(ControllerResponse response,
831                                      DataObject dbobj, String JavaDoc fieldName, String JavaDoc cachedValue, boolean readOnly)
832             throws ControllerException {
833         DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
834         DataObjectMetaData objMetadata = dbobj.getMetaData();
835
836         if (log.isDebugEnabled()) {
837             FastStringBuffer logMsg = FastStringBuffer.getInstance();
838             logMsg.append("entering renderDBObjectField. Parameters: \n\tdbobj=");
839             logMsg.append(dbobj.getClass().getName());
840             logMsg.append("\n\tfieldName=");
841             logMsg.append(fieldName);
842             logMsg.append("\n\tdefaultValue=");
843             logMsg.append(cachedValue);
844             logMsg.append("\n\treadOnly=");
845             logMsg.append(readOnly);
846             log.debug(logMsg.toString());
847             logMsg.release();
848         }
849
850         try {
851             StringUtil.assertNotBlank(fieldName, "Field Name must not be null");
852
853             if (dbobj == null) {
854                 throw new DBException("Database object must be " +
855                         "initialized before calling autoField");
856             }
857
858             if (metaData.isVirtual()) {
859                 return null;
860             }
861
862             String JavaDoc oneFieldValue = dbobj.getField(fieldName);
863
864             /// String oneFieldSize = Integer.toString(metaData.getLengthInt());
865
if (oneFieldValue == null) {
866                 oneFieldValue = ("");
867             }
868
869             // if (oneFieldSize.equals("0")) {
870
// oneFieldSize = ("30");
871
// }
872
int fieldSize = metaData.getLengthInt();
873             fieldSize = fieldSize + 2;
874
875             /* Make the longest display field size 60 characters */
876             int displayFieldSize = fieldSize;
877
878             //
879
//Numeric fields are too small since integers which may, in text
880
//take at least 6 characters are listed as only 2 byte in size via
881
//the database information
882
//
883
if (displayFieldSize > 60) {
884                 displayFieldSize = 60;
885             }
886
887             //Since most numeric values of some sort have a specific
888
//size we want the field. Then we check against the various
889
//data types and set the field appropriately.
890
if (displayFieldSize < 10) {
891                 if (metaData.isNumericType()) {
892                     displayFieldSize = 15;
893                 } else if (metaData.isDateTimeType()) {
894                     displayFieldSize = 30;
895                 } else if (metaData.isDateOnlyType()) {
896                     displayFieldSize = 15;
897                 } else if (metaData.isTimeType()) {
898                     displayFieldSize = 15;
899                 } else {
900                     displayFieldSize = 10;
901                 }
902             }
903
904             Input oneField = new Input(fieldName);
905             oneField.setDisplayLength(displayFieldSize);
906
907             if (fieldSize > displayFieldSize) {
908                 oneField.setMaxLength(fieldSize);
909             } else {
910                 oneField.setMaxLength(displayFieldSize + 2);
911             }
912
913             if ((cachedValue != null) && (cachedValue.length() > 0)) {
914                 oneFieldValue = cachedValue;
915             }
916
917 // String lookupObject = metaData.getLookupObject();
918
// String lookupField = metaData.getLookupField();
919

920             //
921
//If we have a lookup class and field, then we change the field value
922
//to that returned by renderLookupValue
923
//
924
// if (lookupObject != null && lookupObject.length() > 0 && isMappable(lookupObject)
925
// && cachedValue == null) {
926
// oneFieldValue = renderLookupValue(dbobj,oneFieldValue
927
// ,fieldName,oneField);
928
// } else {
929
oneField.setAttribute(Input.ATTRIBUTE_TYPE, metaData.getTypeString());
930
931             // }
932
Iterator JavaDoc dbAttribs = metaData.getAttributesIterator();
933
934             if (dbAttribs != null) {
935                 String JavaDoc oneAttrib = null;
936                 Object JavaDoc oneAttribValue = null;
937
938                 while (dbAttribs.hasNext()) {
939                     oneAttrib = (String JavaDoc) dbAttribs.next();
940                     oneAttribValue = metaData.getAttribute(oneAttrib);
941
942                     if (oneAttribValue != null) {
943                         oneField.setAttribute(oneAttrib,
944                                 oneAttribValue.toString());
945                     }
946                 }
947             }
948
949             // Get the localized description, including any date pattern
950
{
951                 String JavaDoc description;
952
953                 // We could also convert request to HttpServletRequest and get locale from user pref.
954
// I do not think it would be a problem, but I'm not sure this is not used in a
955
// non-web environment.
956
Locale JavaDoc locale = response.getLocale();
957
958                 //
959
// Get the non-localized value to do our own message bundle lookup in order to cascade
960
// the message bundle from the schema bundle if specified. Then lookup in the expresso
961
// bundle. If this is not what is wanted, then a simple call could sufice as follows:
962
//
963
// description = objMetadata.getDescription(locale, fieldName);
964
//
965
// --- David Lloyd
966
//
967
Object JavaDoc[] args = {};
968                 String JavaDoc stringCode = objMetadata.getDescription(fieldName);
969
970                 try {
971                     description = com.jcorporate.expresso.core.i18n.Messages.getString(objMetadata.getSchema(),
972                             locale, stringCode, args);
973                 } catch (IllegalArgumentException JavaDoc iae) {
974                     if (log.isDebugEnabled()) {
975                         log.debug("DefaultAutoElement: Key [" + stringCode +
976                                 "] not found in " + objMetadata.getSchema());
977                     }
978
979                     description = null;
980
981                     if (!objMetadata.getSchema().equals(EXPRESSO_SCHEMA)) {
982                         try {
983                             description = com.jcorporate.expresso.core.i18n.Messages.getString(EXPRESSO_SCHEMA,
984                                     locale, stringCode, args);
985                         } catch (IllegalArgumentException JavaDoc e) {
986                             description = null;
987                         }
988                     }
989                 }
990
991                 if ((description == null) || (description.length() == 0)) {
992                     description = stringCode;
993                 }
994
995                 //
996
// END OF description lookup
997
//
998
if (metaData.isDateType() && !metaData.isReadOnly()) {
999                     // try to show 'A Date (MM/dd/yyyy)'
1000
String JavaDoc pattern = DateTime.getDateFormatString(metaData.isDateOnlyType(),
1001                            locale);
1002
1003                    if (pattern.length() > 0) {
1004                        pattern = " (" + pattern + ")";
1005                    }
1006
1007                    oneField.setLabel(description + pattern);
1008                } else {
1009                    oneField.setLabel(description);
1010                }
1011            }
1012
1013            String JavaDoc dbobjStatus = dbobj.getStatus();
1014
1015            /* If the field is explicitly set to read only, then only offer */
1016            /* input to it in search mode */
1017            /* Except virtual fields, which never get input... */
1018            /* And finally also when it isn't a new record and the field name */
1019            /* is a key field */
1020            if (metaData.isReadOnly()) {
1021                readOnly = true;
1022            } else if (metaData.isVirtual()) {
1023                readOnly = true;
1024            } else if (!dbobjStatus.equals(DBObject.STATUS_NEW)) {
1025                if (dbobj.getMetaData().getKeyFieldListArray().contains(fieldName)) {
1026                    //It's a key field, it should not be changeable.
1027
readOnly = true;
1028                }
1029            }
1030
1031            /**
1032             * Don't display read only fields for a new object since they only
1033             * serve to add confusion and there is no value assigned to them
1034             * yet.
1035             */

1036            if (dbobjStatus.equals(DBObject.STATUS_NEW)) {
1037                if (metaData.isReadOnly()) {
1038                    return null;
1039                }
1040            }
1041
1042            String JavaDoc displayAttrib = (String JavaDoc) metaData.getAttribute("display");
1043
1044            if (displayAttrib != null) {
1045                oneField.setAttribute("display", displayAttrib);
1046            }
1047
1048            //Set the field value to the default value if a default value is
1049
//supplied and an existing field value does not.
1050
if ((cachedValue != null) && (cachedValue.length() > 0)) {
1051                if ((oneFieldValue == null) || (oneFieldValue.length() == 0)) {
1052                    oneField.setDefaultValue(cachedValue);
1053                }
1054            }
1055
1056            if (readOnly) {
1057                oneField = renderReadOnlyInput(response, oneField, dbobj,
1058                        fieldName, oneFieldValue);
1059            } else { /* NOT readonly */
1060
1061                String JavaDoc oneFieldSize = Integer.toString(displayFieldSize);
1062                oneField = renderReadWriteInput(response, oneField, dbobj,
1063                        fieldName, oneFieldValue, oneFieldSize);
1064            }
1065            /* else not read-only */
1066
1067            cachedValue = oneField.getDefaultValue();
1068
1069            if (!StringUtil.notNull(cachedValue).equals("")) {
1070                oneField.setDefaultValue(cachedValue);
1071
1072                if (log.isDebugEnabled()) {
1073                    log.debug("Cached value for '" + fieldName + "' was '" +
1074                            cachedValue + "'");
1075                }
1076            } else {
1077                /* If no cached value, see if the db object has a default */
1078                String JavaDoc defValue = dbobj.getMetaData().getDefaultValue(fieldName);
1079
1080                if (defValue != null) {
1081                    oneField.setDefaultValue(defValue);
1082                }
1083            }
1084
1085            return oneField;
1086        } catch (DBException dbe) {
1087            throw new ControllerException("Error rendering input.", dbe);
1088        }
1089    }
1090
1091    /**
1092     * Same as display value but for Date/DateTime types. Formats things
1093     * appropriate to the user's locale
1094     *
1095     * @param metaData the Data Field's metadata
1096     * @param dt The date value to format
1097     * @param l the User's Locale gathered from the ControllerResponse object
1098     * @return a properly formatted date
1099     */

1100    protected String JavaDoc displayValue(DataFieldMetaData metaData, Date JavaDoc dt, Locale JavaDoc l) {
1101        if (dt == null) {
1102            return "";
1103        }
1104
1105        if (metaData.isDateOnlyType()) {
1106            DateFormat JavaDoc df = DateFormat.getDateInstance(DateFormat.SHORT, l);
1107            df = modifyDateFormat(df);
1108
1109            return df.format(dt);
1110        } else if (metaData.isTimeType()) {
1111            DateFormat JavaDoc df = DateFormat.getTimeInstance(DateFormat.SHORT, l);
1112            df = modifyDateFormat(df);
1113
1114            return df.format(dt);
1115        } else {
1116            DateFormat JavaDoc df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
1117                    DateFormat.SHORT, l);
1118            df = modifyDateFormat(df);
1119
1120            return df.format(dt);
1121        }
1122    }
1123
1124    /**
1125     * Format a value for display in the HTML being returned to the client
1126     *
1127     * @param metaData The Field Metadata
1128     * @param fieldValue The value of the field
1129     * @param fieldName the name of the field to render
1130     * @param l The Locale to display the value for.
1131     * @return String The formatted field
1132     * @throws ControllerException If the field format information could not be
1133     * determined
1134     */

1135    protected String JavaDoc displayValue(DataFieldMetaData metaData,
1136                                  String JavaDoc fieldValue, String JavaDoc fieldName, Locale JavaDoc l)
1137            throws ControllerException {
1138        try {
1139            if (metaData.getTypeString().equalsIgnoreCase("money")) {
1140                if (fieldValue.length() > 0) {
1141                    return new Format("%-10.2f").form(new Double JavaDoc(fieldValue).doubleValue());
1142                }
1143            } else {
1144                return fieldValue;
1145            }
1146        } catch (NumberFormatException JavaDoc ne) {
1147            throw new ControllerException("Number for field not in a " +
1148                    "valid numeric format:" + fieldValue + ":" + ne.getMessage());
1149        }
1150
1151        return null;
1152    }
1153    /* displayValue(String, String) */
1154
1155    /**
1156     * Modifies an already instantiated Input to be a finished read only
1157     * control.
1158     *
1159     * @param response The ControllerResponse object
1160     * @param oneField The input to flesh out.
1161     * @param dbobj The data source object
1162     * @param fieldName The field name in the dbobj to render.
1163     * @param oneFieldValue The value to add to the input control.
1164     * @return a read only input
1165     * @throws DBException if there's an error communicating with the DBObject
1166     * @throws ControllerException if there's an error building the Input
1167     * field.
1168     */

1169    protected Input renderReadOnlyInput(ControllerResponse response,
1170                                        Input oneField, DataObject dbobj, String JavaDoc fieldName, String JavaDoc oneFieldValue)
1171            throws DBException, ControllerException {
1172        DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
1173        DataObjectMetaData objMetaData = dbobj.getMetaData();
1174
1175        oneField.setAttribute(Input.ATTRIBUTE_READONLY, "Y");
1176        oneField.setAttribute(Input.ATTRIBUTE_ORIGINAL_VALUE, oneFieldValue);
1177
1178        if (metaData.isMultiValued()) {
1179            java.util.List JavaDoc values = dbobj.getValidValuesList(fieldName);
1180
1181            if (values == null) {
1182                throw new DBException("Valid values for field " + fieldName +
1183                        " from object " + objMetaData.getName() + " were null");
1184            }
1185
1186            String JavaDoc fieldValue = null;
1187            ValidValue oneVV = null;
1188
1189            for (Iterator JavaDoc e = values.iterator(); e.hasNext();) {
1190                oneVV = (ValidValue) e.next();
1191
1192                if (oneVV.getValue().equals(oneFieldValue)) {
1193                    fieldValue = oneVV.getDescription();
1194                }
1195            }
1196
1197            if (fieldValue == null) {
1198                oneField.setDefaultValue(oneFieldValue);
1199            } else {
1200                oneField.setDefaultValue(fieldValue);
1201            }
1202        } else {
1203            if (metaData.isDateType()) {
1204                if ((oneFieldValue == null) || (oneFieldValue.length() == 0)) {
1205                    oneField.setDefaultValue(displayValue(metaData,
1206                            oneFieldValue, fieldName, response.getLocale()));
1207                } else {
1208                    oneField.setDefaultValue(displayValue(metaData,
1209                            dbobj.getField(fieldName), fieldName,
1210                            response.getLocale()));
1211                }
1212            } else {
1213                oneField.setDefaultValue(displayValue(metaData, oneFieldValue,
1214                        fieldName, response.getLocale()));
1215            }
1216        }
1217
1218        return oneField;
1219    }
1220
1221    /**
1222     * Modifies an already instantiated Input to be a finished Input control
1223     * specifically for a blob field. If the dbobject is a MediaObject, then
1224     * it adds the abilities to view the fields and creates an appropriate
1225     * icon.
1226     *
1227     * @param response The ControllerResponse object
1228     * @param oneField The input to flesh out.
1229     * @param dbobj The data source object
1230     * @param fieldName The field name in the dbobj to render.
1231     * @param oneFieldValue The value to add to the input control.
1232     * @param oneFieldSize The size of the Input control when finished.
1233     * @throws DBException if there's an error communicating with the DBObject
1234     * @throws ControllerException if there's an error building the Input
1235     * field.
1236     */

1237    protected void renderReadWriteBlob(ControllerResponse response,
1238                                       Input oneField, DataObject dbobj, String JavaDoc fieldName,
1239                                       String JavaDoc oneFieldValue, String JavaDoc oneFieldSize)
1240            throws DBException, ControllerException {
1241        oneField.setType("file");
1242        oneField.setDisplayLength(60);
1243
1244        if (dbobj instanceof NestableDataObject) {
1245            String JavaDoc tempFieldName = fieldName;
1246            fieldName = ((NestableDataObject) dbobj).getFieldFromNestedName(fieldName);
1247            dbobj = ((NestableDataObject) dbobj).getNestedFromFieldName(tempFieldName);
1248        }
1249
1250        if (dbobj instanceof MediaDBObject) {
1251            MediaDBObject media = (MediaDBObject) dbobj;
1252            String JavaDoc mimeNumber = media.getField(fieldName + "_mimeType");
1253
1254            if (mimeNumber == null) {
1255                return;
1256            }
1257
1258            MimeTypes mt = new MimeTypes(SecuredDBObject.SYSTEM_ACCOUNT);
1259            mt.setField(MimeTypes.FLD_MIMENUMBER, mimeNumber);
1260
1261            if (mt.find()) {
1262                oneField.setAttribute("IconURL", mt.getIconURL());
1263            } else {
1264                log.error("Unable to find mime type for mime number: " +
1265                        mimeNumber);
1266            }
1267
1268            // Transition t = new Transition("view","View"
1269
// ,com.jcorporate.expresso.services.controller.DBMaint.class,
1270
// "ViewBlob");
1271
// t.addParam("fieldName", fieldName);
1272
// t.addParam("dbobj", ((Object)dbobj).getClass().getName());
1273
}
1274    }
1275
1276    /**
1277     * Modifies an already instantiated Input to be a finished Input control
1278     *
1279     * @param response The ControllerResponse object
1280     * @param oneField The input to flesh out.
1281     * @param dbobj The data source object
1282     * @param fieldName The field name in the dbobj to render.
1283     * @param oneFieldValue The value to add to the input control.
1284     * @param oneFieldSize The size of the Input control when finished.
1285     * @return a rendered Read/Write Input
1286     * @throws DBException if there's an error communicating with the DBObject
1287     * @throws ControllerException if there's an error building the Input
1288     * field.
1289     */

1290    protected Input renderReadWriteInput(ControllerResponse response,
1291                                         Input oneField, DataObject dbobj, String JavaDoc fieldName,
1292                                         String JavaDoc oneFieldValue, String JavaDoc oneFieldSize)
1293            throws DBException, ControllerException {
1294        if (log.isDebugEnabled()) {
1295            log.debug("Entering DefaultAutoElement.renderReadWriteInput");
1296        }
1297
1298        DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
1299        DataObjectMetaData dbobjMetaData = dbobj.getMetaData();
1300
1301        DataField df = dbobj.getDataField(fieldName);
1302
1303        //
1304
//Set the appropriate display style.
1305
//
1306
if (df.getAttribute(DBObject.ATTRIBUTE_ERROR) != null) {
1307            oneField.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
1308                    getErrorStyle());
1309        } else if (!metaData.allowsNull()) {
1310            oneField.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
1311                    getRequiredStyle());
1312        } else {
1313            oneField.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
1314                    getNormalStyle());
1315        }
1316
1317        //
1318
//If it's a required field, decorate the label with a '*' or whatever
1319
//else is defined by the class.
1320
//
1321
if (!metaData.allowsNull()) {
1322            oneField.setLabel(oneField.getLabel() +
1323                    getRequiredDecorator());
1324        }
1325
1326        /* if the field is multi-valued, present a drop-down list */
1327        /* instead of just a text field */
1328        if (metaData.isMultiValued()) {
1329            oneField.setAttribute(Input.ATTRIBUTE_MULTIVALUED, "Y");
1330            oneField.setAttribute(Input.ATTRIBUTE_DROPDOWN, "Y");
1331            oneField.setType(Input.ATTRIBUTE_DROPDOWN);
1332
1333            java.util.List JavaDoc values = dbobj.getValidValuesList(fieldName);
1334
1335            //Hashtable values = dbobj.getValues(fieldName);
1336
if (values == null) {
1337                throw new DBException("Valid values for field " + fieldName +
1338                        " from object " + dbobjMetaData.getName() + " were null");
1339            }
1340
1341            oneField.setValidValues(new Vector JavaDoc(values));
1342            oneField.setDefaultValue(oneFieldValue);
1343        } else {
1344            //
1345
//If we have a blob, then it is a file to upload.
1346
//
1347
if (metaData.isBinaryObjectType()) {
1348                renderReadWriteBlob(response, oneField, dbobj, fieldName,
1349                        oneFieldValue, oneFieldSize);
1350            }
1351
1352            if (metaData.isDateType()) {
1353                oneField.setDisplayLength(10);
1354
1355                // oneField.setMaxLength(10 + 2);
1356
if ((oneFieldValue == null) || (oneFieldValue.length() == 0)) {
1357                    oneField.setDefaultValue(displayValue(metaData,
1358                            oneFieldValue, fieldName, response.getLocale()));
1359                } else {
1360                    oneField.setDefaultValue(displayValue(metaData,
1361                            dbobj.getDataField(fieldName).asDate(),
1362                            response.getLocale()));
1363                }
1364            } else {
1365                if (metaData.isCharacterLongObjectType()) {
1366                    oneField.setDisplayLength(80);
1367                    oneField.setLines(4);
1368                    oneField.setMaxLength(4096);
1369                    oneField.setType("text");
1370                } else {
1371                    // oneField.setMaxLength(new Integer(oneFieldSize).intValue());
1372
}
1373
1374                oneField.setDefaultValue(displayValue(metaData, oneFieldValue,
1375                        fieldName, response.getLocale()));
1376            }
1377        }
1378
1379        if (log.isDebugEnabled()) {
1380            if (oneField != null) {
1381                log.debug("Leaving DefaultAutoElement.renderReadWriteInput " +
1382                        oneField.toString());
1383            } else {
1384                log.debug("Leaving DefaultAutoElement.renderReadWriteInput oneField=null");
1385            }
1386        }
1387
1388        return oneField;
1389    }
1390
1391    /**
1392     * For lookup objects that also define a lookup object AND lookup field,
1393     * then attempt to match the field key with the lookup field value
1394     *
1395     * @param className the DataObject to use as the metadata source
1396     *
1397     * @return String value of the lookup value.
1398     */

1399
1400    // protected String renderLookupValue(DataObject object, String curValue,
1401
// String fieldName,Input i) throws DataException {
1402
// if (curValue == null || curValue.length() == 0) {
1403
// return "";
1404
// }
1405
//
1406
// DataFieldMetaData fieldMetadata = object.getFieldMetaData(fieldName);
1407
// String lookupObject = fieldMetadata.getLookupObject();
1408
//
1409
// Mappable mapObject = constructMappableObject(object,fieldName);
1410
// i.setDescription(mapObject.getMappedDescription());
1411
// return mapObject.getMappedValue(curValue);
1412
// }
1413

1414    /**
1415     * Parses the lookup value. Adds to the ErrorCollection if referential
1416     * integrity cannot be established
1417     *
1418     * @param className the error collection to add errors to if any occur.
1419     *
1420     * @return the lookup value
1421     */

1422
1423    // private String parseLookupValue(ErrorCollection ec,
1424
// DataObject object, String curValue,
1425
// String fieldName) throws DataException {
1426
// if (curValue== null || curValue.length() == 0) {
1427
// return null;
1428
// }
1429
//
1430
// DataFieldMetaData fieldMetadata = object.getFieldMetaData(fieldName);
1431
// String lookupObject = fieldMetadata.getLookupObject();
1432
//
1433
// Mappable mapObject = constructMappableObject(object,fieldName);
1434
// return mapObject.getKeyValue(curValue);
1435
//
1436
// }
1437
//
1438

1439    /**
1440     * Checks to see if a lookup object is mappable.
1441     *
1442     * @param className the class name to test
1443     *
1444     * @return true if the class implements mappable, false otherwise.
1445     */

1446// private boolean isMappable(String className)
1447
// {
1448
// try {
1449
// Object o = ClassLocator.loadClass(className).newInstance();
1450
//
1451
// if (o instanceof Mappable) {
1452
// return true;
1453
// } else {
1454
// return false;
1455
// }
1456
// } catch (InstantiationException ex) {
1457
// log.error("Error instantiating object " + className, ex);
1458
//
1459
// return false;
1460
// } catch (IllegalAccessException ex) {
1461
// log.error("Error instantiating object " + className, ex);
1462
//
1463
// return false;
1464
// } catch (ClassNotFoundException ex) {
1465
// log.error("Error instantiating object " + className, ex);
1466
//
1467
// return false;
1468
// }
1469
// }
1470

1471    /**
1472     * Given a file pathname, tell us what the name without the path is.
1473     *
1474     * @param fileNameParam The file name of the file that was uploaded ot the
1475     * server.
1476     * @return a java.lang.String that contains the file name without any path
1477     * associated with it.
1478     */

1479    private String JavaDoc getOriginalFileName(String JavaDoc fileNameParam) {
1480        if (fileNameParam == null) {
1481            return null;
1482        }
1483
1484        int lastSlash = fileNameParam.lastIndexOf("\\");
1485
1486        if (lastSlash < 0) {
1487            lastSlash = fileNameParam.lastIndexOf("/");
1488
1489            if (lastSlash < 0) {
1490                return fileNameParam;
1491            }
1492        }
1493
1494        return fileNameParam.substring(lastSlash + 1);
1495    }
1496
1497    /**
1498     * Constructs an object to perform the lookups based upon the lookup
1499     * object, and lookup definition names.
1500     *
1501     * @param sourceObject the object where we get the metadata, and source
1502     * data context
1503     * @param fieldName the name of the field to get the lookup object for
1504     *
1505     * @return an instantiated DataObject.
1506     *
1507     * @throws IllegalArgumentException
1508     */

1509// private DataObject constructLookupObject(DataObject sourceObject,
1510
// String fieldName) throws DataException
1511
// {
1512
// DataFieldMetaData fieldMetadata = sourceObject.getFieldMetaData(fieldName);
1513
// String lookupObject = fieldMetadata.getLookupObject();
1514
// String definitionName = fieldMetadata.getLookupDefinition();
1515
//
1516
// if ((lookupObject == null) || (lookupObject.length() == 0)) {
1517
// throw new IllegalArgumentException(
1518
// "Was asked to construct lookup object that didn't exist for field: " +
1519
// fieldName);
1520
// }
1521
//
1522
// DataObject returnValue = null;
1523
// Class returnClass = null;
1524
//
1525
// try {
1526
// returnClass = ClassLocator.loadClass(lookupObject);
1527
// } catch (ClassNotFoundException ex) {
1528
// log.error("Class Not Found Exception", ex);
1529
// throw new IllegalArgumentException("Error finding lookup object: " +
1530
// lookupObject);
1531
// }
1532
//
1533
// returnValue = com.jcorporate.expresso.core.dataobjects.DataObjectFactory.createDataObject(returnClass,
1534
// sourceObject.getDataContext(), definitionName,
1535
// Securable.SYSTEM_ACCOUNT);
1536
//
1537
// try {
1538
// returnValue.clear();
1539
// } catch (DBException ex) {
1540
// throw new DataException("Error clearing new data object");
1541
// }
1542
//
1543
// return returnValue;
1544
// }
1545

1546    /**
1547     * Constructs a properly instantiated mappable object
1548     *
1549     * @param sourceObject the dataobject where we get the lookup names, etc
1550     * @param fieldName the field name to get the lookup for
1551     *
1552     * @return a properly constructed Mappable object
1553     *
1554     * @throws IllegalArgumentException
1555     */

1556// private Mappable constructMappableObject(DataObject sourceObject,
1557
// String fieldName) throws DataException
1558
// {
1559
// DataFieldMetaData fieldMetadata = sourceObject.getFieldMetaData(fieldName);
1560
// String lookupObject = fieldMetadata.getLookupObject();
1561
// String definitionName = fieldMetadata.getLookupDefinition();
1562
//
1563
// if ((lookupObject == null) || (lookupObject.length() == 0)) {
1564
// throw new IllegalArgumentException(
1565
// "Was asked to construct lookup object that didn't exist for field: " +
1566
// fieldName);
1567
// }
1568
//
1569
// Object returnValue = null;
1570
// Class returnClass = null;
1571
//
1572
// try {
1573
// returnClass = ClassLocator.loadClass(lookupObject);
1574
// } catch (ClassNotFoundException ex) {
1575
// log.error("Class Not Found Exception", ex);
1576
// throw new IllegalArgumentException("Error finding lookup object: " +
1577
// lookupObject);
1578
// }
1579
//
1580
// returnValue = com.jcorporate.expresso.core.dataobjects.DataObjectFactory.createObject(returnClass,
1581
// sourceObject.getDataContext(), definitionName,
1582
// Securable.SYSTEM_ACCOUNT);
1583
//
1584
// if (returnValue instanceof Mappable) {
1585
// return (Mappable) returnValue;
1586
// } else {
1587
// return null;
1588
// }
1589
// }
1590

1591    /**
1592     * Gleaned from @link http://www.jguru.com/faq/view.jsp?EID=429821 to
1593     * make the SimpleDateFormat give us 4 year dates instead.
1594     *
1595     * @param df the DateFormat class
1596     * @return a proper DateFormat class to modify
1597     */

1598    private DateFormat JavaDoc modifyDateFormat(DateFormat JavaDoc df) {
1599        SimpleDateFormat JavaDoc sdf = null;
1600
1601        try {
1602            sdf = (SimpleDateFormat JavaDoc) df;
1603        } catch (ClassCastException JavaDoc cce) {
1604            return df;
1605        }
1606
1607        String JavaDoc sTemp = sdf.toPattern();
1608        int iLen = sTemp.length();
1609        int i = sTemp.lastIndexOf('y') + 1;
1610        sTemp = sTemp.substring(0, i) + "yy" +
1611                ((i < iLen) ? sTemp.substring(i, iLen) : "");
1612        sdf.applyPattern(sTemp);
1613
1614        return sdf;
1615    }
1616}
1617
Popular Tags