Source Code Cross Referenced for DefaultAutoElement.java in  » J2EE » Expresso » com » jcorporate » expresso » services » controller » ui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » Expresso » com.jcorporate.expresso.services.controller.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ====================================================================
0002:         * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
0003:         *
0004:         * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
0005:         *
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         *
0010:         * 1. Redistributions of source code must retain the above copyright
0011:         *    notice, this list of conditions and the following disclaimer.
0012:         *
0013:         * 2. Redistributions in binary form must reproduce the above copyright
0014:         *    notice, this list of conditions and the following disclaimer in
0015:         *    the documentation and/or other materials provided with the
0016:         *    distribution.
0017:         *
0018:         * 3. The end-user documentation included with the redistribution,
0019:         *    if any, must include the following acknowledgment:
0020:         *       "This product includes software developed by Jcorporate Ltd.
0021:         *        (http://www.jcorporate.com/)."
0022:         *    Alternately, this acknowledgment may appear in the software itself,
0023:         *    if and wherever such third-party acknowledgments normally appear.
0024:         *
0025:         * 4. "Jcorporate" and product names such as "Expresso" must
0026:         *    not be used to endorse or promote products derived from this
0027:         *    software without prior written permission. For written permission,
0028:         *    please contact info@jcorporate.com.
0029:         *
0030:         * 5. Products derived from this software may not be called "Expresso",
0031:         *    or other Jcorporate product names; nor may "Expresso" or other
0032:         *    Jcorporate product names appear in their name, without prior
0033:         *    written permission of Jcorporate Ltd.
0034:         *
0035:         * 6. No product derived from this software may compete in the same
0036:         *    market space, i.e. framework, without prior written permission
0037:         *    of Jcorporate Ltd. For written permission, please contact
0038:         *    partners@jcorporate.com.
0039:         *
0040:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0041:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0042:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0043:         * DISCLAIMED.  IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
0044:         * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0045:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
0046:         * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0047:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0048:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0049:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0050:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0051:         * SUCH DAMAGE.
0052:         * ====================================================================
0053:         *
0054:         * This software consists of voluntary contributions made by many
0055:         * individuals on behalf of the Jcorporate Ltd. Contributions back
0056:         * to the project(s) are encouraged when you make modifications.
0057:         * Please send them to support@jcorporate.com. For more information
0058:         * on Jcorporate Ltd. and its products, please see
0059:         * <http://www.jcorporate.com/>.
0060:         *
0061:         * Portions of this software are based upon other open source
0062:         * products and are subject to their respective licenses.
0063:         */
0064:        package com.jcorporate.expresso.services.controller.ui;
0065:
0066:        import com.jcorporate.expresso.core.ExpressoSchema;
0067:        import com.jcorporate.expresso.core.controller.Block;
0068:        import com.jcorporate.expresso.core.controller.ControllerException;
0069:        import com.jcorporate.expresso.core.controller.ControllerRequest;
0070:        import com.jcorporate.expresso.core.controller.ControllerResponse;
0071:        import com.jcorporate.expresso.core.controller.ErrorCollection;
0072:        import com.jcorporate.expresso.core.controller.Input;
0073:        import com.jcorporate.expresso.core.controller.Output;
0074:        import com.jcorporate.expresso.core.dataobjects.DataException;
0075:        import com.jcorporate.expresso.core.dataobjects.DataField;
0076:        import com.jcorporate.expresso.core.dataobjects.DataFieldMetaData;
0077:        import com.jcorporate.expresso.core.dataobjects.DataObject;
0078:        import com.jcorporate.expresso.core.dataobjects.DataObjectMetaData;
0079:        import com.jcorporate.expresso.core.dataobjects.NestableDataObject;
0080:        import com.jcorporate.expresso.core.db.DBException;
0081:        import com.jcorporate.expresso.core.dbobj.DBObject;
0082:        import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
0083:        import com.jcorporate.expresso.core.dbobj.ValidValue;
0084:        import com.jcorporate.expresso.core.misc.ConfigManager;
0085:        import com.jcorporate.expresso.core.misc.DateTime;
0086:        import com.jcorporate.expresso.core.misc.Format;
0087:        import com.jcorporate.expresso.core.misc.StringUtil;
0088:        import com.jcorporate.expresso.kernel.util.FastStringBuffer;
0089:        import com.jcorporate.expresso.services.dbobj.MediaDBObject;
0090:        import com.jcorporate.expresso.services.dbobj.MimeTypes;
0091:        import org.apache.log4j.Logger;
0092:
0093:        import java.text.DateFormat;
0094:        import java.text.ParseException;
0095:        import java.text.SimpleDateFormat;
0096:        import java.util.Date;
0097:        import java.util.HashMap;
0098:        import java.util.Iterator;
0099:        import java.util.Locale;
0100:        import java.util.Map;
0101:        import java.util.Vector;
0102:
0103:        /**
0104:         * Default implementation of the AutoController Element. Provides a default
0105:         * unified method for rendering/parsing Inputs from DBObjects
0106:         *
0107:         * @author Michael Rimov, portions from Adam Rossi, Michael Nash, Shash
0108:         *         Chatterjee
0109:         * @since Expresso 5.0
0110:         */
0111:        public class DefaultAutoElement implements  AutoControllerElement {
0112:            /**
0113:             * singleton instance
0114:             */
0115:            protected static AutoControllerElement theDefault = null;
0116:
0117:            /**
0118:             *
0119:             */
0120:            public static final String CLASS_HANDLER_NAME = "AutoControllerElement";
0121:
0122:            /**
0123:             *
0124:             */
0125:            public static final String DEFAULT_CLASS_HANDLER = DefaultAutoElement.class
0126:                    .getName();
0127:
0128:            /**
0129:             *
0130:             */
0131:            public static final String DEFAULT_STYLE = "jc-formfield";
0132:
0133:            /**
0134:             *
0135:             */
0136:            public static final String REQUIRED_STYLE = "jc-required-field";
0137:
0138:            /**
0139:             *
0140:             */
0141:            public static final String ERROR_STYLE = "jc-error-field";
0142:
0143:            /**
0144:             *
0145:             */
0146:            protected static Logger log = Logger
0147:                    .getLogger(DefaultAutoElement.class);
0148:
0149:            /**
0150:             *
0151:             */
0152:            public static final String SESSION_KEY = "expresso.services.controller.ui.dbobjList";
0153:            private static final String EXPRESSO_SCHEMA = ExpressoSchema.class
0154:                    .getName();
0155:            public static final String DBOBJECT_LABEL = "dbobject";
0156:            public static final String BLOCK_TITLE = "block-title";
0157:
0158:            /**
0159:             * The constructor here is protected.  Use getAutoControllerElement()
0160:             * instead to get the instance of this class.
0161:             */
0162:            protected DefaultAutoElement() {
0163:            }
0164:
0165:            /**
0166:             * Constructor.  Allows for a classHandler to be used from the
0167:             * expresso-config.xml if you really need something completely different.
0168:             *
0169:             * @return an instantiated AutoControllerElement
0170:             * @throws ControllerException upon error
0171:             */
0172:            public static synchronized AutoControllerElement getAutoControllerElement()
0173:                    throws ControllerException {
0174:                if (theDefault == null) {
0175:                    String classHandler = ConfigManager
0176:                            .getClassHandler("AutoControllerElement");
0177:
0178:                    if (classHandler == null) {
0179:                        classHandler = DEFAULT_CLASS_HANDLER;
0180:                    }
0181:
0182:                    try {
0183:                        theDefault = (AutoControllerElement) Class.forName(
0184:                                classHandler).newInstance();
0185:                    } catch (Exception e) {
0186:                        log.error("Unable to instantiate controller renderer",
0187:                                e);
0188:                        throw new ControllerException(
0189:                                "Error instantiating controller renderer", e);
0190:                    }
0191:                }
0192:
0193:                return theDefault;
0194:            }
0195:
0196:            /**
0197:             * Returns the style to be used if the Input field has an error with it.
0198:             *
0199:             * @return java.lang.String a Stylesheet class to render to
0200:             */
0201:            public String getErrorStyle() {
0202:                return ERROR_STYLE;
0203:            }
0204:
0205:            /**
0206:             * Returns the style to be used if the input has normal non-required
0207:             * characteristics
0208:             *
0209:             * @return java.lang.String a Stylesheet class to render to
0210:             */
0211:            public String getNormalStyle() {
0212:                return DEFAULT_STYLE;
0213:            }
0214:
0215:            /**
0216:             * Returns the string to append to a field label if it is required.
0217:             * Default is an &quot;&quot;
0218:             *
0219:             * @return java.lang.String a Stylesheet class to render to
0220:             */
0221:            public String getRequiredDecorator() {
0222:                return "*";
0223:            }
0224:
0225:            /**
0226:             * Returns the style to be used if the Input is required
0227:             *
0228:             * @return java.lang.String a Stylesheet class to render to
0229:             */
0230:            public String getRequiredStyle() {
0231:                return REQUIRED_STYLE;
0232:            }
0233:
0234:            /**
0235:             * Creates a DBObject Block that contains all the non-secret fields for the
0236:             * DBObject.  The Block will have a nested Output that matches DBObject's
0237:             * description unless one is not supplied in which case the nested Output
0238:             * will have the title "Untitled"
0239:             *
0240:             * @param response The ControllerResponse object
0241:             * @param request  The ControllerRequest Object
0242:             * @param dbobj    The dbObject to automatically render.
0243:             * @return a rendered block
0244:             * @throws ControllerException if there's an error rendering the DBObject
0245:             */
0246:            public Block createDBObjectBlock(ControllerRequest request,
0247:                    ControllerResponse response, DataObject dbobj)
0248:                    throws ControllerException {
0249:                return createDBObjectBlock(request, response, dbobj
0250:                        .getMetaData().getDescription(request.getLocale()),
0251:                        dbobj);
0252:            }
0253:
0254:            /**
0255:             * Creates a DBObject Block that contains all the non-secret fields for the
0256:             * DBObject.
0257:             *
0258:             * @param response The ControllerResponse object
0259:             * @param request  The ControllerRequest Object
0260:             * @param title    The title to give this block.  The system renders a nested
0261:             *                 Output called "block-title" for the block that contains this
0262:             *                 data.
0263:             * @param dbobj    The dbObject to automatically render.
0264:             * @return a rendered Block object
0265:             * @throws ControllerException if there's an error rendering the DBObject
0266:             */
0267:            public Block createDBObjectBlock(ControllerRequest request,
0268:                    ControllerResponse response, String title, DataObject dbobj)
0269:                    throws ControllerException {
0270:                Block b = new Block(DBOBJECT_LABEL);
0271:                b.add(new Output(BLOCK_TITLE, title));
0272:
0273:                Map map = (Map) request.getSession().getAttribute(SESSION_KEY);
0274:                DataObject dbobj2 = dbobj;
0275:
0276:                if (map != null) {
0277:                    DBObject temp = (DBObject) map.get(dbobj.getClass()
0278:                            .getName());
0279:
0280:                    if (temp != null) {
0281:                        dbobj2 = temp;
0282:                    }
0283:                }
0284:
0285:                request.getSession().removeAttribute(SESSION_KEY);
0286:
0287:                try {
0288:                    String oneFieldName = null;
0289:                    DataObjectMetaData objMetaData = dbobj2.getMetaData();
0290:
0291:                    for (Iterator e = objMetaData.getFieldListArray()
0292:                            .iterator(); e.hasNext();) {
0293:                        oneFieldName = (String) e.next();
0294:
0295:                        if (!objMetaData.isSecret(oneFieldName)) {
0296:                            Input i = renderDBObjectField(response, dbobj2,
0297:                                    oneFieldName,
0298:                                    dbobj2.getField(oneFieldName), false);
0299:                            if (i != null) {
0300:                                b.add(i);
0301:                            }
0302:
0303:                            // provide hook for subclass to reset value to what user typed in
0304:                            retrieveCachedValueInForm(response, oneFieldName, i);
0305:                        }
0306:
0307:                    }
0308:                    /* for each field */
0309:
0310:                    return b;
0311:                } catch (DBException de) {
0312:                    throw new ControllerException(de);
0313:                }
0314:            }
0315:
0316:            /**
0317:             * Used to set values in created db objects to the values found (if any)
0318:             * in the form cache. (the form cache is what people type into an HTML form,
0319:             * and if there is an error, we cache those values in order to send back the
0320:             * form (with error message) and have their typing preserved for the next try.)
0321:             *
0322:             * @param response     ?
0323:             * @param oneFieldName ?
0324:             * @param i            The Input to retrieve.
0325:             * @see CacheAutoElement
0326:             */
0327:            protected void retrieveCachedValueInForm(
0328:                    ControllerResponse response, String oneFieldName, Input i)
0329:                    throws ControllerException {
0330:            }
0331:
0332:            /**
0333:             * Convienence method if you only expect one DBObject to be returned from a
0334:             * particular form.
0335:             *
0336:             * @param request   The ControllerRequest object handed down by the framework
0337:             * @param oneObject a single dbobject ro dumpt the parsed values into.
0338:             * @param ec        An instantiated ErrorCollection that is filled in with any
0339:             *                  error
0340:             * @return a filled out DBObject
0341:             * @throws ControllerException if there's an error parsing the block or
0342:             *                             communicating with the underlying DBObject
0343:             */
0344:            public DataObject parseBlock(ControllerRequest request,
0345:                    DataObject oneObject, ErrorCollection ec)
0346:                    throws ControllerException {
0347:                DataObject[] objs = parseBlocks(request,
0348:                        new DataObject[] { oneObject }, ec);
0349:
0350:                if ((objs == null) || (objs.length == 0)) {
0351:                    return null;
0352:                } else {
0353:                    return objs[0];
0354:                }
0355:            }
0356:
0357:            /**
0358:             * Parses the appropriate DBObject from the block.  Returns the fully
0359:             * constructed DBOBject including any errors in the DBObject
0360:             *
0361:             * @param request    The ControllerRequest object handed down by the framework
0362:             * @param theObjects A pre-instantiated group of DBObjects in which you
0363:             *                   expect to have the fields overwritten/filled.  By using
0364:             *                   instantiated DBObjects, you can pre-fill any potentially blank
0365:             *                   fields and thus remove any Errors.
0366:             * @param ec         An instantiated ErrorCollection that is filled in with any
0367:             *                   error
0368:             * @return An array of parsed DBObjects
0369:             * @throws ControllerException      if there's an error parsing the block or
0370:             *                                  communicating with the underlying DBObject
0371:             * @throws IllegalArgumentException if request, theObjects, or ec is null
0372:             */
0373:            public DataObject[] parseBlocks(ControllerRequest request,
0374:                    DataObject[] theObjects, ErrorCollection ec)
0375:                    throws ControllerException {
0376:                if (request == null) {
0377:                    throw new IllegalArgumentException(
0378:                            "parseBlocks - request cannot be null");
0379:                }
0380:
0381:                if (ec == null) {
0382:                    throw new IllegalArgumentException(
0383:                            "parseBlocks - ec cannot be null");
0384:                }
0385:
0386:                if (theObjects == null) {
0387:                    throw new IllegalArgumentException(
0388:                            "parseBlocks - theObjects cannot be null");
0389:                }
0390:
0391:                String[] dbobjPrefixes = new String[theObjects.length];
0392:
0393:                //First construct the DBObjects
0394:                for (int i = 0; i < theObjects.length; i++) {
0395:                    dbobjPrefixes[i] = theObjects[i].getClass().getName() + ".";
0396:                }
0397:
0398:                for (int i = 0; i < theObjects.length; i++) {
0399:                    DataObject oneObject = theObjects[i];
0400:
0401:                    //
0402:                    //We have to guard against checkboxes because if they are left blank,
0403:                    //their value is simply not submitted.
0404:                    //
0405:                    try {
0406:                        for (Iterator it = oneObject.getMetaData()
0407:                                .getFieldListArray().iterator(); it.hasNext();) {
0408:                            String fieldName = (String) it.next();
0409:                            DataFieldMetaData metadata = oneObject
0410:                                    .getFieldMetaData(fieldName);
0411:
0412:                            if (metadata.getAttribute("checkbox") != null) {
0413:                                DataField dataField = oneObject
0414:                                        .getDataField(fieldName);
0415:
0416:                                if (dataField.getFieldMetaData()
0417:                                        .isBooleanType()) {
0418:                                    oneObject
0419:                                            .set(fieldName, new Boolean(false));
0420:                                } else {
0421:                                    oneObject.set(fieldName, "N");
0422:                                }
0423:                            }
0424:                        }
0425:                    } catch (DBException ex) {
0426:                        log.error("Error checking boolean fields", ex);
0427:                    }
0428:                }
0429:
0430:                //
0431:                //Now iterate through all the parameters to find matching parameter
0432:                //patterns and load them into the appropriate DBObject by calling
0433:                //parseSingleInput for each matching paramter.
0434:                //
0435:                for (Iterator e = request.getParameters().keySet().iterator(); e
0436:                        .hasNext();) {
0437:                    String oneParameterName = (String) e.next();
0438:
0439:                    for (int i = 0; i < dbobjPrefixes.length; i++) {
0440:                        if (oneParameterName.startsWith(dbobjPrefixes[i])
0441:                                && (oneParameterName.length() > dbobjPrefixes[i]
0442:                                        .length())) {
0443:                            String fieldName = oneParameterName
0444:                                    .substring(dbobjPrefixes[i].length());
0445:
0446:                            //                    String oneParameter = request.getParameter(oneParameterName);
0447:                            parseSingleInput(request, theObjects[i], fieldName,
0448:                                    oneParameterName, ec);
0449:                        }
0450:                    }
0451:                }
0452:
0453:                //
0454:                //Ok, we successfully parsed things without bombing, now save that parsed
0455:                //entity onto the Session so that we can grab it for rendering
0456:                //
0457:                Map dbobjList = (Map) request.getSession()
0458:                        .getPersistentAttribute(SESSION_KEY);
0459:
0460:                if (dbobjList == null) {
0461:                    dbobjList = new HashMap(theObjects.length);
0462:                }
0463:
0464:                for (int i = 0; i < theObjects.length; i++) {
0465:                    //Now we make sure that there are no blank fields floating around
0466:                    //that are required.
0467:                    try {
0468:                        theObjects[i].setFieldsWithDefaults();
0469:                    } catch (DataException ex1) {
0470:                        ec.addError(ex1.getMessage());
0471:                        continue;
0472:                    }
0473:
0474:                    for (Iterator it = theObjects[i].getMetaData()
0475:                            .getFieldListArray().iterator(); it.hasNext();) {
0476:                        String fieldName = (String) it.next();
0477:
0478:                        try {
0479:                            String fieldValue = theObjects[i]
0480:                                    .getField(fieldName);
0481:
0482:                            if ((fieldValue == null)
0483:                                    || (fieldValue.length() == 0)) {
0484:                                theObjects[i].checkField(fieldName, fieldValue);
0485:                            }
0486:                        } catch (DBException dbe) {
0487:                            ec.addError(dbe.getMessage());
0488:                        }
0489:                    }
0490:
0491:                    dbobjList.put(theObjects[i].getClass().getName(),
0492:                            theObjects[i]);
0493:                }
0494:
0495:                //WE don't need session, just request scope.
0496:                request.getSession().setAttribute(SESSION_KEY, dbobjList);
0497:
0498:                return theObjects;
0499:            }
0500:
0501:            /**
0502:             * Parses a dbobject
0503:             *
0504:             * @param request   The ControllerRequest that contains all the parameters
0505:             *                  for parsing.
0506:             * @param oneObject The DBObject to populate.
0507:             * @param ec        An error Collection to send in for any parsing errors to be
0508:             *                  saved to.
0509:             * @param validate  Set to true if you want the DBObject validated.
0510:             *                  Sometimes, like for the DBMaint search form, this is not a
0511:             *                  desired feature.
0512:             * @return The parsed DBObject [Although oneObject gets populated since no
0513:             *         assignment takes place.]  So you can ignore this return value
0514:             *         if you desire.
0515:             * @throws IllegalArgumentException upon data exception.
0516:             * @throws ControllerException      upon controller-related error.
0517:             */
0518:            public DataObject parseDBObject(ControllerRequest request,
0519:                    DataObject oneObject, ErrorCollection ec, boolean validate)
0520:                    throws ControllerException {
0521:                if (request == null) {
0522:                    throw new IllegalArgumentException(
0523:                            "parseBlocks - request cannot be null");
0524:                }
0525:
0526:                if (ec == null) {
0527:                    throw new IllegalArgumentException(
0528:                            "parseBlocks - ec cannot be null");
0529:                }
0530:
0531:                if (oneObject == null) {
0532:                    throw new IllegalArgumentException(
0533:                            "parseBlocks - theObjects cannot be null");
0534:                }
0535:
0536:                //
0537:                //We have to guard against checkboxes because if they are left blank,
0538:                //their value is simply not submitted.
0539:                //
0540:                try {
0541:                    for (Iterator it = oneObject.getMetaData()
0542:                            .getFieldListArray().iterator(); it.hasNext();) {
0543:                        String fieldName = (String) it.next();
0544:                        DataFieldMetaData metadata = oneObject
0545:                                .getFieldMetaData(fieldName);
0546:
0547:                        if (metadata.getAttribute("checkbox") != null) {
0548:                            DataField dataField = oneObject
0549:                                    .getDataField(fieldName);
0550:
0551:                            if (dataField.getFieldMetaData().isBooleanType()) {
0552:                                oneObject.set(fieldName, new Boolean(false));
0553:                            } else {
0554:                                oneObject.set(fieldName, "N");
0555:                            }
0556:                        }
0557:                    }
0558:                } catch (DBException ex) {
0559:                    log.error("Error checking boolean fields", ex);
0560:                }
0561:
0562:                //
0563:                //Now iterate through all the parameters to find matching parameter
0564:                //patterns and load them into the appropriate DBObject by calling
0565:                //parseSingleInput for each matching paramter.
0566:                //
0567:                for (Iterator i = oneObject.getMetaData().getFieldListArray()
0568:                        .iterator(); i.hasNext();) {
0569:                    String oneFieldName = (String) i.next();
0570:                    String oneParameterValue = request
0571:                            .getParameter(oneFieldName);
0572:
0573:                    if (oneParameterValue != null) {
0574:                        parseSingleInput(request, oneObject, oneFieldName,
0575:                                null, ec);
0576:                    }
0577:                }
0578:
0579:                if (validate) {
0580:                    for (Iterator it = oneObject.getMetaData()
0581:                            .getFieldListArray().iterator(); it.hasNext();) {
0582:                        String fieldName = (String) it.next();
0583:
0584:                        try {
0585:                            String fieldValue = oneObject.getField(fieldName);
0586:
0587:                            if (((fieldValue == null) || (fieldValue.length() == 0))
0588:                                    && !oneObject.getFieldMetaData(fieldName)
0589:                                            .isReadOnly()) {
0590:                                oneObject.checkField(fieldName, fieldValue);
0591:                            }
0592:                        } catch (DBException dbe) {
0593:                            ec.addError(dbe.getMessage());
0594:                        }
0595:                    }
0596:                }
0597:
0598:                //
0599:                //Ok, we successfully parsed things without bombing, now save that parsed
0600:                //entity onto the Request so that we can grab it for rendering
0601:                // NOTE: this is the REQUEST SCOPE, not session scope
0602:                //
0603:                Map dbobjList = (Map) request.getSession().getAttribute(
0604:                        SESSION_KEY);
0605:
0606:                if (dbobjList == null) {
0607:                    dbobjList = new HashMap(1);
0608:                }
0609:
0610:                dbobjList.put(oneObject.getClass().getName(), oneObject);
0611:
0612:                request.getSession().setAttribute(SESSION_KEY, dbobjList);
0613:
0614:                return oneObject;
0615:            }
0616:
0617:            /**
0618:             * Convienence method if you only expect one DBObject to be returned from a
0619:             * particular form, and unlike the ParseBlock, there is no DBOBject name
0620:             * prefix attached to the parameter names.  This is similar to the
0621:             * ControllerRequest validateDBObject functionality, but we're
0622:             * consolodating things here.
0623:             *
0624:             * @param request   The ControllerRequest object handed down by the framework
0625:             * @param oneObject A DBObject to fill in.
0626:             * @param ec        An instantiated ErrorCollection that is filled in with any
0627:             *                  error
0628:             * @return a parsed DBObject
0629:             * @throws ControllerException if there's an error parsing the block or
0630:             *                             communicating with the underlying DBObject
0631:             */
0632:            public DataObject parseDBObject(ControllerRequest request,
0633:                    DataObject oneObject, ErrorCollection ec)
0634:                    throws ControllerException {
0635:                return parseDBObject(request, oneObject, ec, true);
0636:            }
0637:
0638:            /**
0639:             * Takes the Controller Request and appropriately parses a string for a
0640:             * particular field.  If the field is a Date, then it parses it as such,
0641:             * if it is money, then it perses it as such.  Etc.
0642:             * <h4>
0643:             * <p/>
0644:             * <p/>
0645:             * As of Expresso 5.1, the system properly parses multi-part request data.
0646:             * If a parameter is a file parameter, then it sets the following field
0647:             * attributes that can be retrieved by:<br/
0648:             * ><code> DataObject.getFieldData(fieldName).getAttribute(attribName);
0649:             * </code>
0650:             * </p>
0651:             * <p/>
0652:             * <p/>
0653:             * <p/>
0654:             * <ul>
0655:             * <li>
0656:             * Attribute: fileName - The locally accessible file name to be used for
0657:             * most likely saving to the database.  Use <code>new
0658:             * File(fileName)</code> to actually access the uploaded file
0659:             * </li>
0660:             * <li>
0661:             * Attribute: origFileName - The original file name (without path) that was
0662:             * uploaded to the server through the web browser.  This will be different
0663:             * from the attribute fileName since Expresso will rename the local file
0664:             * name to prevent naming collisions
0665:             * </li>
0666:             * <li>
0667:             * Attribute: MimeType - The system will make a guess as to the mime type
0668:             * of the file that was uploaded based upon the file name.
0669:             * </li>
0670:             * </ul>
0671:             * </p>
0672:             * <p/>
0673:             * <p/>
0674:             * Finally, if the target dbobj is of type MediaDBObject the fields:
0675:             * 'fieldName + &quot;_mimeType&quot;' and 'fieldName +
0676:             * &quot;_fileName&quot;' will be set with the corresponding mimeType and
0677:             * origFileName values
0678:             * </p>
0679:             *
0680:             * @param request       The ControllerRequest object
0681:             * @param dbobj         The DBObject for which we're going to put the field to
0682:             * @param fieldName     The name of the field to parse
0683:             * @param parameterName The name of the http paramter to parse  May be null
0684:             *                      in which case, the funciton will by default use the fieldName as
0685:             *                      the parameter name.
0686:             * @param ec            An instantiated ErrorCollection object that will be filled
0687:             *                      with any parsing errors that may be encountered.
0688:             * @return java.lang.String for the value.
0689:             * @throws ControllerException upon parsing error
0690:             * @since Expresso 5.0; Multipart Request Handling since Expresso 5.1
0691:             */
0692:            public String parseSingleInput(ControllerRequest request,
0693:                    DataObject dbobj, String fieldName, String parameterName,
0694:                    ErrorCollection ec) throws ControllerException {
0695:                DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
0696:                Locale currentLocale = request.getLocale();
0697:
0698:                if (parameterName == null) {
0699:                    parameterName = fieldName;
0700:                }
0701:
0702:                String oneParameter = request.getParameter(parameterName);
0703:
0704:                if (oneParameter == null) {
0705:                    ec.addError("Missing field: " + fieldName);
0706:
0707:                    return null;
0708:                }
0709:
0710:                //
0711:                //Check for multipart request handling.
0712:                //
0713:                if (request.isFileParameter(fieldName)) {
0714:                    try {
0715:                        String fileName = request.getFileName(fieldName);
0716:                        String param = request.getParameter(fieldName);
0717:                        dbobj.getDataField(fieldName).setAttribute("fileName",
0718:                                fileName);
0719:
0720:                        String origFileName = null;
0721:                        String mimeType = null;
0722:
0723:                        if (param != null) {
0724:                            origFileName = getOriginalFileName(param);
0725:                            dbobj.getDataField(fieldName).setAttribute(
0726:                                    "origFileName", origFileName);
0727:                            mimeType = MimeTypes.getMimeType(fileName,
0728:                                    request.getDataContext()).getField(
0729:                                    MimeTypes.FLD_MIMENUMBER);
0730:
0731:                            //                    mimeType = MimeTypes.getFileMap(request.getDataContext())
0732:                            //                            .getContentType(origFileName);
0733:                            dbobj.getDataField(fieldName).setAttribute(
0734:                                    "mimeType", mimeType);
0735:                        }
0736:
0737:                        if (dbobj instanceof  MediaDBObject) {
0738:                            MediaDBObject mediaObject = (MediaDBObject) dbobj;
0739:                            mediaObject.setField(fieldName + "_mimeType",
0740:                                    mimeType);
0741:                            mediaObject.setField(fieldName + "_fileName",
0742:                                    origFileName);
0743:                        }
0744:
0745:                        return param;
0746:                    } catch (DBException ex) {
0747:                        log.warn("Validation error for field:", ex);
0748:                        ec.addError(ex.getMessage());
0749:
0750:                        return null;
0751:                    }
0752:                }
0753:
0754:                if (!metaData.isVirtual() && !metaData.isBinaryObjectType()) {
0755:                    try {
0756:                        //
0757:                        //If we have date, or time let's try to parse it.
0758:                        //
0759:                        if (metaData.isDateOnlyType()) {
0760:                            try {
0761:                                DateFormat df = DateFormat.getDateInstance(
0762:                                        DateFormat.SHORT, currentLocale);
0763:                                df.setLenient(true);
0764:
0765:                                Date dt = df.parse(oneParameter);
0766:                                dbobj.set(fieldName, DateTime.getDateForDB(dt,
0767:                                        request.getDataContext()));
0768:
0769:                                //                        dbobj.setField(fieldName, DateTime.getDateForDB(dt,request.getDBName()));
0770:                            } catch (ParseException ex) {
0771:                                //We try to set the field anyway, since all those > 1988-10-1
0772:                                //type of queries need to be allowed through.
0773:                                dbobj.set(fieldName, oneParameter);
0774:
0775:                                //                        dbobj.setField(fieldName, oneParameter);
0776:                            }
0777:                        } else if (metaData.isTimeType()) {
0778:                            try {
0779:                                DateFormat df = DateFormat.getTimeInstance(
0780:                                        DateFormat.SHORT, currentLocale);
0781:                                df.setLenient(true);
0782:
0783:                                Date dt = df.parse(oneParameter);
0784:                                dbobj.set(fieldName, DateTime.getTimeForDB(dt,
0785:                                        request.getDataContext()));
0786:
0787:                                //                        dbobj.setField(fieldName, DateTime.getTimeForDB(dt,request.getDBName()));
0788:                            } catch (ParseException ex) {
0789:                                dbobj.set(fieldName, oneParameter);
0790:
0791:                                //                        dbobj.setField(fieldName, oneParameter);
0792:                            }
0793:                        } else if (metaData.isDateTimeType()) {
0794:                            try {
0795:                                DateFormat df = DateFormat.getDateTimeInstance(
0796:                                        DateFormat.SHORT, DateFormat.SHORT,
0797:                                        currentLocale);
0798:                                df.setLenient(true);
0799:
0800:                                Date dt = df.parse(oneParameter);
0801:                                dbobj.set(fieldName, DateTime.getDateTimeForDB(
0802:                                        dt, request.getDataContext()));
0803:
0804:                                //                        dbobj.setField(fieldName, DateTime.getDateTimeForDB(dt,request.getDBName()));
0805:                            } catch (ParseException ex) {
0806:                                dbobj.set(fieldName, oneParameter);
0807:                            }
0808:                        } else if (metaData.isNumericType()) {
0809:                            /*
0810:                            Numeric fields are a bit special, because DBObject.getFieldInt()
0811:                            will return zero if the field is null, and will throw an exception
0812:                            for "". getFieldInt() javadoc tells people to check
0813:                            DBObject.isFieldNull() for a numeric field to know whether the zero
0814:                            is real or not.
0815:
0816:                            DBObject.isFieldNull() will NOT return true after the empty string
0817:                            is put into a field.
0818:
0819:                             */
0820:
0821:                            if (oneParameter != null
0822:                                    && oneParameter.length() == 0) {
0823:                                dbobj.set(fieldName, null);
0824:                            } else {
0825:                                dbobj.set(fieldName, oneParameter);
0826:                            }
0827:
0828:                        } else {
0829:                            //                    String lookupObject = metaData.getLookupObject();
0830:                            //                    String lookupField = metaData.getLookupField();
0831:
0832:                            //                    if (lookupObject != null && lookupObject.length() > 0 && isMappable(lookupObject)) {
0833:                            //                        oneParameter = parseLookupValue(ec,dbobj,oneParameter,fieldName);
0834:                            //                    }
0835:                            dbobj.set(fieldName, oneParameter);
0836:                        }
0837:                    } catch (DBException de) {
0838:                        if (log.isInfoEnabled()) {
0839:                            log.info("Validation error for field:", de);
0840:                        }
0841:
0842:                        ec.addError(de.getMessage());
0843:                    }
0844:                }
0845:
0846:                return null;
0847:            }
0848:
0849:            /**
0850:             * Renders a DBOBject Field as either an Input or an Output.  For example,
0851:             * if we're talking updating, then all key fields are outputs and not
0852:             * inputs. This function auto-detects whether we are dealing with a add()
0853:             * or update() situation by checking the DBObject's status.  If it's NEW,
0854:             * then we treat this as an add form, if it is
0855:             *
0856:             * @param response    The ControllerResponse object
0857:             * @param dbobj       The parameter to render
0858:             * @param fieldName   The name of the field to render
0859:             * @param cachedValue Any cached form value to put in the field.
0860:             * @param readOnly    - If set to true, then this is automatically a read-only
0861:             *                    field... if set to false, this function might still render the
0862:             *                    field as read-only if, for example, it's a key field.
0863:             * @return a created Input
0864:             * @throws ControllerException if there's an error creating the Input Field
0865:             */
0866:            public Input renderDBObjectField(ControllerResponse response,
0867:                    DataObject dbobj, String fieldName, String cachedValue,
0868:                    boolean readOnly) throws ControllerException {
0869:                DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
0870:                DataObjectMetaData objMetadata = dbobj.getMetaData();
0871:
0872:                if (log.isDebugEnabled()) {
0873:                    FastStringBuffer logMsg = FastStringBuffer.getInstance();
0874:                    logMsg
0875:                            .append("entering renderDBObjectField.  Parameters: \n\tdbobj=");
0876:                    logMsg.append(dbobj.getClass().getName());
0877:                    logMsg.append("\n\tfieldName=");
0878:                    logMsg.append(fieldName);
0879:                    logMsg.append("\n\tdefaultValue=");
0880:                    logMsg.append(cachedValue);
0881:                    logMsg.append("\n\treadOnly=");
0882:                    logMsg.append(readOnly);
0883:                    log.debug(logMsg.toString());
0884:                    logMsg.release();
0885:                }
0886:
0887:                try {
0888:                    StringUtil.assertNotBlank(fieldName,
0889:                            "Field Name must not be null");
0890:
0891:                    if (dbobj == null) {
0892:                        throw new DBException("Database object must be "
0893:                                + "initialized before calling autoField");
0894:                    }
0895:
0896:                    if (metaData.isVirtual()) {
0897:                        return null;
0898:                    }
0899:
0900:                    String oneFieldValue = dbobj.getField(fieldName);
0901:
0902:                    ///            String oneFieldSize = Integer.toString(metaData.getLengthInt());
0903:                    if (oneFieldValue == null) {
0904:                        oneFieldValue = ("");
0905:                    }
0906:
0907:                    //            if (oneFieldSize.equals("0")) {
0908:                    //                oneFieldSize = ("30");
0909:                    //            }
0910:                    int fieldSize = metaData.getLengthInt();
0911:                    fieldSize = fieldSize + 2;
0912:
0913:                    /* Make the longest display field size 60 characters */
0914:                    int displayFieldSize = fieldSize;
0915:
0916:                    //
0917:                    //Numeric fields are too small since integers which may, in text
0918:                    //take at least 6 characters are listed as only 2 byte in size via
0919:                    //the database information
0920:                    //
0921:                    if (displayFieldSize > 60) {
0922:                        displayFieldSize = 60;
0923:                    }
0924:
0925:                    //Since most numeric values of some sort have a specific
0926:                    //size we want the field.  Then we check against the various
0927:                    //data types and set the field appropriately.
0928:                    if (displayFieldSize < 10) {
0929:                        if (metaData.isNumericType()) {
0930:                            displayFieldSize = 15;
0931:                        } else if (metaData.isDateTimeType()) {
0932:                            displayFieldSize = 30;
0933:                        } else if (metaData.isDateOnlyType()) {
0934:                            displayFieldSize = 15;
0935:                        } else if (metaData.isTimeType()) {
0936:                            displayFieldSize = 15;
0937:                        } else {
0938:                            displayFieldSize = 10;
0939:                        }
0940:                    }
0941:
0942:                    Input oneField = new Input(fieldName);
0943:                    oneField.setDisplayLength(displayFieldSize);
0944:
0945:                    if (fieldSize > displayFieldSize) {
0946:                        oneField.setMaxLength(fieldSize);
0947:                    } else {
0948:                        oneField.setMaxLength(displayFieldSize + 2);
0949:                    }
0950:
0951:                    if ((cachedValue != null) && (cachedValue.length() > 0)) {
0952:                        oneFieldValue = cachedValue;
0953:                    }
0954:
0955:                    //            String lookupObject = metaData.getLookupObject();
0956:                    //            String lookupField = metaData.getLookupField();
0957:
0958:                    //
0959:                    //If we have a lookup class and field, then we change the field value
0960:                    //to that returned by renderLookupValue
0961:                    //
0962:                    //            if (lookupObject != null && lookupObject.length() > 0 && isMappable(lookupObject)
0963:                    //                && cachedValue == null) {
0964:                    //                oneFieldValue = renderLookupValue(dbobj,oneFieldValue
0965:                    //                        ,fieldName,oneField);
0966:                    //            } else {
0967:                    oneField.setAttribute(Input.ATTRIBUTE_TYPE, metaData
0968:                            .getTypeString());
0969:
0970:                    //            }
0971:                    Iterator dbAttribs = metaData.getAttributesIterator();
0972:
0973:                    if (dbAttribs != null) {
0974:                        String oneAttrib = null;
0975:                        Object oneAttribValue = null;
0976:
0977:                        while (dbAttribs.hasNext()) {
0978:                            oneAttrib = (String) dbAttribs.next();
0979:                            oneAttribValue = metaData.getAttribute(oneAttrib);
0980:
0981:                            if (oneAttribValue != null) {
0982:                                oneField.setAttribute(oneAttrib, oneAttribValue
0983:                                        .toString());
0984:                            }
0985:                        }
0986:                    }
0987:
0988:                    // Get the localized description, including any date pattern
0989:                    {
0990:                        String description;
0991:
0992:                        // We could also convert request to HttpServletRequest and get locale from user pref.
0993:                        // I do not think it would be a problem, but I'm not sure this is not used in a
0994:                        // non-web environment.
0995:                        Locale locale = response.getLocale();
0996:
0997:                        //
0998:                        // Get the non-localized value to do our own message bundle lookup in order to cascade
0999:                        // the message bundle from the schema bundle if specified.  Then lookup in the expresso
1000:                        // bundle.  If this is not what is wanted, then a simple call could sufice as follows:
1001:                        //
1002:                        //  description = objMetadata.getDescription(locale, fieldName);
1003:                        //
1004:                        // --- David Lloyd
1005:                        //
1006:                        Object[] args = {};
1007:                        String stringCode = objMetadata
1008:                                .getDescription(fieldName);
1009:
1010:                        try {
1011:                            description = com.jcorporate.expresso.core.i18n.Messages
1012:                                    .getString(objMetadata.getSchema(), locale,
1013:                                            stringCode, args);
1014:                        } catch (IllegalArgumentException iae) {
1015:                            if (log.isDebugEnabled()) {
1016:                                log.debug("DefaultAutoElement: Key ["
1017:                                        + stringCode + "] not found in "
1018:                                        + objMetadata.getSchema());
1019:                            }
1020:
1021:                            description = null;
1022:
1023:                            if (!objMetadata.getSchema()
1024:                                    .equals(EXPRESSO_SCHEMA)) {
1025:                                try {
1026:                                    description = com.jcorporate.expresso.core.i18n.Messages
1027:                                            .getString(EXPRESSO_SCHEMA, locale,
1028:                                                    stringCode, args);
1029:                                } catch (IllegalArgumentException e) {
1030:                                    description = null;
1031:                                }
1032:                            }
1033:                        }
1034:
1035:                        if ((description == null)
1036:                                || (description.length() == 0)) {
1037:                            description = stringCode;
1038:                        }
1039:
1040:                        //
1041:                        // END OF description lookup
1042:                        //
1043:                        if (metaData.isDateType() && !metaData.isReadOnly()) {
1044:                            // try to show 'A Date (MM/dd/yyyy)'
1045:                            String pattern = DateTime.getDateFormatString(
1046:                                    metaData.isDateOnlyType(), locale);
1047:
1048:                            if (pattern.length() > 0) {
1049:                                pattern = " (" + pattern + ")";
1050:                            }
1051:
1052:                            oneField.setLabel(description + pattern);
1053:                        } else {
1054:                            oneField.setLabel(description);
1055:                        }
1056:                    }
1057:
1058:                    String dbobjStatus = dbobj.getStatus();
1059:
1060:                    /* If the field is explicitly set to read only, then only offer */
1061:                    /* input to it in search mode */
1062:                    /* Except virtual fields, which never get input... */
1063:                    /* And finally also when it isn't a new record and the field name */
1064:                    /* is a key field */
1065:                    if (metaData.isReadOnly()) {
1066:                        readOnly = true;
1067:                    } else if (metaData.isVirtual()) {
1068:                        readOnly = true;
1069:                    } else if (!dbobjStatus.equals(DBObject.STATUS_NEW)) {
1070:                        if (dbobj.getMetaData().getKeyFieldListArray()
1071:                                .contains(fieldName)) {
1072:                            //It's a key field, it should not be changeable.
1073:                            readOnly = true;
1074:                        }
1075:                    }
1076:
1077:                    /**
1078:                     * Don't display read only fields for a new object since they only
1079:                     * serve to add confusion and there is no value assigned to them
1080:                     * yet.
1081:                     */
1082:                    if (dbobjStatus.equals(DBObject.STATUS_NEW)) {
1083:                        if (metaData.isReadOnly()) {
1084:                            return null;
1085:                        }
1086:                    }
1087:
1088:                    String displayAttrib = (String) metaData
1089:                            .getAttribute("display");
1090:
1091:                    if (displayAttrib != null) {
1092:                        oneField.setAttribute("display", displayAttrib);
1093:                    }
1094:
1095:                    //Set the field value to the default value if a default value is
1096:                    //supplied and an existing field value does not.
1097:                    if ((cachedValue != null) && (cachedValue.length() > 0)) {
1098:                        if ((oneFieldValue == null)
1099:                                || (oneFieldValue.length() == 0)) {
1100:                            oneField.setDefaultValue(cachedValue);
1101:                        }
1102:                    }
1103:
1104:                    if (readOnly) {
1105:                        oneField = renderReadOnlyInput(response, oneField,
1106:                                dbobj, fieldName, oneFieldValue);
1107:                    } else { /* NOT readonly */
1108:
1109:                        String oneFieldSize = Integer
1110:                                .toString(displayFieldSize);
1111:                        oneField = renderReadWriteInput(response, oneField,
1112:                                dbobj, fieldName, oneFieldValue, oneFieldSize);
1113:                    }
1114:                    /* else not read-only */
1115:
1116:                    cachedValue = oneField.getDefaultValue();
1117:
1118:                    if (!StringUtil.notNull(cachedValue).equals("")) {
1119:                        oneField.setDefaultValue(cachedValue);
1120:
1121:                        if (log.isDebugEnabled()) {
1122:                            log.debug("Cached value for '" + fieldName
1123:                                    + "' was '" + cachedValue + "'");
1124:                        }
1125:                    } else {
1126:                        /* If no cached value, see if the db object has a default */
1127:                        String defValue = dbobj.getMetaData().getDefaultValue(
1128:                                fieldName);
1129:
1130:                        if (defValue != null) {
1131:                            oneField.setDefaultValue(defValue);
1132:                        }
1133:                    }
1134:
1135:                    return oneField;
1136:                } catch (DBException dbe) {
1137:                    throw new ControllerException("Error rendering input.", dbe);
1138:                }
1139:            }
1140:
1141:            /**
1142:             * Same as display value but for Date/DateTime types.  Formats things
1143:             * appropriate to the user's locale
1144:             *
1145:             * @param metaData the Data Field's metadata
1146:             * @param dt       The date value to format
1147:             * @param l        the User's Locale gathered from the ControllerResponse object
1148:             * @return a properly formatted date
1149:             */
1150:            protected String displayValue(DataFieldMetaData metaData, Date dt,
1151:                    Locale l) {
1152:                if (dt == null) {
1153:                    return "";
1154:                }
1155:
1156:                if (metaData.isDateOnlyType()) {
1157:                    DateFormat df = DateFormat.getDateInstance(
1158:                            DateFormat.SHORT, l);
1159:                    df = modifyDateFormat(df);
1160:
1161:                    return df.format(dt);
1162:                } else if (metaData.isTimeType()) {
1163:                    DateFormat df = DateFormat.getTimeInstance(
1164:                            DateFormat.SHORT, l);
1165:                    df = modifyDateFormat(df);
1166:
1167:                    return df.format(dt);
1168:                } else {
1169:                    DateFormat df = DateFormat.getDateTimeInstance(
1170:                            DateFormat.SHORT, DateFormat.SHORT, l);
1171:                    df = modifyDateFormat(df);
1172:
1173:                    return df.format(dt);
1174:                }
1175:            }
1176:
1177:            /**
1178:             * Format a value for display in the HTML being returned to the client
1179:             *
1180:             * @param metaData   The Field Metadata
1181:             * @param fieldValue The value of the field
1182:             * @param fieldName  the name of the field to render
1183:             * @param l          The Locale to display the value for.
1184:             * @return String The formatted field
1185:             * @throws ControllerException If the field format information could not be
1186:             *                             determined
1187:             */
1188:            protected String displayValue(DataFieldMetaData metaData,
1189:                    String fieldValue, String fieldName, Locale l)
1190:                    throws ControllerException {
1191:                try {
1192:                    if (metaData.getTypeString().equalsIgnoreCase("money")) {
1193:                        if (fieldValue.length() > 0) {
1194:                            return new Format("%-10.2f").form(new Double(
1195:                                    fieldValue).doubleValue());
1196:                        }
1197:                    } else {
1198:                        return fieldValue;
1199:                    }
1200:                } catch (NumberFormatException ne) {
1201:                    throw new ControllerException("Number for field not in a "
1202:                            + "valid numeric format:" + fieldValue + ":"
1203:                            + ne.getMessage());
1204:                }
1205:
1206:                return null;
1207:            }
1208:
1209:            /* displayValue(String, String) */
1210:
1211:            /**
1212:             * Modifies an already instantiated Input to be a finished read only
1213:             * control.
1214:             *
1215:             * @param response      The ControllerResponse object
1216:             * @param oneField      The input to flesh out.
1217:             * @param dbobj         The data source object
1218:             * @param fieldName     The field name in the dbobj to render.
1219:             * @param oneFieldValue The value to add to the input control.
1220:             * @return a read only input
1221:             * @throws DBException         if there's an error communicating with the DBObject
1222:             * @throws ControllerException if there's an error building the Input
1223:             *                             field.
1224:             */
1225:            protected Input renderReadOnlyInput(ControllerResponse response,
1226:                    Input oneField, DataObject dbobj, String fieldName,
1227:                    String oneFieldValue) throws DBException,
1228:                    ControllerException {
1229:                DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
1230:                DataObjectMetaData objMetaData = dbobj.getMetaData();
1231:
1232:                oneField.setAttribute(Input.ATTRIBUTE_READONLY, "Y");
1233:                oneField.setAttribute(Input.ATTRIBUTE_ORIGINAL_VALUE,
1234:                        oneFieldValue);
1235:
1236:                if (metaData.isMultiValued()) {
1237:                    java.util.List values = dbobj.getValidValuesList(fieldName);
1238:
1239:                    if (values == null) {
1240:                        throw new DBException("Valid values for field "
1241:                                + fieldName + " from object "
1242:                                + objMetaData.getName() + " were null");
1243:                    }
1244:
1245:                    String fieldValue = null;
1246:                    ValidValue oneVV = null;
1247:
1248:                    for (Iterator e = values.iterator(); e.hasNext();) {
1249:                        oneVV = (ValidValue) e.next();
1250:
1251:                        if (oneVV.getValue().equals(oneFieldValue)) {
1252:                            fieldValue = oneVV.getDescription();
1253:                        }
1254:                    }
1255:
1256:                    if (fieldValue == null) {
1257:                        oneField.setDefaultValue(oneFieldValue);
1258:                    } else {
1259:                        oneField.setDefaultValue(fieldValue);
1260:                    }
1261:                } else {
1262:                    if (metaData.isDateType()) {
1263:                        if ((oneFieldValue == null)
1264:                                || (oneFieldValue.length() == 0)) {
1265:                            oneField.setDefaultValue(displayValue(metaData,
1266:                                    oneFieldValue, fieldName, response
1267:                                            .getLocale()));
1268:                        } else {
1269:                            oneField.setDefaultValue(displayValue(metaData,
1270:                                    dbobj.getField(fieldName), fieldName,
1271:                                    response.getLocale()));
1272:                        }
1273:                    } else {
1274:                        oneField
1275:                                .setDefaultValue(displayValue(metaData,
1276:                                        oneFieldValue, fieldName, response
1277:                                                .getLocale()));
1278:                    }
1279:                }
1280:
1281:                return oneField;
1282:            }
1283:
1284:            /**
1285:             * Modifies an already instantiated Input to be a finished Input control
1286:             * specifically for a blob field.  If the dbobject is a MediaObject, then
1287:             * it adds the abilities to view the fields and creates an appropriate
1288:             * icon.
1289:             *
1290:             * @param response      The ControllerResponse object
1291:             * @param oneField      The input to flesh out.
1292:             * @param dbobj         The data source object
1293:             * @param fieldName     The field name in the dbobj to render.
1294:             * @param oneFieldValue The value to add to the input control.
1295:             * @param oneFieldSize  The size of the Input control when finished.
1296:             * @throws DBException         if there's an error communicating with the DBObject
1297:             * @throws ControllerException if there's an error building the Input
1298:             *                             field.
1299:             */
1300:            protected void renderReadWriteBlob(ControllerResponse response,
1301:                    Input oneField, DataObject dbobj, String fieldName,
1302:                    String oneFieldValue, String oneFieldSize)
1303:                    throws DBException, ControllerException {
1304:                oneField.setType("file");
1305:                oneField.setDisplayLength(60);
1306:
1307:                if (dbobj instanceof  NestableDataObject) {
1308:                    String tempFieldName = fieldName;
1309:                    fieldName = ((NestableDataObject) dbobj)
1310:                            .getFieldFromNestedName(fieldName);
1311:                    dbobj = ((NestableDataObject) dbobj)
1312:                            .getNestedFromFieldName(tempFieldName);
1313:                }
1314:
1315:                if (dbobj instanceof  MediaDBObject) {
1316:                    MediaDBObject media = (MediaDBObject) dbobj;
1317:                    String mimeNumber = media.getField(fieldName + "_mimeType");
1318:
1319:                    if (mimeNumber == null) {
1320:                        return;
1321:                    }
1322:
1323:                    MimeTypes mt = new MimeTypes(SecuredDBObject.SYSTEM_ACCOUNT);
1324:                    mt.setField(MimeTypes.FLD_MIMENUMBER, mimeNumber);
1325:
1326:                    if (mt.find()) {
1327:                        oneField.setAttribute("IconURL", mt.getIconURL());
1328:                    } else {
1329:                        log.error("Unable to find mime type for mime number: "
1330:                                + mimeNumber);
1331:                    }
1332:
1333:                    //            Transition t = new Transition("view","View"
1334:                    //                    ,com.jcorporate.expresso.services.controller.DBMaint.class,
1335:                    //                    "ViewBlob");
1336:                    //            t.addParam("fieldName", fieldName);
1337:                    //            t.addParam("dbobj", ((Object)dbobj).getClass().getName());
1338:                }
1339:            }
1340:
1341:            /**
1342:             * Modifies an already instantiated Input to be a finished Input control
1343:             *
1344:             * @param response      The ControllerResponse object
1345:             * @param oneField      The input to flesh out.
1346:             * @param dbobj         The data source object
1347:             * @param fieldName     The field name in the dbobj to render.
1348:             * @param oneFieldValue The value to add to the input control.
1349:             * @param oneFieldSize  The size of the Input control when finished.
1350:             * @return a rendered Read/Write Input
1351:             * @throws DBException         if there's an error communicating with the DBObject
1352:             * @throws ControllerException if there's an error building the Input
1353:             *                             field.
1354:             */
1355:            protected Input renderReadWriteInput(ControllerResponse response,
1356:                    Input oneField, DataObject dbobj, String fieldName,
1357:                    String oneFieldValue, String oneFieldSize)
1358:                    throws DBException, ControllerException {
1359:                if (log.isDebugEnabled()) {
1360:                    log
1361:                            .debug("Entering DefaultAutoElement.renderReadWriteInput");
1362:                }
1363:
1364:                DataFieldMetaData metaData = dbobj.getFieldMetaData(fieldName);
1365:                DataObjectMetaData dbobjMetaData = dbobj.getMetaData();
1366:
1367:                DataField df = dbobj.getDataField(fieldName);
1368:
1369:                //
1370:                //Set the appropriate display style.
1371:                //
1372:                if (df.getAttribute(DBObject.ATTRIBUTE_ERROR) != null) {
1373:                    oneField.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
1374:                            getErrorStyle());
1375:                } else if (!metaData.allowsNull()) {
1376:                    oneField.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
1377:                            getRequiredStyle());
1378:                } else {
1379:                    oneField.setAttribute(Input.ATTRIBUTE_CSS_STYLE,
1380:                            getNormalStyle());
1381:                }
1382:
1383:                //
1384:                //If it's a required field, decorate the label with a '*' or whatever
1385:                //else is defined by the class.
1386:                //
1387:                if (!metaData.allowsNull()) {
1388:                    oneField.setLabel(oneField.getLabel()
1389:                            + getRequiredDecorator());
1390:                }
1391:
1392:                /* if the field is multi-valued, present a drop-down list */
1393:                /* instead of just a text field */
1394:                if (metaData.isMultiValued()) {
1395:                    oneField.setAttribute(Input.ATTRIBUTE_MULTIVALUED, "Y");
1396:                    oneField.setAttribute(Input.ATTRIBUTE_DROPDOWN, "Y");
1397:                    oneField.setType(Input.ATTRIBUTE_DROPDOWN);
1398:
1399:                    java.util.List values = dbobj.getValidValuesList(fieldName);
1400:
1401:                    //Hashtable values = dbobj.getValues(fieldName);
1402:                    if (values == null) {
1403:                        throw new DBException("Valid values for field "
1404:                                + fieldName + " from object "
1405:                                + dbobjMetaData.getName() + " were null");
1406:                    }
1407:
1408:                    oneField.setValidValues(new Vector(values));
1409:                    oneField.setDefaultValue(oneFieldValue);
1410:                } else {
1411:                    //
1412:                    //If we have a blob, then it is a file to upload.
1413:                    //
1414:                    if (metaData.isBinaryObjectType()) {
1415:                        renderReadWriteBlob(response, oneField, dbobj,
1416:                                fieldName, oneFieldValue, oneFieldSize);
1417:                    }
1418:
1419:                    if (metaData.isDateType()) {
1420:                        oneField.setDisplayLength(10);
1421:
1422:                        //                oneField.setMaxLength(10 + 2);
1423:                        if ((oneFieldValue == null)
1424:                                || (oneFieldValue.length() == 0)) {
1425:                            oneField.setDefaultValue(displayValue(metaData,
1426:                                    oneFieldValue, fieldName, response
1427:                                            .getLocale()));
1428:                        } else {
1429:                            oneField.setDefaultValue(displayValue(metaData,
1430:                                    dbobj.getDataField(fieldName).asDate(),
1431:                                    response.getLocale()));
1432:                        }
1433:                    } else {
1434:                        if (metaData.isCharacterLongObjectType()) {
1435:                            oneField.setDisplayLength(80);
1436:                            oneField.setLines(4);
1437:                            oneField.setMaxLength(4096);
1438:                            oneField.setType("text");
1439:                        } else {
1440:                            //                    oneField.setMaxLength(new Integer(oneFieldSize).intValue());
1441:                        }
1442:
1443:                        oneField
1444:                                .setDefaultValue(displayValue(metaData,
1445:                                        oneFieldValue, fieldName, response
1446:                                                .getLocale()));
1447:                    }
1448:                }
1449:
1450:                if (log.isDebugEnabled()) {
1451:                    if (oneField != null) {
1452:                        log
1453:                                .debug("Leaving DefaultAutoElement.renderReadWriteInput "
1454:                                        + oneField.toString());
1455:                    } else {
1456:                        log
1457:                                .debug("Leaving DefaultAutoElement.renderReadWriteInput oneField=null");
1458:                    }
1459:                }
1460:
1461:                return oneField;
1462:            }
1463:
1464:            /**
1465:             * For lookup objects that also define a lookup object AND lookup field,
1466:             * then attempt to match the field key with the lookup field value
1467:             *
1468:             * @param className the DataObject to use as the metadata source
1469:             *
1470:             * @return String value of the lookup value.
1471:             */
1472:
1473:            //    protected String renderLookupValue(DataObject object, String curValue,
1474:            //                                     String fieldName,Input i)  throws DataException {
1475:            //        if (curValue == null || curValue.length() == 0) {
1476:            //            return "";
1477:            //        }
1478:            //
1479:            //        DataFieldMetaData fieldMetadata = object.getFieldMetaData(fieldName);
1480:            //        String lookupObject = fieldMetadata.getLookupObject();
1481:            //
1482:            //        Mappable mapObject = constructMappableObject(object,fieldName);
1483:            //        i.setDescription(mapObject.getMappedDescription());
1484:            //        return mapObject.getMappedValue(curValue);
1485:            //    }
1486:            /**
1487:             * Parses the lookup value.  Adds to the ErrorCollection if referential
1488:             * integrity cannot be established
1489:             *
1490:             * @param className the error collection to add errors to if any occur.
1491:             *
1492:             * @return the lookup value
1493:             */
1494:
1495:            //    private String parseLookupValue(ErrorCollection ec,
1496:            //                                    DataObject object, String curValue,
1497:            //                                    String fieldName) throws DataException {
1498:            //        if (curValue== null || curValue.length() == 0) {
1499:            //            return null;
1500:            //        }
1501:            //
1502:            //        DataFieldMetaData fieldMetadata = object.getFieldMetaData(fieldName);
1503:            //        String lookupObject = fieldMetadata.getLookupObject();
1504:            //
1505:            //        Mappable mapObject = constructMappableObject(object,fieldName);
1506:            //        return mapObject.getKeyValue(curValue);
1507:            //
1508:            //    }
1509:            //
1510:            /**
1511:             * Checks to see if a lookup object is mappable.
1512:             *
1513:             * @param className the class name to test
1514:             *
1515:             * @return true if the class implements mappable, false otherwise.
1516:             */
1517:            //    private boolean isMappable(String className)
1518:            //    {
1519:            //        try {
1520:            //            Object o = ClassLocator.loadClass(className).newInstance();
1521:            //
1522:            //            if (o instanceof Mappable) {
1523:            //                return true;
1524:            //            } else {
1525:            //                return false;
1526:            //            }
1527:            //        } catch (InstantiationException ex) {
1528:            //            log.error("Error instantiating object " + className, ex);
1529:            //
1530:            //            return false;
1531:            //        } catch (IllegalAccessException ex) {
1532:            //            log.error("Error instantiating object " + className, ex);
1533:            //
1534:            //            return false;
1535:            //        } catch (ClassNotFoundException ex) {
1536:            //            log.error("Error instantiating object " + className, ex);
1537:            //
1538:            //            return false;
1539:            //        }
1540:            //    }
1541:            /**
1542:             * Given a file pathname, tell us what the name without the path is.
1543:             *
1544:             * @param fileNameParam The file name of the file that was uploaded ot the
1545:             *                      server.
1546:             * @return a java.lang.String that contains the file name without any path
1547:             *         associated with it.
1548:             */
1549:            private String getOriginalFileName(String fileNameParam) {
1550:                if (fileNameParam == null) {
1551:                    return null;
1552:                }
1553:
1554:                int lastSlash = fileNameParam.lastIndexOf("\\");
1555:
1556:                if (lastSlash < 0) {
1557:                    lastSlash = fileNameParam.lastIndexOf("/");
1558:
1559:                    if (lastSlash < 0) {
1560:                        return fileNameParam;
1561:                    }
1562:                }
1563:
1564:                return fileNameParam.substring(lastSlash + 1);
1565:            }
1566:
1567:            /**
1568:             * Constructs an object to perform the lookups based upon the lookup
1569:             * object, and lookup definition names.
1570:             *
1571:             * @param sourceObject the object where we get the metadata, and source
1572:             *        data context
1573:             * @param fieldName the name of the field to get the lookup object for
1574:             *
1575:             * @return an instantiated DataObject.
1576:             *
1577:             * @throws IllegalArgumentException
1578:             */
1579:            //    private DataObject constructLookupObject(DataObject sourceObject,
1580:            //        String fieldName) throws DataException
1581:            //    {
1582:            //        DataFieldMetaData fieldMetadata = sourceObject.getFieldMetaData(fieldName);
1583:            //        String lookupObject = fieldMetadata.getLookupObject();
1584:            //        String definitionName = fieldMetadata.getLookupDefinition();
1585:            //
1586:            //        if ((lookupObject == null) || (lookupObject.length() == 0)) {
1587:            //            throw new IllegalArgumentException(
1588:            //                "Was asked to construct lookup object that didn't exist for field: " +
1589:            //                fieldName);
1590:            //        }
1591:            //
1592:            //        DataObject returnValue = null;
1593:            //        Class returnClass = null;
1594:            //
1595:            //        try {
1596:            //            returnClass = ClassLocator.loadClass(lookupObject);
1597:            //        } catch (ClassNotFoundException ex) {
1598:            //            log.error("Class Not Found Exception", ex);
1599:            //            throw new IllegalArgumentException("Error finding lookup object: " +
1600:            //                lookupObject);
1601:            //        }
1602:            //
1603:            //        returnValue = com.jcorporate.expresso.core.dataobjects.DataObjectFactory.createDataObject(returnClass,
1604:            //                sourceObject.getDataContext(), definitionName,
1605:            //                Securable.SYSTEM_ACCOUNT);
1606:            //
1607:            //        try {
1608:            //            returnValue.clear();
1609:            //        } catch (DBException ex) {
1610:            //            throw new DataException("Error clearing new data object");
1611:            //        }
1612:            //
1613:            //        return returnValue;
1614:            //    }
1615:            /**
1616:             * Constructs a properly instantiated mappable object
1617:             *
1618:             * @param sourceObject the dataobject where we get the lookup names, etc
1619:             * @param fieldName the field name to get the lookup for
1620:             *
1621:             * @return a properly constructed Mappable object
1622:             *
1623:             * @throws IllegalArgumentException
1624:             */
1625:            //    private Mappable constructMappableObject(DataObject sourceObject,
1626:            //        String fieldName) throws DataException
1627:            //    {
1628:            //        DataFieldMetaData fieldMetadata = sourceObject.getFieldMetaData(fieldName);
1629:            //        String lookupObject = fieldMetadata.getLookupObject();
1630:            //        String definitionName = fieldMetadata.getLookupDefinition();
1631:            //
1632:            //        if ((lookupObject == null) || (lookupObject.length() == 0)) {
1633:            //            throw new IllegalArgumentException(
1634:            //                "Was asked to construct lookup object that didn't exist for field: " +
1635:            //                fieldName);
1636:            //        }
1637:            //
1638:            //        Object returnValue = null;
1639:            //        Class returnClass = null;
1640:            //
1641:            //        try {
1642:            //            returnClass = ClassLocator.loadClass(lookupObject);
1643:            //        } catch (ClassNotFoundException ex) {
1644:            //            log.error("Class Not Found Exception", ex);
1645:            //            throw new IllegalArgumentException("Error finding lookup object: " +
1646:            //                lookupObject);
1647:            //        }
1648:            //
1649:            //        returnValue = com.jcorporate.expresso.core.dataobjects.DataObjectFactory.createObject(returnClass,
1650:            //                sourceObject.getDataContext(), definitionName,
1651:            //                Securable.SYSTEM_ACCOUNT);
1652:            //
1653:            //        if (returnValue instanceof Mappable) {
1654:            //            return (Mappable) returnValue;
1655:            //        } else {
1656:            //            return null;
1657:            //        }
1658:            //    }
1659:            /**
1660:             * Gleaned from @link http://www.jguru.com/faq/view.jsp?EID=429821 to
1661:             * make the SimpleDateFormat give us 4 year dates instead.
1662:             *
1663:             * @param df the DateFormat class
1664:             * @return a proper DateFormat class to modify
1665:             */
1666:            private DateFormat modifyDateFormat(DateFormat df) {
1667:                SimpleDateFormat sdf = null;
1668:
1669:                try {
1670:                    sdf = (SimpleDateFormat) df;
1671:                } catch (ClassCastException cce) {
1672:                    return df;
1673:                }
1674:
1675:                String sTemp = sdf.toPattern();
1676:                int iLen = sTemp.length();
1677:                int i = sTemp.lastIndexOf('y') + 1;
1678:                sTemp = sTemp.substring(0, i) + "yy"
1679:                        + ((i < iLen) ? sTemp.substring(i, iLen) : "");
1680:                sdf.applyPattern(sTemp);
1681:
1682:                return sdf;
1683:            }
1684:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.