Source Code Cross Referenced for FieldUtils.java in  » ERP-CRM-Financial » Kuali-Financial-System » org » kuali » core » util » 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 » ERP CRM Financial » Kuali Financial System » org.kuali.core.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2005-2007 The Kuali Foundation.
0003:         * 
0004:         * Licensed under the Educational Community License, Version 1.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         * 
0008:         * http://www.opensource.org/licenses/ecl1.php
0009:         * 
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        package org.kuali.core.util;
0017:
0018:        import java.lang.reflect.InvocationTargetException;
0019:        import java.security.GeneralSecurityException;
0020:        import java.util.ArrayList;
0021:        import java.util.HashMap;
0022:        import java.util.Iterator;
0023:        import java.util.List;
0024:        import java.util.Map;
0025:
0026:        import org.apache.commons.beanutils.PropertyUtils;
0027:        import org.apache.commons.lang.StringUtils;
0028:        import org.kuali.RiceConstants;
0029:        import org.kuali.core.authorization.FieldAuthorization;
0030:        import org.kuali.core.bo.BusinessObject;
0031:        import org.kuali.core.datadictionary.MaintainableCollectionDefinition;
0032:        import org.kuali.core.datadictionary.control.ApcSelectControlDefinition;
0033:        import org.kuali.core.datadictionary.control.ControlDefinition;
0034:        import org.kuali.core.datadictionary.control.CurrencyControlDefinition;
0035:        import org.kuali.core.datadictionary.control.KualiUserControlDefinition;
0036:        import org.kuali.core.document.authorization.MaintenanceDocumentAuthorizations;
0037:        import org.kuali.core.exceptions.UnknownBusinessClassAttributeException;
0038:        import org.kuali.core.inquiry.Inquirable;
0039:        import org.kuali.core.inquiry.KualiInquirableImpl;
0040:        import org.kuali.core.lookup.LookupUtils;
0041:        import org.kuali.core.lookup.keyvalues.ApcValuesFinder;
0042:        import org.kuali.core.lookup.keyvalues.IndicatorValuesFinder;
0043:        import org.kuali.core.lookup.keyvalues.KeyValuesFinder;
0044:        import org.kuali.core.lookup.valueFinder.ValueFinder;
0045:        import org.kuali.core.service.BusinessObjectDictionaryService;
0046:        import org.kuali.core.service.BusinessObjectMetaDataService;
0047:        import org.kuali.core.service.DataDictionaryService;
0048:        import org.kuali.core.service.EncryptionService;
0049:        import org.kuali.core.service.KualiConfigurationService;
0050:        import org.kuali.core.web.format.FormatException;
0051:        import org.kuali.core.web.format.Formatter;
0052:        import org.kuali.core.web.ui.Field;
0053:        import org.kuali.core.web.ui.Row;
0054:        import org.kuali.core.web.ui.Section;
0055:        import org.kuali.rice.KNSServiceLocator;
0056:
0057:        /**
0058:         * This class is used to build Field objects from underlying data dictionary and general utility methods for handling fields.
0059:         */
0060:        public class FieldUtils {
0061:            private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
0062:                    .getLogger(FieldUtils.class);
0063:            private static DataDictionaryService dictionaryService = KNSServiceLocator
0064:                    .getDataDictionaryService();
0065:            private static BusinessObjectMetaDataService businessObjectMetaDataService = KNSServiceLocator
0066:                    .getBusinessObjectMetaDataService();
0067:            private static BusinessObjectDictionaryService businessObjectDictionaryService = KNSServiceLocator
0068:                    .getBusinessObjectDictionaryService();
0069:            private static KualiConfigurationService kualiConfigurationService = KNSServiceLocator
0070:                    .getKualiConfigurationService();
0071:
0072:            public static void setInquiryURL(Field field, BusinessObject bo,
0073:                    String propertyName) {
0074:                String inquiryUrl = "";
0075:
0076:                Boolean b = businessObjectDictionaryService
0077:                        .noInquiryFieldInquiry(bo.getClass(), propertyName);
0078:                if (b == null || !b.booleanValue()) {
0079:                    Class<Inquirable> inquirableClass = businessObjectDictionaryService
0080:                            .getInquirableClass(bo.getClass());
0081:                    Boolean b2 = businessObjectDictionaryService
0082:                            .forceLookupResultFieldInquiry(bo.getClass(),
0083:                                    propertyName);
0084:                    Inquirable inq = null;
0085:                    try {
0086:                        if (inquirableClass != null) {
0087:                            inq = inquirableClass.newInstance();
0088:                        } else {
0089:                            inq = KNSServiceLocator.getKualiInquirable();
0090:                            if (LOG.isDebugEnabled()) {
0091:                                LOG.debug("Default Inquirable Class: "
0092:                                        + inq.getClass());
0093:                            }
0094:                        }
0095:
0096:                        inquiryUrl = inq.getInquiryUrl(bo, propertyName,
0097:                                null == b2 ? false : b2.booleanValue());
0098:
0099:                    } catch (Exception ex) {
0100:                        LOG
0101:                                .error(
0102:                                        "unable to create inquirable to get inquiry URL",
0103:                                        ex);
0104:                    }
0105:                }
0106:
0107:                field.setInquiryURL(inquiryUrl);
0108:            }
0109:
0110:            /**
0111:             * Builds up a Field object based on the propertyName and business object class.
0112:             * 
0113:             * @param propertyName
0114:             * @return Field
0115:             */
0116:            public static Field getPropertyField(Class businessObjectClass,
0117:                    String attributeName, boolean translateCheckboxes) {
0118:                Field field = new Field();
0119:                field.setPropertyName(attributeName);
0120:                field.setFieldLabel(dictionaryService.getAttributeLabel(
0121:                        businessObjectClass, attributeName));
0122:
0123:                // get control type for ui, depending on type set other field properties
0124:                ControlDefinition control = dictionaryService
0125:                        .getAttributeControlDefinition(businessObjectClass,
0126:                                attributeName);
0127:                String fieldType = Field.TEXT;
0128:
0129:                if (control != null) {
0130:                    if (control.isSelect()) {
0131:                        if (control.getScript() != null
0132:                                && control.getScript().length() > 0) {
0133:                            fieldType = Field.DROPDOWN_SCRIPT;
0134:                            field.setScript(control.getScript());
0135:                        } else {
0136:                            fieldType = Field.DROPDOWN;
0137:                        }
0138:                    }
0139:
0140:                    if (control.isApcSelect()) {
0141:                        fieldType = Field.DROPDOWN_APC;
0142:                    }
0143:
0144:                    if (control.isCheckbox()) {
0145:                        fieldType = Field.CHECKBOX;
0146:                    }
0147:
0148:                    if (control.isRadio()) {
0149:                        fieldType = Field.RADIO;
0150:                    }
0151:
0152:                    if (control.isHidden()) {
0153:                        fieldType = Field.HIDDEN;
0154:                    }
0155:
0156:                    if (control.isKualiUser()) {
0157:                        fieldType = Field.KUALIUSER;
0158:                        KualiUserControlDefinition kualiUserControl = (KualiUserControlDefinition) control;
0159:                        field.setUniversalIdAttributeName(kualiUserControl
0160:                                .getUniversalIdAttributeName());
0161:                        field.setUserIdAttributeName(kualiUserControl
0162:                                .getUserIdAttributeName());
0163:                        field.setPersonNameAttributeName(kualiUserControl
0164:                                .getPersonNameAttributeName());
0165:                    }
0166:
0167:                    if (control.isWorkflowWorkgroup()) {
0168:                        fieldType = Field.WORKFLOW_WORKGROUP;
0169:                    }
0170:
0171:                    if (control.isTextarea()) {
0172:                        fieldType = Field.TEXT_AREA;
0173:                    }
0174:
0175:                    if (control.isLookupHidden()) {
0176:                        fieldType = Field.LOOKUP_HIDDEN;
0177:                    }
0178:
0179:                    if (control.isLookupReadonly()) {
0180:                        fieldType = Field.LOOKUP_READONLY;
0181:                    }
0182:
0183:                    if (control.isCurrency()) {
0184:                        fieldType = Field.CURRENCY;
0185:                    }
0186:
0187:                    if (Field.CURRENCY.equals(fieldType)
0188:                            && control instanceof  CurrencyControlDefinition) {
0189:                        CurrencyControlDefinition currencyControl = (CurrencyControlDefinition) control;
0190:                        field.setStyleClass("amount");
0191:                        field.setSize(currencyControl.getSize());
0192:                        field.setFormattedMaxLength(currencyControl
0193:                                .getFormattedMaxLength());
0194:                    }
0195:
0196:                    // for text controls, set size attribute
0197:                    if (Field.TEXT.equals(fieldType)) {
0198:                        Integer size = control.getSize();
0199:                        if (size != null) {
0200:                            field.setSize(size.intValue());
0201:                        } else {
0202:                            field.setSize(30);
0203:                        }
0204:                        field.setDatePicker(control.isDatePicker());
0205:
0206:                    }
0207:
0208:                    if (Field.WORKFLOW_WORKGROUP.equals(fieldType)) {
0209:                        Integer size = control.getSize();
0210:                        if (size != null) {
0211:                            field.setSize(size.intValue());
0212:                        } else {
0213:                            field.setSize(30);
0214:                        }
0215:                    }
0216:
0217:                    // for text area controls, set rows and cols attributes
0218:                    if (Field.TEXT_AREA.equals(fieldType)) {
0219:                        Integer rows = control.getRows();
0220:                        if (rows != null) {
0221:                            field.setRows(rows.intValue());
0222:                        } else {
0223:                            field.setRows(3);
0224:                        }
0225:
0226:                        Integer cols = control.getCols();
0227:                        if (cols != null) {
0228:                            field.setCols(cols.intValue());
0229:                        } else {
0230:                            field.setCols(40);
0231:                        }
0232:                    }
0233:
0234:                    // for dropdown and radio, get instance of specified KeyValuesFinder and set field values
0235:                    if (Field.DROPDOWN.equals(fieldType)
0236:                            || Field.RADIO.equals(fieldType)
0237:                            || Field.DROPDOWN_SCRIPT.equals(fieldType)
0238:                            || Field.DROPDOWN_APC.equals(fieldType)) {
0239:                        Class keyFinderClassName = control
0240:                                .getValuesFinderClass();
0241:
0242:                        if (keyFinderClassName != null) {
0243:                            try {
0244:                                KeyValuesFinder finder = (KeyValuesFinder) keyFinderClassName
0245:                                        .newInstance();
0246:
0247:                                if (finder != null) {
0248:                                    if (finder instanceof  ApcValuesFinder
0249:                                            && control instanceof  ApcSelectControlDefinition) {
0250:                                        ((ApcValuesFinder) finder)
0251:                                                .setParameterNamespace(((ApcSelectControlDefinition) control)
0252:                                                        .getParameterNamespace());
0253:                                        ((ApcValuesFinder) finder)
0254:                                                .setParameterDetailType(((ApcSelectControlDefinition) control)
0255:                                                        .getParameterDetailType());
0256:                                        ((ApcValuesFinder) finder)
0257:                                                .setParameterName(((ApcSelectControlDefinition) control)
0258:                                                        .getParameterName());
0259:                                    }
0260:                                    field.setFieldValidValues(finder
0261:                                            .getKeyValues());
0262:                                }
0263:                            } catch (InstantiationException e) {
0264:                                LOG
0265:                                        .error("Unable to get new instance of finder class: "
0266:                                                + keyFinderClassName);
0267:                                throw new RuntimeException(
0268:                                        "Unable to get new instance of finder class: "
0269:                                                + keyFinderClassName);
0270:                            } catch (IllegalAccessException e) {
0271:                                LOG
0272:                                        .error("Unable to get new instance of finder class: "
0273:                                                + keyFinderClassName);
0274:                                throw new RuntimeException(
0275:                                        "Unable to get new instance of finder class: "
0276:                                                + keyFinderClassName);
0277:                            }
0278:                        }
0279:                    }
0280:
0281:                    if (Field.CHECKBOX.equals(fieldType) && translateCheckboxes) {
0282:                        fieldType = Field.RADIO;
0283:                        field.setFieldValidValues((new IndicatorValuesFinder())
0284:                                .getKeyValues());
0285:                    }
0286:                }
0287:
0288:                field.setFieldType(fieldType);
0289:
0290:                Boolean fieldRequired = KNSServiceLocator
0291:                        .getBusinessObjectDictionaryService()
0292:                        .getLookupAttributeRequired(businessObjectClass,
0293:                                attributeName);
0294:                if (fieldRequired != null) {
0295:                    field.setFieldRequired(fieldRequired.booleanValue());
0296:                }
0297:
0298:                Integer maxLength = dictionaryService.getAttributeMaxLength(
0299:                        businessObjectClass, attributeName);
0300:                if (maxLength != null) {
0301:                    field.setMaxLength(maxLength.intValue());
0302:                }
0303:
0304:                Boolean upperCase = null;
0305:                try {
0306:                    upperCase = dictionaryService.getAttributeForceUppercase(
0307:                            businessObjectClass, attributeName);
0308:                } catch (UnknownBusinessClassAttributeException t) {
0309:                    boolean catchme = true;
0310:                    // throw t;
0311:                }
0312:                if (upperCase != null) {
0313:                    field.setUpperCase(upperCase.booleanValue());
0314:                }
0315:
0316:                Class formatterClass = dictionaryService.getAttributeFormatter(
0317:                        businessObjectClass, attributeName);
0318:                if (formatterClass != null) {
0319:                    try {
0320:                        field.setFormatter((Formatter) formatterClass
0321:                                .newInstance());
0322:                    } catch (InstantiationException e) {
0323:                        LOG
0324:                                .error("Unable to get new instance of formatter class: "
0325:                                        + formatterClass.getName());
0326:                        throw new RuntimeException(
0327:                                "Unable to get new instance of formatter class: "
0328:                                        + formatterClass.getName());
0329:                    } catch (IllegalAccessException e) {
0330:                        LOG
0331:                                .error("Unable to get new instance of formatter class: "
0332:                                        + formatterClass.getName());
0333:                        throw new RuntimeException(
0334:                                "Unable to get new instance of formatter class: "
0335:                                        + formatterClass.getName());
0336:                    }
0337:                }
0338:
0339:                // set Field help properties
0340:                field.setBusinessObjectClassName(businessObjectClass.getName());
0341:                field.setFieldHelpName(attributeName);
0342:                field
0343:                        .setFieldHelpSummary(dictionaryService
0344:                                .getAttributeSummary(businessObjectClass,
0345:                                        attributeName));
0346:
0347:                return field;
0348:            }
0349:
0350:            /**
0351:             * Wraps each Field in the list into a Row.
0352:             * 
0353:             * @param fields
0354:             * @return List of Row objects
0355:             */
0356:            public static List wrapFields(List fields) {
0357:                return wrapFields(fields, RiceConstants.DEFAULT_NUM_OF_COLUMNS);
0358:            }
0359:
0360:            /**
0361:             * This method is to implement multiple columns where the numberOfColumns is obtained from data dictionary.
0362:             * 
0363:             * @param fields
0364:             * @param numberOfColumns
0365:             * @return
0366:             */
0367:            public static List<Row> wrapFields(List<Field> fields,
0368:                    int numberOfColumns) {
0369:
0370:                List<Row> rows = new ArrayList();
0371:                List<Field> fieldOnlyList = new ArrayList();
0372:                int fieldsPosition = 0;
0373:                for (Field element : fields) {
0374:                    if (Field.SUB_SECTION_SEPARATOR.equals(element
0375:                            .getFieldType())) {
0376:                        fieldsPosition = createBlankSpace(fieldOnlyList, rows,
0377:                                numberOfColumns, fieldsPosition);
0378:                        List fieldList = new ArrayList();
0379:                        fieldList.add(element);
0380:                        rows.add(new Row(fieldList));
0381:                    } else {
0382:                        if (fieldsPosition < numberOfColumns) {
0383:                            fieldOnlyList.add(element);
0384:                            fieldsPosition++;
0385:                        } else {
0386:                            rows.add(new Row(new ArrayList(fieldOnlyList)));
0387:                            fieldOnlyList.clear();
0388:                            fieldOnlyList.add(element);
0389:                            fieldsPosition = 1;
0390:                        }
0391:                    }
0392:                }
0393:                createBlankSpace(fieldOnlyList, rows, numberOfColumns,
0394:                        fieldsPosition);
0395:                return rows;
0396:            }
0397:
0398:            /**
0399:             * This is a helper method to create and add a blank space to the fieldOnly List.
0400:             * 
0401:             * @param fieldOnlyList
0402:             * @param rows
0403:             * @param numberOfColumns
0404:             * @return fieldsPosition
0405:             */
0406:            private static int createBlankSpace(List<Field> fieldOnlyList,
0407:                    List<Row> rows, int numberOfColumns, int fieldsPosition) {
0408:                int fieldOnlySize = fieldOnlyList.size();
0409:                if (fieldOnlySize > 0) {
0410:                    for (int i = 0; i < (numberOfColumns - fieldOnlySize); i++) {
0411:                        Field empty = new Field();
0412:                        empty.setFieldType(Field.BLANK_SPACE);
0413:                        fieldOnlyList.add(empty);
0414:                    }
0415:                    rows.add(new Row(new ArrayList(fieldOnlyList)));
0416:                    fieldOnlyList.clear();
0417:                    fieldsPosition = 0;
0418:                }
0419:                return fieldsPosition;
0420:            }
0421:
0422:            /**
0423:             * Wraps list of fields into a Field of type CONTAINER
0424:             * 
0425:             * @param name name for the field
0426:             * @param label label for the field
0427:             * @param fields list of fields that should be contained in the container
0428:             * @return Field of type CONTAINER
0429:             */
0430:            public static Field constructContainerField(String name,
0431:                    String label, List fields) {
0432:                return constructContainerField(name, label, fields,
0433:                        RiceConstants.DEFAULT_NUM_OF_COLUMNS);
0434:            }
0435:
0436:            /**
0437:             * Wraps list of fields into a Field of type CONTAINER and arrange them into multiple columns.
0438:             * 
0439:             * @param name name for the field
0440:             * @param label label for the field
0441:             * @param fields list of fields that should be contained in the container
0442:             * @param numberOfColumns the number of columns for each row that the fields should be arranged into
0443:             * @return Field of type CONTAINER
0444:             */
0445:            public static Field constructContainerField(String name,
0446:                    String label, List fields, int numberOfColumns) {
0447:                Field containerField = new Field();
0448:                containerField.setPropertyName(name);
0449:                containerField.setFieldLabel(label);
0450:                containerField.setFieldType(Field.CONTAINER);
0451:                containerField.setNumberOfColumnsForCollection(numberOfColumns);
0452:
0453:                List rows = wrapFields(fields, numberOfColumns);
0454:                containerField.setContainerRows(rows);
0455:
0456:                return containerField;
0457:            }
0458:
0459:            /**
0460:             * Uses reflection to get the property names of the business object, then checks for a matching field property name. If found,
0461:             * takes the value of the business object property and populates the field value. Iterates through for all fields in the list.
0462:             * 
0463:             * @param fields list of Field object to populate
0464:             * @param bo business object to get field values from
0465:             * @return List of fields with values populated from business object.
0466:             */
0467:            public static List populateFieldsFromBusinessObject(List fields,
0468:                    BusinessObject bo) {
0469:                List populatedFields = new ArrayList();
0470:
0471:                for (Iterator iter = fields.iterator(); iter.hasNext();) {
0472:                    Field element = (Field) iter.next();
0473:                    if (element.containsBOData()) {
0474:                        String propertyName = element.getPropertyName();
0475:
0476:                        // See: https://test.kuali.org/jira/browse/KULCOA-1185
0477:                        // Properties that could not possibly be set by the BusinessObject should be ignored.
0478:                        // (https://test.kuali.org/jira/browse/KULRNE-4354; this code was killing the src attribute of IMAGE_SUBMITs).
0479:                        if (isPropertyNested(propertyName)
0480:                                && !isObjectTreeNonNullAllTheWayDown(bo,
0481:                                        propertyName)
0482:                                && ((!element.getFieldType().equals(
0483:                                        Field.IMAGE_SUBMIT))
0484:                                        && !(element.getFieldType()
0485:                                                .equals(Field.CONTAINER)) && (!element
0486:                                        .getFieldType().equals(
0487:                                                Field.QUICKFINDER)))) {
0488:                            element.setPropertyValue(null);
0489:                        } else if (PropertyUtils.isReadable(bo, propertyName)) {
0490:                            Object obj = ObjectUtils.getNestedValue(bo, element
0491:                                    .getPropertyName());
0492:                            if (obj != null) {
0493:                                element.setPropertyValue(obj);
0494:                            }
0495:
0496:                            // set encrypted & masked value if user does not have permission to see real value in UI
0497:                            if (element.isSecure()) {
0498:                                try {
0499:                                    if (obj != null
0500:                                            && obj
0501:                                                    .toString()
0502:                                                    .endsWith(
0503:                                                            EncryptionService.HASH_POST_PREFIX)) {
0504:                                        element.setEncryptedValue(obj
0505:                                                .toString());
0506:                                    } else {
0507:                                        element
0508:                                                .setEncryptedValue(KNSServiceLocator
0509:                                                        .getEncryptionService()
0510:                                                        .encrypt(obj)
0511:                                                        + EncryptionService.ENCRYPTION_POST_PREFIX);
0512:                                    }
0513:                                } catch (GeneralSecurityException e) {
0514:                                    throw new RuntimeException(
0515:                                            "Unable to encrypt secure field "
0516:                                                    + e.getMessage());
0517:                                }
0518:                                element.setDisplayMaskValue(element
0519:                                        .getDisplayMask().maskValue(obj));
0520:                            }
0521:                        }
0522:                    }
0523:                    populatedFields.add(element);
0524:                }
0525:
0526:                return populatedFields;
0527:            }
0528:
0529:            /**
0530:             * This method indicates whether or not propertyName refers to a nested attribute.
0531:             * 
0532:             * @param propertyName
0533:             * @return true if propertyName refers to a nested property (e.g. "x.y")
0534:             */
0535:            static private boolean isPropertyNested(String propertyName) {
0536:                return -1 != propertyName.indexOf('.');
0537:            }
0538:
0539:            /**
0540:             * This method verifies that all of the parent objects of propertyName are non-null.
0541:             * 
0542:             * @param bo
0543:             * @param propertyName
0544:             * @return true if all parents are non-null, otherwise false
0545:             */
0546:
0547:            static private boolean isObjectTreeNonNullAllTheWayDown(
0548:                    BusinessObject bo, String propertyName) {
0549:                String[] propertyParts = propertyName.split("\\.");
0550:
0551:                StringBuffer property = new StringBuffer();
0552:                for (int i = 0; i < propertyParts.length - 1; i++) {
0553:
0554:                    property.append((0 == property.length()) ? "" : ".")
0555:                            .append(propertyParts[i]);
0556:                    try {
0557:                        if (null == PropertyUtils.getNestedProperty(bo,
0558:                                property.toString())) {
0559:                            return false;
0560:                        }
0561:                    } catch (Throwable t) {
0562:                        LOG.debug(
0563:                                "Either getter or setter not specified for property \""
0564:                                        + property.toString() + "\"", t);
0565:                        return false;
0566:                    }
0567:                }
0568:
0569:                return true;
0570:
0571:            }
0572:
0573:            /**
0574:             * @param bo
0575:             * @param propertyName
0576:             * @return true if one (or more) of the intermediate objects in the given propertyName is null
0577:             */
0578:            private static boolean containsIntermediateNull(Object bo,
0579:                    String propertyName) {
0580:                boolean containsNull = false;
0581:
0582:                if (StringUtils.contains(propertyName, ".")) {
0583:                    String prefix = StringUtils.substringBefore(propertyName,
0584:                            ".");
0585:                    Object propertyValue = ObjectUtils.getPropertyValue(bo,
0586:                            prefix);
0587:
0588:                    if (propertyValue == null) {
0589:                        containsNull = true;
0590:                    } else {
0591:                        String suffix = StringUtils.substringAfter(
0592:                                propertyName, ".");
0593:                        containsNull = containsIntermediateNull(propertyValue,
0594:                                suffix);
0595:                    }
0596:                }
0597:
0598:                return containsNull;
0599:            }
0600:
0601:            /**
0602:             * Uses reflection to get the property names of the business object, then checks for the property name as a key in the passed
0603:             * map. If found, takes the value from the map and sets the business object property.
0604:             * 
0605:             * @param bo
0606:             * @param fieldValues
0607:             * @return Cached Values from any formatting failures
0608:             */
0609:            public static Map populateBusinessObjectFromMap(BusinessObject bo,
0610:                    Map fieldValues) {
0611:                return populateBusinessObjectFromMap(bo, fieldValues, "");
0612:            }
0613:
0614:            /**
0615:             * Uses reflection to get the property names of the business object, then checks for the property name as a key in the passed
0616:             * map. If found, takes the value from the map and sets the business object property.
0617:             * 
0618:             * @param bo
0619:             * @param fieldValues
0620:             * @param propertyNamePrefix this value will be prepended to all property names in the returned unformattable values map
0621:             * @return Cached Values from any formatting failures
0622:             */
0623:            public static Map populateBusinessObjectFromMap(BusinessObject bo,
0624:                    Map fieldValues, String propertyNamePrefix) {
0625:                Map cachedValues = new HashMap();
0626:                ErrorMap errorMap = GlobalVariables.getErrorMap();
0627:
0628:                try {
0629:                    for (Iterator iter = fieldValues.keySet().iterator(); iter
0630:                            .hasNext();) {
0631:                        String propertyName = (String) iter.next();
0632:
0633:                        if (propertyName
0634:                                .endsWith(RiceConstants.CHECKBOX_PRESENT_ON_FORM_ANNOTATION)) {
0635:                            // since checkboxes do not post values when unchecked, this code detects whether a checkbox was unchecked, and
0636:                            // sets the value to false.
0637:                            if (StringUtils.isNotBlank((String) fieldValues
0638:                                    .get(propertyName))) {
0639:                                String checkboxName = StringUtils
0640:                                        .removeEnd(
0641:                                                propertyName,
0642:                                                RiceConstants.CHECKBOX_PRESENT_ON_FORM_ANNOTATION);
0643:                                String checkboxValue = (String) fieldValues
0644:                                        .get(checkboxName);
0645:                                if (checkboxValue == null) {
0646:                                    // didn't find a checkbox value, assume that it is unchecked
0647:                                    if (PropertyUtils.isWriteable(bo,
0648:                                            checkboxName)) {
0649:                                        Class type = ObjectUtils
0650:                                                .easyGetPropertyType(bo,
0651:                                                        checkboxName);
0652:                                        if (type == Boolean.TYPE
0653:                                                || type == Boolean.class) {
0654:                                            // ASSUMPTION: unchecked means false
0655:                                            ObjectUtils
0656:                                                    .setObjectProperty(bo,
0657:                                                            checkboxName, type,
0658:                                                            "false");
0659:                                        }
0660:                                    }
0661:                                }
0662:                            }
0663:                            // else, if not null, then it has a value, and we'll let the rest of the code handle it when the param is processed on
0664:                            // another iteration (may be before or after this iteration).
0665:                        } else if (PropertyUtils.isWriteable(bo, propertyName)
0666:                                && fieldValues.get(propertyName) != null) {
0667:                            // if the field propertyName is a valid property on the bo class
0668:                            Class type = ObjectUtils.easyGetPropertyType(bo,
0669:                                    propertyName);
0670:                            try {
0671:                                ObjectUtils.setObjectProperty(bo, propertyName,
0672:                                        type, fieldValues.get(propertyName));
0673:                            } catch (FormatException e) {
0674:                                cachedValues.put(propertyNamePrefix
0675:                                        + propertyName, fieldValues
0676:                                        .get(propertyName));
0677:                                errorMap.putError(propertyName,
0678:                                        e.getErrorKey(), e.getErrorArgs());
0679:                            }
0680:                        }
0681:                    }
0682:                } catch (IllegalAccessException e) {
0683:                    LOG.error("unable to populate business object"
0684:                            + e.getMessage());
0685:                    throw new RuntimeException(e.getMessage(), e);
0686:                } catch (InvocationTargetException e) {
0687:                    LOG.error("unable to populate business object"
0688:                            + e.getMessage());
0689:                    throw new RuntimeException(e.getMessage(), e);
0690:                } catch (NoSuchMethodException e) {
0691:                    LOG.error("unable to populate business object"
0692:                            + e.getMessage());
0693:                    throw new RuntimeException(e.getMessage(), e);
0694:                }
0695:
0696:                return cachedValues;
0697:            }
0698:
0699:            /**
0700:             * Does prefixing and read only settings of a Field UI for display in a maintenance document.
0701:             * 
0702:             * @param field - the Field object to be displayed
0703:             * @param keyFieldNames - Primary key property names for the business object being maintained.
0704:             * @param namePrefix - String to prefix Field names with.
0705:             * @param maintenanceAction - The maintenance action requested.
0706:             * @param readOnly - Indicates whether all fields should be read only.
0707:             * @return Field
0708:             */
0709:            public static Field fixFieldForForm(Field field,
0710:                    List keyFieldNames, String namePrefix,
0711:                    String maintenanceAction, boolean readOnly,
0712:                    MaintenanceDocumentAuthorizations auths) {
0713:                String propertyName = field.getPropertyName();
0714:                // We only need to do the following processing if the field is not a sub section header
0715:                if (field.containsBOData()) {
0716:
0717:                    // don't prefix submit fields, must start with dispatch parameter name
0718:                    if (!propertyName
0719:                            .startsWith(RiceConstants.DISPATCH_REQUEST_PARAMETER)) {
0720:                        // if the developer hasn't set a specific prefix use the one supplied
0721:                        if (field.getPropertyPrefix() == null
0722:                                || field.getPropertyPrefix().equals("")) {
0723:                            field.setPropertyName(namePrefix + propertyName);
0724:                        } else {
0725:                            field.setPropertyName(field.getPropertyPrefix()
0726:                                    + "." + propertyName);
0727:                        }
0728:                    }
0729:
0730:                    if (readOnly) {
0731:                        field.setReadOnly(true);
0732:                    }
0733:
0734:                    // set keys read only for edit
0735:                    if (keyFieldNames.contains(propertyName)
0736:                            && RiceConstants.MAINTENANCE_EDIT_ACTION
0737:                                    .equals(maintenanceAction)) {
0738:                        field.setReadOnly(true);
0739:                        field.setKeyField(true);
0740:                    }
0741:
0742:                    // apply any authorization restrictions to field availability on the UI
0743:                    applyAuthorization(field, auths);
0744:
0745:                    // if fieldConversions specified, prefix with new constant
0746:                    if (StringUtils.isNotBlank(field.getFieldConversions())) {
0747:                        String fieldConversions = field.getFieldConversions();
0748:                        String newFieldConversions = RiceConstants.EMPTY_STRING;
0749:                        String[] conversions = StringUtils.split(
0750:                                fieldConversions,
0751:                                RiceConstants.FIELD_CONVERSIONS_SEPERATOR);
0752:
0753:                        for (int l = 0; l < conversions.length; l++) {
0754:                            String conversion = conversions[l];
0755:                            String[] conversionPair = StringUtils
0756:                                    .split(
0757:                                            conversion,
0758:                                            RiceConstants.FIELD_CONVERSION_PAIR_SEPERATOR);
0759:                            String conversionFrom = conversionPair[0];
0760:                            String conversionTo = conversionPair[1];
0761:                            conversionTo = RiceConstants.MAINTENANCE_NEW_MAINTAINABLE
0762:                                    + conversionTo;
0763:                            newFieldConversions += (conversionFrom
0764:                                    + RiceConstants.FIELD_CONVERSION_PAIR_SEPERATOR + conversionTo);
0765:
0766:                            if (l < conversions.length) {
0767:                                newFieldConversions += RiceConstants.FIELD_CONVERSIONS_SEPERATOR;
0768:                            }
0769:                        }
0770:
0771:                        field.setFieldConversions(newFieldConversions);
0772:                    }
0773:
0774:                    if (Field.KUALIUSER.equals(field.getFieldType())) {
0775:                        // prefix the personNameAttributeName
0776:                        int suffixIndex = field.getPropertyName().indexOf(
0777:                                field.getUserIdAttributeName());
0778:                        if (suffixIndex != -1) {
0779:                            field.setPersonNameAttributeName(field
0780:                                    .getPropertyName()
0781:                                    .substring(0, suffixIndex)
0782:                                    + field.getPersonNameAttributeName());
0783:                        } else {
0784:                            field.setPersonNameAttributeName(namePrefix
0785:                                    + field.getPersonNameAttributeName());
0786:                        }
0787:
0788:                        // TODO: do we need to prefix the universalIdAttributeName in Field as well?
0789:                    }
0790:
0791:                    // if lookupParameters specified, prefix with new constant
0792:                    if (StringUtils.isNotBlank(field.getLookupParameters())) {
0793:                        String lookupParameters = field.getLookupParameters();
0794:                        String newLookupParameters = RiceConstants.EMPTY_STRING;
0795:                        String[] conversions = StringUtils.split(
0796:                                lookupParameters,
0797:                                RiceConstants.FIELD_CONVERSIONS_SEPERATOR);
0798:
0799:                        for (int m = 0; m < conversions.length; m++) {
0800:                            String conversion = conversions[m];
0801:                            String[] conversionPair = StringUtils
0802:                                    .split(
0803:                                            conversion,
0804:                                            RiceConstants.FIELD_CONVERSION_PAIR_SEPERATOR);
0805:                            String conversionFrom = conversionPair[0];
0806:                            String conversionTo = conversionPair[1];
0807:                            conversionFrom = RiceConstants.MAINTENANCE_NEW_MAINTAINABLE
0808:                                    + conversionFrom;
0809:                            newLookupParameters += (conversionFrom
0810:                                    + RiceConstants.FIELD_CONVERSION_PAIR_SEPERATOR + conversionTo);
0811:
0812:                            if (m < conversions.length) {
0813:                                newLookupParameters += RiceConstants.FIELD_CONVERSIONS_SEPERATOR;
0814:                            }
0815:                        }
0816:
0817:                        field.setLookupParameters(newLookupParameters);
0818:                    }
0819:
0820:                    // CONTAINER field types have nested rows and fields that need setup for the form
0821:                    if (Field.CONTAINER.equals(field.getFieldType())) {
0822:                        List containerRows = field.getContainerRows();
0823:                        List fixedRows = new ArrayList();
0824:
0825:                        for (Iterator iter = containerRows.iterator(); iter
0826:                                .hasNext();) {
0827:                            Row containerRow = (Row) iter.next();
0828:                            List containerFields = containerRow.getFields();
0829:                            List fixedFields = new ArrayList();
0830:
0831:                            for (Iterator iterator = containerFields.iterator(); iterator
0832:                                    .hasNext();) {
0833:                                Field containerField = (Field) iterator.next();
0834:                                containerField = fixFieldForForm(
0835:                                        containerField, keyFieldNames,
0836:                                        namePrefix, maintenanceAction,
0837:                                        readOnly, auths);
0838:                                fixedFields.add(containerField);
0839:                            }
0840:
0841:                            fixedRows.add(new Row(fixedFields));
0842:                        }
0843:
0844:                        field.setContainerRows(fixedRows);
0845:                    }
0846:                }
0847:                return field;
0848:            }
0849:
0850:            public static void applyAuthorization(Field field,
0851:                    MaintenanceDocumentAuthorizations auths) {
0852:
0853:                // only apply this on the newMaintainable
0854:                if (field.getPropertyName().startsWith(
0855:                        RiceConstants.MAINTENANCE_NEW_MAINTAINABLE)) {
0856:
0857:                    // get just the actual fieldName, with the document.newMaintainableObject, etc etc removed
0858:                    String fieldName = field.getPropertyName()
0859:                            .substring(
0860:                                    RiceConstants.MAINTENANCE_NEW_MAINTAINABLE
0861:                                            .length());
0862:
0863:                    // if the field is restricted somehow
0864:                    if (auths.hasAuthFieldRestricted(fieldName)) {
0865:                        FieldAuthorization fieldAuth = auths
0866:                                .getAuthFieldAuthorization(fieldName);
0867:
0868:                        // if its an editable field, allow decreasing availability to readonly or hidden
0869:                        if (Field.isInputField(field.getFieldType())
0870:                                || field.getFieldType().equalsIgnoreCase(
0871:                                        Field.CHECKBOX)) {
0872:
0873:                            // only touch the field if the restricted type is hidden or readonly
0874:                            if (fieldAuth.isReadOnly()) {
0875:                                if (!field.isReadOnly()) {
0876:                                    field.setReadOnly(true);
0877:                                }
0878:                            }
0879:
0880:                            else if (fieldAuth.isHidden()) {
0881:                                if (field.getFieldType() != Field.HIDDEN) {
0882:                                    field.setFieldType(Field.HIDDEN);
0883:                                }
0884:                            }
0885:                        }
0886:
0887:                        // if the field is readOnly, and the authorization says it should be hidden,
0888:                        // then restrict it
0889:                        if (field.isReadOnly() && fieldAuth.isHidden()) {
0890:                            field.setFieldType(Field.HIDDEN);
0891:                        }
0892:                    }
0893:                    // special check for old maintainable - need to ensure that fields hidden on the
0894:                    // "new" side are also hidden on the old side
0895:                } else if (field.getPropertyName().startsWith(
0896:                        RiceConstants.MAINTENANCE_OLD_MAINTAINABLE)) {
0897:                    // get just the actual fieldName, with the document.oldMaintainableObject, etc etc removed
0898:                    String fieldName = field.getPropertyName()
0899:                            .substring(
0900:                                    RiceConstants.MAINTENANCE_OLD_MAINTAINABLE
0901:                                            .length());
0902:                    // if the field is restricted somehow
0903:                    if (auths.hasAuthFieldRestricted(fieldName)) {
0904:                        FieldAuthorization fieldAuth = auths
0905:                                .getAuthFieldAuthorization(fieldName);
0906:
0907:                        if (fieldAuth.isHidden()) {
0908:                            field.setFieldType(Field.HIDDEN);
0909:                        }
0910:                    }
0911:                }
0912:            }
0913:
0914:            /**
0915:             * Merges together sections of the old maintainable and new maintainable.
0916:             * 
0917:             * @param oldSections
0918:             * @param newSections
0919:             * @param keyFieldNames
0920:             * @param maintenanceAction
0921:             * @param readOnly
0922:             * @return List of Section objects
0923:             */
0924:            public static List meshSections(List oldSections, List newSections,
0925:                    List keyFieldNames, String maintenanceAction,
0926:                    boolean readOnly, MaintenanceDocumentAuthorizations auths) {
0927:                List meshedSections = new ArrayList();
0928:
0929:                for (int i = 0; i < newSections.size(); i++) {
0930:                    Section maintSection = (Section) newSections.get(i);
0931:                    List sectionRows = maintSection.getRows();
0932:                    Section oldMaintSection = (Section) oldSections.get(i);
0933:                    List oldSectionRows = oldMaintSection.getRows();
0934:                    List<Row> meshedRows = new ArrayList();
0935:                    meshedRows = meshRows(oldSectionRows, sectionRows,
0936:                            keyFieldNames, maintenanceAction, readOnly, auths);
0937:                    maintSection.setRows(meshedRows);
0938:                    if (StringUtils.isBlank(maintSection.getErrorKey())) {
0939:                        maintSection.setErrorKey(MaintenanceUtils
0940:                                .generateErrorKeyForSection(maintSection));
0941:                    }
0942:                    meshedSections.add(maintSection);
0943:                }
0944:
0945:                return meshedSections;
0946:            }
0947:
0948:            /**
0949:             * This method is a helper method for createRowsForNewFields. It puts together all the fields that should exist in a row after
0950:             * calling the fixFieldForForm for the other necessary prefixing and setting up of the fields.
0951:             * 
0952:             * @param newFields
0953:             * @param keyFieldNames
0954:             * @param maintenanceAction
0955:             * @param readOnly
0956:             * @param auths
0957:             * @return a List of Field
0958:             */
0959:            private static List<Field> arrangeNewFields(List newFields,
0960:                    List keyFieldNames, String maintenanceAction,
0961:                    boolean readOnly, MaintenanceDocumentAuthorizations auths) {
0962:                List<Field> results = new ArrayList();
0963:                for (int k = 0; k < newFields.size(); k++) {
0964:                    Field newMaintField = (Field) newFields.get(k);
0965:                    String propertyName = newMaintField.getPropertyName();
0966:                    newMaintField = FieldUtils.fixFieldForForm(newMaintField,
0967:                            keyFieldNames,
0968:                            RiceConstants.MAINTENANCE_NEW_MAINTAINABLE,
0969:                            maintenanceAction, readOnly, auths);
0970:
0971:                    results.add(newMaintField);
0972:                }
0973:                return results;
0974:            }
0975:
0976:            /**
0977:             * Merges together rows of an old maintainable section and new maintainable section.
0978:             * 
0979:             * @param oldRows
0980:             * @param newRows
0981:             * @param keyFieldNames
0982:             * @param maintenanceAction
0983:             * @param readOnly
0984:             * @return List of Row objects
0985:             */
0986:            public static List meshRows(List oldRows, List newRows,
0987:                    List keyFieldNames, String maintenanceAction,
0988:                    boolean readOnly, MaintenanceDocumentAuthorizations auths) {
0989:                List<Row> meshedRows = new ArrayList<Row>();
0990:
0991:                for (int j = 0; j < newRows.size(); j++) {
0992:                    Row sectionRow = (Row) newRows.get(j);
0993:                    List rowFields = sectionRow.getFields();
0994:                    Row oldSectionRow = null;
0995:                    List oldRowFields = new ArrayList();
0996:
0997:                    if (null != oldRows && oldRows.size() > j) {
0998:                        oldSectionRow = (Row) oldRows.get(j);
0999:                        oldRowFields = oldSectionRow.getFields();
1000:                    }
1001:
1002:                    List meshedFields = meshFields(oldRowFields, rowFields,
1003:                            keyFieldNames, maintenanceAction, readOnly, auths);
1004:                    if (meshedFields.size() > 0) {
1005:                        Row meshedRow = new Row(meshedFields);
1006:                        if (sectionRow.isHidden()) {
1007:                            meshedRow.setHidden(true);
1008:                        }
1009:
1010:                        meshedRows.add(meshedRow);
1011:                    }
1012:                }
1013:
1014:                return meshedRows;
1015:            }
1016:
1017:            /**
1018:             * Merges together fields and an old maintainble row and new maintainable row, for each field call fixFieldForForm.
1019:             * 
1020:             * @param oldFields
1021:             * @param newFields
1022:             * @param keyFieldNames
1023:             * @param maintenanceAction
1024:             * @param readOnly
1025:             * @return List of Field objects
1026:             */
1027:            public static List meshFields(List oldFields, List newFields,
1028:                    List keyFieldNames, String maintenanceAction,
1029:                    boolean readOnly, MaintenanceDocumentAuthorizations auths) {
1030:                List meshedFields = new ArrayList();
1031:
1032:                List newFieldsToMerge = new ArrayList();
1033:                List oldFieldsToMerge = new ArrayList();
1034:
1035:                for (int k = 0; k < newFields.size(); k++) {
1036:                    Field newMaintField = (Field) newFields.get(k);
1037:                    String propertyName = newMaintField.getPropertyName();
1038:                    // If this is an add button, then we have to have only this field for the entire row.
1039:                    if (Field.IMAGE_SUBMIT.equals(newMaintField.getFieldType())) {
1040:                        meshedFields.add(newMaintField);
1041:                    } else if (Field.CONTAINER.equals(newMaintField
1042:                            .getFieldType())) {
1043:                        if (oldFields.size() > k) {
1044:                            Field oldMaintField = (Field) oldFields.get(k);
1045:                            newMaintField = meshContainerFields(oldMaintField,
1046:                                    newMaintField, keyFieldNames,
1047:                                    maintenanceAction, readOnly, auths);
1048:                        } else {
1049:                            newMaintField = meshContainerFields(newMaintField,
1050:                                    newMaintField, keyFieldNames,
1051:                                    maintenanceAction, readOnly, auths);
1052:                        }
1053:                        meshedFields.add(newMaintField);
1054:                    } else {
1055:                        newMaintField = FieldUtils.fixFieldForForm(
1056:                                newMaintField, keyFieldNames,
1057:                                RiceConstants.MAINTENANCE_NEW_MAINTAINABLE,
1058:                                maintenanceAction, readOnly, auths);
1059:                        // add old fields for edit
1060:                        if (RiceConstants.MAINTENANCE_EDIT_ACTION
1061:                                .equals(maintenanceAction)
1062:                                || RiceConstants.MAINTENANCE_COPY_ACTION
1063:                                        .equals(maintenanceAction)) {
1064:                            Field oldMaintField = (Field) oldFields.get(k);
1065:                            oldMaintField = FieldUtils.fixFieldForForm(
1066:                                    oldMaintField, keyFieldNames,
1067:                                    RiceConstants.MAINTENANCE_OLD_MAINTAINABLE,
1068:                                    maintenanceAction, true, auths);
1069:                            oldFieldsToMerge.add(oldMaintField);
1070:
1071:                            // compare values for change, and set new maintainable fields for highlighting
1072:                            // no point in highlighting the hidden fields, since they won't be rendered anyways
1073:                            if (!StringUtils.equalsIgnoreCase(newMaintField
1074:                                    .getPropertyValue(), oldMaintField
1075:                                    .getPropertyValue())
1076:                                    && !Field.HIDDEN.equals(newMaintField
1077:                                            .getFieldType())) {
1078:                                newMaintField.setHighlightField(true);
1079:                            }
1080:                        }
1081:
1082:                        newFieldsToMerge.add(newMaintField);
1083:
1084:                        for (Iterator iter = oldFieldsToMerge.iterator(); iter
1085:                                .hasNext();) {
1086:                            Field element = (Field) iter.next();
1087:                            meshedFields.add(element);
1088:                        }
1089:
1090:                        for (Iterator iter = newFieldsToMerge.iterator(); iter
1091:                                .hasNext();) {
1092:                            Field element = (Field) iter.next();
1093:                            meshedFields.add(element);
1094:                        }
1095:                    }
1096:                }
1097:                return meshedFields;
1098:            }
1099:
1100:            /**
1101:             * Determines whether field level help is enabled for the field corresponding to the businessObjectClass and attribute name
1102:             * 
1103:             * If this value is true, then the field level help will be enabled.
1104:             * If false, then whether a field is enabled is determined by the value returned by {@link #isLookupFieldLevelHelpDisabled(Class, String)} and the system-wide
1105:             * parameter setting.  Note that if a field is read-only, that may cause field-level help to not be rendered.
1106:             * 
1107:             * @param businessObjectClass the looked up class
1108:             * @param attributeName the attribute for the field
1109:             * @return true if field level help is enabled, false if the value of this method should NOT be used to determine whether this method's return value
1110:             * affects the enablement of field level help
1111:             */
1112:            protected static boolean isLookupFieldLevelHelpEnabled(
1113:                    Class businessObjectClass, String attributeName) {
1114:                return false;
1115:            }
1116:
1117:            /**
1118:             * Determines whether field level help is disabled for the field corresponding to the businessObjectClass and attribute name
1119:             * 
1120:             * If this value is true and {@link #isLookupFieldLevelHelpEnabled(Class, String)} returns false,
1121:             * then the field level help will not be rendered.  If both this and {@link #isLookupFieldLevelHelpEnabled(Class, String)} return false, then the system-wide
1122:             * setting will determine whether field level help is enabled.  Note that if a field is read-only, that may cause field-level help to not be rendered.
1123:             * 
1124:             * @param businessObjectClass the looked up class
1125:             * @param attributeName the attribute for the field
1126:             * @return true if field level help is disabled, false if the value of this method should NOT be used to determine whether this method's return value
1127:             * affects the enablement of field level help
1128:             */
1129:            protected static boolean isLookupFieldLevelHelpDisabled(
1130:                    Class businessObjectClass, String attributeName) {
1131:                return false;
1132:            }
1133:
1134:            public static List createAndPopulateFieldsForLookup(
1135:                    List<String> lookupFieldAttributeList,
1136:                    List<String> readOnlyFieldsList, Class businessObjectClass)
1137:                    throws InstantiationException, IllegalAccessException {
1138:                List<Field> fields = new ArrayList<Field>();
1139:                for (Iterator iter = lookupFieldAttributeList.iterator(); iter
1140:                        .hasNext();) {
1141:                    String attributeName = (String) iter.next();
1142:                    Field field = FieldUtils.getPropertyField(
1143:                            businessObjectClass, attributeName, true);
1144:
1145:                    // TODO: This makes no sense, why do we pass it in and then return the same thing
1146:                    // back to us?
1147:                    field = LookupUtils.setFieldQuickfinder(
1148:                            (BusinessObject) businessObjectClass.newInstance(),
1149:                            attributeName, field, lookupFieldAttributeList);
1150:
1151:                    // overwrite maxLength to allow for wildcards and ranges in the select
1152:                    field.setMaxLength(100);
1153:                    fields.add(field);
1154:
1155:                    // set default value
1156:                    String defaultValue = businessObjectMetaDataService
1157:                            .getLookupFieldDefaultValue(businessObjectClass,
1158:                                    attributeName);
1159:                    if (defaultValue != null) {
1160:                        field.setPropertyValue(defaultValue);
1161:                        field.setDefaultValue(defaultValue);
1162:                    }
1163:
1164:                    Class defaultValueFinderClass = businessObjectMetaDataService
1165:                            .getLookupFieldDefaultValueFinderClass(
1166:                                    businessObjectClass, attributeName);
1167:                    if (defaultValueFinderClass != null) {
1168:                        field
1169:                                .setPropertyValue(((ValueFinder) defaultValueFinderClass
1170:                                        .newInstance()).getValue());
1171:                        field
1172:                                .setDefaultValue(((ValueFinder) defaultValueFinderClass
1173:                                        .newInstance()).getValue());
1174:                    }
1175:                    if (readOnlyFieldsList != null
1176:                            && readOnlyFieldsList.contains(field
1177:                                    .getPropertyName())) {
1178:                        field.setReadOnly(true);
1179:                    }
1180:
1181:                    field
1182:                            .setFieldLevelHelpEnabled(isLookupFieldLevelHelpEnabled(
1183:                                    businessObjectClass, attributeName));
1184:                    field
1185:                            .setFieldLevelHelpDisabled(isLookupFieldLevelHelpDisabled(
1186:                                    businessObjectClass, attributeName));
1187:                }
1188:                return fields;
1189:            }
1190:
1191:            private static Field meshContainerFields(Field oldMaintField,
1192:                    Field newMaintField, List keyFieldNames,
1193:                    String maintenanceAction, boolean readOnly,
1194:                    MaintenanceDocumentAuthorizations auths) {
1195:                List resultingRows = new ArrayList();
1196:                resultingRows.addAll(meshRows(oldMaintField.getContainerRows(),
1197:                        newMaintField.getContainerRows(), keyFieldNames,
1198:                        maintenanceAction, readOnly, auths));
1199:                Field resultingField = newMaintField;
1200:                resultingField.setFieldType(Field.CONTAINER);
1201:
1202:                // save the summary info
1203:                resultingField.setContainerElementName(newMaintField
1204:                        .getContainerElementName());
1205:                resultingField.setContainerDisplayFields(newMaintField
1206:                        .getContainerDisplayFields());
1207:                resultingField.setNumberOfColumnsForCollection(newMaintField
1208:                        .getNumberOfColumnsForCollection());
1209:
1210:                resultingField.setContainerRows(resultingRows);
1211:                List resultingRowsList = newMaintField.getContainerRows();
1212:                if (resultingRowsList.size() > 0) {
1213:                    List resultingFieldsList = ((Row) resultingRowsList.get(0))
1214:                            .getFields();
1215:                    if (resultingFieldsList.size() > 0) {
1216:                        // todo: assign the correct propertyName to the container in the first place. For now, I'm wary of the weird usages
1217:                        // of constructContainerField().
1218:                        String containedFieldName = ((Field) (resultingFieldsList
1219:                                .get(0))).getPropertyName();
1220:                        resultingField.setPropertyName(containedFieldName
1221:                                .substring(0, containedFieldName
1222:                                        .lastIndexOf('.')));
1223:                    }
1224:                } else {
1225:                    resultingField.setPropertyName(oldMaintField
1226:                            .getPropertyName());
1227:                }
1228:                return resultingField;
1229:            }
1230:
1231:            /**
1232:             * This method modifies the passed in field so that it may be used to render a multiple values lookup button
1233:             * 
1234:             * @param field this object will be modified by this method
1235:             * @param parents
1236:             * @param definition
1237:             */
1238:            static final public void modifyFieldToSupportMultipleValueLookups(
1239:                    Field field, String parents,
1240:                    MaintainableCollectionDefinition definition) {
1241:                field.setMultipleValueLookedUpCollectionName(parents
1242:                        + definition.getName());
1243:                field.setMultipleValueLookupClassName(definition
1244:                        .getSourceClassName());
1245:                field.setMultipleValueLookupClassLabel(dictionaryService
1246:                        .getDataDictionary().getBusinessObjectEntry(
1247:                                definition.getSourceClassName())
1248:                        .getObjectLabel());
1249:            }
1250:
1251:            /**
1252:             * Returns whether the passed in collection has been properly configured in the maint doc dictionary to support multiple value
1253:             * lookups.
1254:             * 
1255:             * @param definition
1256:             * @return
1257:             */
1258:            static final public boolean isCollectionMultipleLookupEnabled(
1259:                    MaintainableCollectionDefinition definition) {
1260:                return definition.getSourceClassName() != null
1261:                        && definition.getSourceClassName().length() > 0
1262:                        && definition.isIncludeMultipleLookupLine();
1263:            }
1264:
1265:            /**
1266:             * This method removes any duplicating spacing (internal or on the ends) from a String, meant to be exposed as a tag library
1267:             * function.
1268:             * 
1269:             * @param s String to remove duplicate spacing from.
1270:             * @return String without duplicate spacing.
1271:             */
1272:            public static String scrubWhitespace(String s) {
1273:                return s.replaceAll("(\\s)(\\s+)", " ");
1274:            }
1275:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.