Source Code Cross Referenced for GenericEntity.java in  » ERP-CRM-Financial » ofbiz » org » ofbiz » entity » 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 » ofbiz » org.ofbiz.entity 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*******************************************************************************
0002:         * Licensed to the Apache Software Foundation (ASF) under one
0003:         * or more contributor license agreements.  See the NOTICE file
0004:         * distributed with this work for additional information
0005:         * regarding copyright ownership.  The ASF licenses this file
0006:         * to you under the Apache License, Version 2.0 (the
0007:         * "License"); you may not use this file except in compliance
0008:         * with the License.  You may obtain a copy of the License at
0009:         * 
0010:         * http://www.apache.org/licenses/LICENSE-2.0
0011:         * 
0012:         * Unless required by applicable law or agreed to in writing,
0013:         * software distributed under the License is distributed on an
0014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015:         * KIND, either express or implied.  See the License for the
0016:         * specific language governing permissions and limitations
0017:         * under the License.
0018:         *******************************************************************************/package org.ofbiz.entity;
0019:
0020:        import java.io.PrintWriter;
0021:        import java.io.Serializable;
0022:        import java.math.BigDecimal;
0023:        import java.util.Collection;
0024:        import java.util.Collections;
0025:        import java.util.Iterator;
0026:        import java.util.Locale;
0027:        import java.util.Map;
0028:        import java.util.MissingResourceException;
0029:        import java.util.Observable;
0030:        import java.util.ResourceBundle;
0031:        import java.util.TreeSet;
0032:
0033:        import javolution.lang.Reusable;
0034:        import javolution.util.FastList;
0035:        import javolution.util.FastMap;
0036:
0037:        import org.ofbiz.base.util.Base64;
0038:        import org.ofbiz.base.util.Debug;
0039:        import org.ofbiz.base.util.ObjectType;
0040:        import org.ofbiz.base.util.UtilDateTime;
0041:        import org.ofbiz.base.util.UtilProperties;
0042:        import org.ofbiz.base.util.UtilValidate;
0043:        import org.ofbiz.base.util.UtilXml;
0044:        import org.ofbiz.base.util.collections.LocalizedMap;
0045:        import org.ofbiz.entity.condition.EntityCondition;
0046:        import org.ofbiz.entity.jdbc.SqlJdbcUtil;
0047:        import org.ofbiz.entity.model.ModelEntity;
0048:        import org.ofbiz.entity.model.ModelField;
0049:        import org.ofbiz.entity.model.ModelFieldType;
0050:        import org.ofbiz.entity.model.ModelViewEntity;
0051:        import org.ofbiz.entity.model.ModelViewEntity.ModelAlias;
0052:
0053:        import org.ofbiz.entity.util.ByteWrapper;
0054:        import org.w3c.dom.Document;
0055:        import org.w3c.dom.Element;
0056:
0057:        /**
0058:         * Generic Entity Value Object - Handles persisntence for any defined entity.
0059:         * <p>Note that this class extends <code>Observable</code> to achieve change notification for
0060:         * <code>Observer</code>s. Whenever a field changes the name of the field will be passed to
0061:         * the <code>notifyObservers()</code> method, and through that to the <code>update()</code> method of each
0062:         * <code>Observer</code>.
0063:         *
0064:         */
0065:        public class GenericEntity extends Observable implements  Map,
0066:                LocalizedMap, Serializable, Comparable, Cloneable, Reusable {
0067:            public static final String module = GenericEntity.class.getName();
0068:            public static final GenericEntity NULL_ENTITY = new NullGenericEntity();
0069:            public static final NullField NULL_FIELD = new NullField();
0070:
0071:            /** Name of the GenericDelegator, used to reget the GenericDelegator when deserialized */
0072:            protected String delegatorName = null;
0073:
0074:            /** Reference to an instance of GenericDelegator used to do some basic operations on this entity value. If null various methods in this class will fail. This is automatically set by the GenericDelegator for all GenericValue objects instantiated through it. You may set this manually for objects you instantiate manually, but it is optional. */
0075:            protected transient GenericDelegator internalDelegator = null;
0076:
0077:            /** Contains the fields for this entity. Note that this should always be a
0078:             *  HashMap to allow for two things: non-synchronized reads (synchronized
0079:             *  writes are done through synchronized setters) and being able to store
0080:             *  null values. Null values are important because with them we can distinguish
0081:             *  between desiring to set a value to null and desiring to not modify the
0082:             *  current value on an update.
0083:             */
0084:            protected Map fields = FastMap.newInstance();
0085:
0086:            /** Contains the entityName of this entity, necessary for efficiency when creating EJBs */
0087:            protected String entityName = null;
0088:
0089:            /** Contains the ModelEntity instance that represents the definition of this entity, not to be serialized */
0090:            protected transient ModelEntity modelEntity = null;
0091:
0092:            /** Denotes whether or not this entity has been modified, or is known to be out of sync with the persistent record */
0093:            protected boolean modified = false;
0094:            protected boolean generateHashCode = true;
0095:            protected int cachedHashCode = 0;
0096:
0097:            /** Used to specify whether or not this representation of the entity can be changed; generally cleared when this object comes from a cache */
0098:            protected boolean mutable = true;
0099:
0100:            /** This is an internal field used to specify that a value has come from a sync process and that the auto-stamps should not be over-written */
0101:            protected boolean isFromEntitySync = false;
0102:
0103:            /** Creates new GenericEntity - Should never be used, prefer the other options. */
0104:            protected GenericEntity() {
0105:            }
0106:
0107:            /** Creates new GenericEntity */
0108:            public static GenericEntity createGenericEntity(
0109:                    ModelEntity modelEntity) {
0110:                if (modelEntity == null) {
0111:                    throw new IllegalArgumentException(
0112:                            "Cannot create a GenericEntity with a null modelEntity parameter");
0113:                }
0114:
0115:                GenericEntity newEntity = new GenericEntity();
0116:                newEntity.init(modelEntity);
0117:                return newEntity;
0118:            }
0119:
0120:            /** Creates new GenericEntity from existing Map */
0121:            public static GenericEntity createGenericEntity(
0122:                    ModelEntity modelEntity, Map fields) {
0123:                if (modelEntity == null) {
0124:                    throw new IllegalArgumentException(
0125:                            "Cannot create a GenericEntity with a null modelEntity parameter");
0126:                }
0127:
0128:                GenericEntity newEntity = new GenericEntity();
0129:                newEntity.init(modelEntity, fields);
0130:                return newEntity;
0131:            }
0132:
0133:            /** Copy Factory Method: Creates new GenericEntity from existing GenericEntity */
0134:            public static GenericEntity createGenericEntity(GenericEntity value) {
0135:                if (value == null) {
0136:                    throw new IllegalArgumentException(
0137:                            "Cannot create a GenericEntity with a null value parameter");
0138:                }
0139:
0140:                GenericEntity newEntity = new GenericEntity();
0141:                newEntity.init(value);
0142:                return newEntity;
0143:            }
0144:
0145:            /** Creates new GenericEntity */
0146:            protected void init(ModelEntity modelEntity) {
0147:                if (modelEntity == null) {
0148:                    throw new IllegalArgumentException(
0149:                            "Cannont create a GenericEntity with a null modelEntity parameter");
0150:                }
0151:                this .modelEntity = modelEntity;
0152:                this .entityName = modelEntity.getEntityName();
0153:
0154:                // check some things
0155:                if (this .entityName == null) {
0156:                    throw new IllegalArgumentException(
0157:                            "Cannont create a GenericEntity with a null entityName in the modelEntity parameter");
0158:                }
0159:            }
0160:
0161:            /** Creates new GenericEntity from existing Map */
0162:            protected void init(ModelEntity modelEntity, Map fields) {
0163:                if (modelEntity == null) {
0164:                    throw new IllegalArgumentException(
0165:                            "Cannont create a GenericEntity with a null modelEntity parameter");
0166:                }
0167:                this .modelEntity = modelEntity;
0168:                this .entityName = modelEntity.getEntityName();
0169:                setFields(fields);
0170:
0171:                // check some things
0172:                if (this .entityName == null) {
0173:                    throw new IllegalArgumentException(
0174:                            "Cannont create a GenericEntity with a null entityName in the modelEntity parameter");
0175:                }
0176:            }
0177:
0178:            /** Copy Constructor: Creates new GenericEntity from existing GenericEntity */
0179:            protected void init(GenericEntity value) {
0180:                if (value.modelEntity == null) {
0181:                    throw new IllegalArgumentException(
0182:                            "Cannont create a GenericEntity from another GenericEntity with a null modelEntity in the value parameter");
0183:                }
0184:                this .entityName = value.modelEntity.getEntityName();
0185:                this .modelEntity = value.modelEntity;
0186:                if (value.fields != null)
0187:                    this .fields.putAll(value.fields);
0188:                this .delegatorName = value.delegatorName;
0189:                this .internalDelegator = value.internalDelegator;
0190:
0191:                // check some things
0192:                if (this .entityName == null) {
0193:                    throw new IllegalArgumentException(
0194:                            "Cannont create a GenericEntity with a null entityName in the modelEntity parameter");
0195:                }
0196:            }
0197:
0198:            public void reset() {
0199:                // from GenericEntity
0200:                this .delegatorName = null;
0201:                this .internalDelegator = null;
0202:                this .fields = FastMap.newInstance();
0203:                this .entityName = null;
0204:                this .modelEntity = null;
0205:                this .modified = false;
0206:                this .generateHashCode = true;
0207:                this .cachedHashCode = 0;
0208:                this .mutable = true;
0209:                this .isFromEntitySync = false;
0210:            }
0211:
0212:            public void refreshFromValue(GenericEntity newValue)
0213:                    throws GenericEntityException {
0214:                if (newValue == null) {
0215:                    throw new GenericEntityException(
0216:                            "Could not refresh value, new value not found for: "
0217:                                    + this );
0218:                }
0219:                GenericPK this PK = this .getPrimaryKey();
0220:                GenericPK newPK = newValue.getPrimaryKey();
0221:                if (!this PK.equals(newPK)) {
0222:                    throw new GenericEntityException(
0223:                            "Could not refresh value, new value did not have the same primary key; this PK="
0224:                                    + this PK + ", new value PK=" + newPK);
0225:                }
0226:                this .fields = newValue.fields;
0227:                this .setDelegator(newValue.getDelegator());
0228:                this .generateHashCode = newValue.generateHashCode;
0229:                this .cachedHashCode = newValue.cachedHashCode;
0230:                this .modified = false;
0231:            }
0232:
0233:            public boolean isModified() {
0234:                return this .modified;
0235:            }
0236:
0237:            public void synchronizedWithDatasource() {
0238:                this .modified = false;
0239:            }
0240:
0241:            public void removedFromDatasource() {
0242:                // seems kind of minimal, but should do for now...
0243:                this .modified = true;
0244:            }
0245:
0246:            public boolean isMutable() {
0247:                return this .mutable;
0248:            }
0249:
0250:            public void setImmutable() {
0251:                this .mutable = false;
0252:            }
0253:
0254:            /**
0255:             * @return Returns the isFromEntitySync.
0256:             */
0257:            public boolean getIsFromEntitySync() {
0258:                return this .isFromEntitySync;
0259:            }
0260:
0261:            /**
0262:             * @param isFromEntitySync The isFromEntitySync to set.
0263:             */
0264:            public void setIsFromEntitySync(boolean isFromEntitySync) {
0265:                this .isFromEntitySync = isFromEntitySync;
0266:            }
0267:
0268:            public String getEntityName() {
0269:                return entityName;
0270:            }
0271:
0272:            public ModelEntity getModelEntity() {
0273:                if (modelEntity == null) {
0274:                    if (entityName != null)
0275:                        modelEntity = this .getDelegator().getModelEntity(
0276:                                entityName);
0277:                    if (modelEntity == null) {
0278:                        throw new IllegalStateException(
0279:                                "[GenericEntity.getModelEntity] could not find modelEntity for entityName "
0280:                                        + entityName);
0281:                    }
0282:                }
0283:                return modelEntity;
0284:            }
0285:
0286:            /** Get the GenericDelegator instance that created this value object and that is repsonsible for it.
0287:             *@return GenericDelegator object
0288:             */
0289:            public GenericDelegator getDelegator() {
0290:                if (internalDelegator == null) {
0291:                    if (delegatorName == null)
0292:                        delegatorName = "default";
0293:                    if (delegatorName != null)
0294:                        internalDelegator = GenericDelegator
0295:                                .getGenericDelegator(delegatorName);
0296:                    if (internalDelegator == null) {
0297:                        throw new IllegalStateException(
0298:                                "[GenericEntity.getDelegator] could not find delegator with name "
0299:                                        + delegatorName);
0300:                    }
0301:                }
0302:                return internalDelegator;
0303:            }
0304:
0305:            /** Set the GenericDelegator instance that created this value object and that is repsonsible for it. */
0306:            public void setDelegator(GenericDelegator internalDelegator) {
0307:                if (internalDelegator == null)
0308:                    return;
0309:                this .delegatorName = internalDelegator.getDelegatorName();
0310:                this .internalDelegator = internalDelegator;
0311:            }
0312:
0313:            public Object get(String name) {
0314:                if (getModelEntity().getField(name) == null) {
0315:                    throw new IllegalArgumentException("[GenericEntity.get] \""
0316:                            + name + "\" is not a field of " + entityName);
0317:                }
0318:                return fields.get(name);
0319:            }
0320:
0321:            /** Returns true if the entity contains all of the primary key fields, but NO others. */
0322:            public boolean isPrimaryKey() {
0323:                return isPrimaryKey(false);
0324:            }
0325:
0326:            public boolean isPrimaryKey(boolean requireValue) {
0327:                TreeSet fieldKeys = new TreeSet(this .fields.keySet());
0328:                Iterator pkIter = getModelEntity().getPksIterator();
0329:                while (pkIter.hasNext()) {
0330:                    ModelField curPk = (ModelField) pkIter.next();
0331:                    String fieldName = curPk.getName();
0332:                    if (requireValue) {
0333:                        if (this .fields.get(fieldName) == null)
0334:                            return false;
0335:                    } else {
0336:                        if (!this .fields.containsKey(fieldName))
0337:                            return false;
0338:                    }
0339:                    fieldKeys.remove(fieldName);
0340:                }
0341:                if (!fieldKeys.isEmpty())
0342:                    return false;
0343:                return true;
0344:            }
0345:
0346:            /** Returns true if the entity contains all of the primary key fields. */
0347:            public boolean containsPrimaryKey() {
0348:                return containsPrimaryKey(false);
0349:            }
0350:
0351:            public boolean containsPrimaryKey(boolean requireValue) {
0352:                //TreeSet fieldKeys = new TreeSet(fields.keySet());
0353:                Iterator pkIter = getModelEntity().getPksIterator();
0354:                while (pkIter.hasNext()) {
0355:                    ModelField curPk = (ModelField) pkIter.next();
0356:                    String fieldName = curPk.getName();
0357:                    if (requireValue) {
0358:                        if (this .fields.get(fieldName) == null)
0359:                            return false;
0360:                    } else {
0361:                        if (!this .fields.containsKey(fieldName))
0362:                            return false;
0363:                    }
0364:                }
0365:                return true;
0366:            }
0367:
0368:            /** Sets the named field to the passed value, even if the value is null
0369:             * @param name The field name to set
0370:             * @param value The value to set
0371:             */
0372:            public void set(String name, Object value) {
0373:                set(name, value, true);
0374:            }
0375:
0376:            /** Sets the named field to the passed value. If value is null, it is only
0377:             *  set if the setIfNull parameter is true. This is useful because an update
0378:             *  will only set values that are included in the HashMap and will store null
0379:             *  values in the HashMap to the datastore. If a value is not in the HashMap,
0380:             *  it will be left unmodified in the datastore.
0381:             * @param name The field name to set
0382:             * @param value The value to set
0383:             * @param setIfNull Specifies whether or not to set the value if it is null
0384:             */
0385:            public synchronized Object set(String name, Object value,
0386:                    boolean setIfNull) {
0387:                if (!this .mutable) {
0388:                    // comment this out to disable the mutable check
0389:                    throw new IllegalStateException(
0390:                            "This object has been flagged as immutable (unchangeable), probably because it came from an Entity Engine cache. Cannot set a value in an immutable entity object.");
0391:                }
0392:
0393:                ModelField modelField = getModelEntity().getField(name);
0394:                if (modelField == null) {
0395:                    throw new IllegalArgumentException("[GenericEntity.set] \""
0396:                            + name + "\" is not a field of " + entityName
0397:                            + ", must be one of: "
0398:                            + getModelEntity().fieldNameString());
0399:                }
0400:                if (value != null || setIfNull) {
0401:                    ModelFieldType type = null;
0402:                    try {
0403:                        type = getDelegator().getEntityFieldType(
0404:                                getModelEntity(), modelField.getType());
0405:                    } catch (GenericEntityException e) {
0406:                        Debug.logWarning(e, module);
0407:                    }
0408:                    if (type == null) {
0409:                        throw new IllegalArgumentException("Type "
0410:                                + modelField.getType() + " not found");
0411:                    }
0412:
0413:                    if (value instanceof  Boolean) {
0414:                        // if this is a Boolean check to see if we should convert from an indicator or just leave as is
0415:                        try {
0416:                            int fieldType = SqlJdbcUtil.getType(type
0417:                                    .getJavaType());
0418:                            if (fieldType != 9) {
0419:                                value = ((Boolean) value).booleanValue() ? "Y"
0420:                                        : "N";
0421:                            }
0422:                        } catch (GenericNotImplementedException e) {
0423:                            throw new IllegalArgumentException(e.getMessage());
0424:                        }
0425:                    } else if (value != null) {
0426:                        // make sure the type matches the field Java type
0427:                        if (!ObjectType.instanceOf(value, type.getJavaType())) {
0428:                            String errMsg = "In entity field ["
0429:                                    + this .getEntityName()
0430:                                    + "."
0431:                                    + name
0432:                                    + "] set the value passed in ["
0433:                                    + value.getClass().getName()
0434:                                    + "] is not compatible with the Java type of the field ["
0435:                                    + type.getJavaType() + "]";
0436:                            // eventually we should do this, but for now we'll do a "soft" failure: throw new IllegalArgumentException(errMsg);
0437:                            Debug.logWarning(errMsg, module);
0438:                        }
0439:                    }
0440:                    Object old = fields.put(name, value);
0441:
0442:                    generateHashCode = true;
0443:                    modified = true;
0444:                    this .setChanged();
0445:                    this .notifyObservers(name);
0446:                    return old;
0447:                } else {
0448:                    return fields.get(name);
0449:                }
0450:            }
0451:
0452:            public void dangerousSetNoCheckButFast(ModelField modelField,
0453:                    Object value) {
0454:                if (modelField == null)
0455:                    throw new IllegalArgumentException(
0456:                            "Cannot set field with a null modelField");
0457:                generateHashCode = true;
0458:                this .fields.put(modelField.getName(), value);
0459:            }
0460:
0461:            public Object dangerousGetNoCheckButFast(ModelField modelField) {
0462:                if (modelField == null)
0463:                    throw new IllegalArgumentException(
0464:                            "Cannot get field with a null modelField");
0465:                return this .fields.get(modelField.getName());
0466:            }
0467:
0468:            /** Sets the named field to the passed value, converting the value from a String to the corrent type using <code>Type.valueOf()</code>
0469:             * @param name The field name to set
0470:             * @param value The String value to convert and set
0471:             */
0472:            public void setString(String name, String value) {
0473:                if (value == null) {
0474:                    set(name, null);
0475:                    return;
0476:                }
0477:
0478:                boolean isNullString = false;
0479:                if ("null".equals(value)) {
0480:                    // count this as a null too, but only for numbers and stuff, not for Strings
0481:                    isNullString = true;
0482:                }
0483:
0484:                ModelField field = getModelEntity().getField(name);
0485:                if (field == null)
0486:                    set(name, value); // this will get an error in the set() method...
0487:
0488:                ModelFieldType type = null;
0489:                try {
0490:                    type = getDelegator().getEntityFieldType(getModelEntity(),
0491:                            field.getType());
0492:                } catch (GenericEntityException e) {
0493:                    Debug.logWarning(e, module);
0494:                }
0495:                if (type == null)
0496:                    throw new IllegalArgumentException("Type "
0497:                            + field.getType() + " not found");
0498:                String fieldType = type.getJavaType();
0499:
0500:                try {
0501:                    switch (SqlJdbcUtil.getType(fieldType)) {
0502:                    case 1:
0503:                        set(name, value);
0504:                        break;
0505:
0506:                    case 2:
0507:                        set(name, isNullString ? null : java.sql.Timestamp
0508:                                .valueOf(value));
0509:                        break;
0510:
0511:                    case 3:
0512:                        set(name, isNullString ? null : java.sql.Time
0513:                                .valueOf(value));
0514:                        break;
0515:
0516:                    case 4:
0517:                        set(name, isNullString ? null : java.sql.Date
0518:                                .valueOf(value));
0519:                        break;
0520:
0521:                    case 5:
0522:                        set(name, isNullString ? null : Integer.valueOf(value));
0523:                        break;
0524:
0525:                    case 6:
0526:                        set(name, isNullString ? null : Long.valueOf(value));
0527:                        break;
0528:
0529:                    case 7:
0530:                        set(name, isNullString ? null : Float.valueOf(value));
0531:                        break;
0532:
0533:                    case 8:
0534:                        set(name, isNullString ? null : Double.valueOf(value));
0535:                        break;
0536:
0537:                    case 9:
0538:                        set(name, isNullString ? null : Boolean.valueOf(value));
0539:                        break;
0540:
0541:                    case 10: // BigDecimal
0542:                        set(name, isNullString ? null : new BigDecimal(value));
0543:                        break;
0544:
0545:                    case 11: // Object
0546:                        set(name, value);
0547:                        break;
0548:
0549:                    case 12: // java.sql.Blob
0550:                        // TODO: any better way to handle Blob from String?
0551:                        set(name, value);
0552:                        break;
0553:
0554:                    case 13: // java.sql.Clob
0555:                        // TODO: any better way to handle Clob from String?
0556:                        set(name, value);
0557:                        break;
0558:
0559:                    case 14: // java.util.Date
0560:                        set(name, UtilDateTime.toDate(value));
0561:                        break;
0562:
0563:                    case 15: // java.util.Collection
0564:                        // TODO: how to convert from String to Collection? ie what should the default behavior be?
0565:                        set(name, value);
0566:                        break;
0567:                    }
0568:                } catch (GenericNotImplementedException ex) {
0569:                    throw new IllegalArgumentException(ex.getMessage());
0570:                }
0571:            }
0572:
0573:            /** Sets a field with an array of bytes, wrapping them automatically for easy use.
0574:             * @param name The field name to set
0575:             * @param bytes The byte array to be wrapped and set
0576:             */
0577:            public void setBytes(String name, byte[] bytes) {
0578:                this .set(name, new ByteWrapper(bytes));
0579:            }
0580:
0581:            public Boolean getBoolean(String name) {
0582:                Object obj = get(name);
0583:
0584:                if (obj == null) {
0585:                    return null;
0586:                }
0587:                if (obj instanceof  Boolean) {
0588:                    return (Boolean) obj;
0589:                } else if (obj instanceof  String) {
0590:                    String value = (String) obj;
0591:
0592:                    if ("Y".equalsIgnoreCase(value)
0593:                            || "T".equalsIgnoreCase(value)) {
0594:                        return Boolean.TRUE;
0595:                    } else if ("N".equalsIgnoreCase(value)
0596:                            || "F".equalsIgnoreCase(value)) {
0597:                        return Boolean.FALSE;
0598:                    } else {
0599:                        throw new IllegalArgumentException(
0600:                                "getBoolean could not map the String '" + value
0601:                                        + "' to Boolean type");
0602:                    }
0603:                } else {
0604:                    throw new IllegalArgumentException(
0605:                            "getBoolean could not map the object '"
0606:                                    + obj.toString()
0607:                                    + "' to Boolean type, unknown object type: "
0608:                                    + obj.getClass().getName());
0609:                }
0610:            }
0611:
0612:            public String getString(String name) {
0613:                // might be nice to add some ClassCastException handling... and auto conversion? hmmm...
0614:                Object object = get(name);
0615:                if (object == null)
0616:                    return null;
0617:                if (object instanceof  java.lang.String) {
0618:                    return (String) object;
0619:                } else {
0620:                    return object.toString();
0621:                }
0622:            }
0623:
0624:            public java.sql.Timestamp getTimestamp(String name) {
0625:                return (java.sql.Timestamp) get(name);
0626:            }
0627:
0628:            public java.sql.Time getTime(String name) {
0629:                return (java.sql.Time) get(name);
0630:            }
0631:
0632:            public java.sql.Date getDate(String name) {
0633:                return (java.sql.Date) get(name);
0634:            }
0635:
0636:            public Integer getInteger(String name) {
0637:                return (Integer) get(name);
0638:            }
0639:
0640:            public Long getLong(String name) {
0641:                return (Long) get(name);
0642:            }
0643:
0644:            public Float getFloat(String name) {
0645:                return (Float) get(name);
0646:            }
0647:
0648:            public Double getDouble(String name) {
0649:                // this "hack" is needed for now until the Double/BigDecimal issues are all resolved
0650:                Object value = get(name);
0651:                if (value instanceof  BigDecimal) {
0652:                    return new Double(((BigDecimal) value).doubleValue());
0653:                } else {
0654:                    return (Double) get(name);
0655:                }
0656:            }
0657:
0658:            public BigDecimal getBigDecimal(String name) {
0659:                // this "hack" is needed for now until the Double/BigDecimal issues are all resolved
0660:                // NOTE: for this to be used properly it should really be used as the java-type in the field type def XML files
0661:                Object value = get(name);
0662:                if (value instanceof  Double) {
0663:                    return new BigDecimal(((Double) value).toString());
0664:                } else {
0665:                    return (BigDecimal) value;
0666:                }
0667:            }
0668:
0669:            public byte[] getBytes(String name) {
0670:                Object value = get(name);
0671:                if (value == null) {
0672:                    return null;
0673:                }
0674:                if (value instanceof  ByteWrapper) {
0675:                    ByteWrapper wrapper = (ByteWrapper) value;
0676:                    return wrapper.getBytes();
0677:                }
0678:                if (value instanceof  byte[]) {
0679:                    return (byte[]) value;
0680:                }
0681:                // uh-oh, this shouldn't happen...
0682:                throw new IllegalArgumentException(
0683:                        "In call to getBytes the value is not a supported type, should be byte[] or ByteWrapper, is: "
0684:                                + value.getClass().getName());
0685:            }
0686:
0687:            /** Checks a resource bundle for a value for this field using the entity name, the field name
0688:             *    and a composite of the Primary Key field values as a key. If no value is found in the
0689:             *    resource then the field value is returned. Uses the default-resource-name from the entity
0690:             *    definition as the resource name. To specify a resource name manually, use the other getResource method.
0691:             *
0692:             *  So, the key in the resource bundle (properties file) should be as follows:
0693:             *    <entity-name>.<field-name>.<pk-field-value-1>.<pk-field-value-2>...<pk-field-value-n>
0694:             *  For example:
0695:             *    ProductType.description.FINISHED_GOOD
0696:             *
0697:             * @param name The name of the field on the entity
0698:             * @param locale The locale to use when finding the ResourceBundle, if null uses the default
0699:             *    locale for the current instance of Java
0700:             * @return If the corresponding resource is found and contains a key as described above, then that
0701:             *    property value is returned; otherwise returns the field value
0702:             */
0703:            public Object get(String name, Locale locale) {
0704:                return get(name, null, locale);
0705:            }
0706:
0707:            /** Same as the getResource method that does not take resource name, but instead allows manually
0708:             *    specifying the resource name. In general you should use the other method for more consistent
0709:             *    naming and use of the corresponding properties files.
0710:             * @param name The name of the field on the entity
0711:             * @param resource The name of the resource to get the value from; if null defaults to the
0712:             *    default-resource-name on the entity definition, if specified there
0713:             * @param locale The locale to use when finding the ResourceBundle, if null uses the default
0714:             *    locale for the current instance of Java
0715:             * @return If the specified resource is found and contains a key as described above, then that
0716:             *    property value is returned; otherwise returns the field value
0717:             */
0718:            public Object get(String name, String resource, Locale locale) {
0719:                Object fieldValue = null;
0720:                try {
0721:                    fieldValue = get(name);
0722:                } catch (IllegalArgumentException e) {
0723:                    if (Debug.verboseOn()) {
0724:                        Debug
0725:                                .logVerbose(
0726:                                        e,
0727:                                        "The field name (or key) ["
0728:                                                + name
0729:                                                + "] is not valid for entity ["
0730:                                                + this .getEntityName()
0731:                                                + "], printing IllegalArgumentException instead of throwing it because Map interface specification does not allow throwing that exception.",
0732:                                        module);
0733:                    } else {
0734:                        Debug
0735:                                .logWarning(
0736:                                        "The field name (or key) ["
0737:                                                + name
0738:                                                + "] is not valid for entity ["
0739:                                                + this .getEntityName()
0740:                                                + "], printing IllegalArgumentException instead of throwing it because Map interface specification does not allow throwing that exception.",
0741:                                        module);
0742:                    }
0743:                    fieldValue = null;
0744:                }
0745:
0746:                // In case of view entity try to retrieve the field heading from the real entity linked to the view
0747:                ModelEntity modelEntityToUse = this .getModelEntity();
0748:                if (modelEntityToUse instanceof  ModelViewEntity) {
0749:                    ModelViewEntity modelViewEntity = (ModelViewEntity) modelEntityToUse;
0750:                    Iterator it = modelViewEntity.getAliasesIterator();
0751:                    while (it.hasNext()) {
0752:                        ModelAlias modelAlias = (ModelAlias) it.next();
0753:                        if (modelAlias.getName().equalsIgnoreCase(name)) {
0754:                            modelEntityToUse = modelViewEntity
0755:                                    .getMemberModelEntity(modelAlias
0756:                                            .getEntityAlias());
0757:                            name = modelAlias.getField();
0758:                            break;
0759:                        }
0760:                    }
0761:                }
0762:                if (UtilValidate.isEmpty(resource)) {
0763:                    resource = modelEntityToUse.getDefaultResourceName();
0764:                    // still empty? return the fieldValue
0765:                    if (UtilValidate.isEmpty(resource)) {
0766:                        //Debug.logWarning("Tried to getResource value for field named " + name + " but no resource name was passed to the method or specified in the default-resource-name attribute of the entity definition", module);
0767:                        return fieldValue;
0768:                    }
0769:                }
0770:                ResourceBundle bundle = null;
0771:                try {
0772:                    bundle = UtilProperties.getResourceBundle(resource, locale);
0773:                } catch (IllegalArgumentException e) {
0774:                    bundle = null;
0775:                }
0776:                if (bundle == null) {
0777:                    //Debug.logWarning("Tried to getResource value for field named " + name + " but no resource was found with the name " + resource + " in the locale " + locale, module);
0778:                    return fieldValue;
0779:                }
0780:
0781:                StringBuffer keyBuffer = new StringBuffer();
0782:                // start with the Entity Name
0783:                keyBuffer.append(modelEntityToUse.getEntityName());
0784:                // next add the Field Name
0785:                keyBuffer.append('.');
0786:                keyBuffer.append(name);
0787:                // finish off by adding the values of all PK fields
0788:                Iterator iter = modelEntityToUse.getPksIterator();
0789:                while (iter != null && iter.hasNext()) {
0790:                    ModelField curField = (ModelField) iter.next();
0791:                    keyBuffer.append('.');
0792:                    keyBuffer.append(this .get(curField.getName()));
0793:                }
0794:
0795:                String bundleKey = keyBuffer.toString();
0796:
0797:                Object resourceValue = null;
0798:                try {
0799:                    resourceValue = bundle.getObject(bundleKey);
0800:                } catch (MissingResourceException e) {
0801:                    return fieldValue;
0802:                }
0803:                if (resourceValue == null) {
0804:                    return fieldValue;
0805:                } else {
0806:                    return resourceValue;
0807:                }
0808:            }
0809:
0810:            public GenericPK getPrimaryKey() {
0811:                Collection pkNames = FastList.newInstance();
0812:                Iterator iter = this .getModelEntity().getPksIterator();
0813:                while (iter != null && iter.hasNext()) {
0814:                    ModelField curField = (ModelField) iter.next();
0815:                    pkNames.add(curField.getName());
0816:                }
0817:                GenericPK newPK = GenericPK.create(getModelEntity(), this 
0818:                        .getFields(pkNames));
0819:                newPK.setDelegator(this .getDelegator());
0820:                return newPK;
0821:            }
0822:
0823:            /** go through the pks and for each one see if there is an entry in fields to set */
0824:            public void setPKFields(Map fields) {
0825:                setAllFields(fields, true, null, Boolean.TRUE);
0826:            }
0827:
0828:            /** go through the pks and for each one see if there is an entry in fields to set */
0829:            public void setPKFields(Map fields, boolean setIfEmpty) {
0830:                setAllFields(fields, setIfEmpty, null, Boolean.TRUE);
0831:            }
0832:
0833:            /** go through the non-pks and for each one see if there is an entry in fields to set */
0834:            public void setNonPKFields(Map fields) {
0835:                setAllFields(fields, true, null, Boolean.FALSE);
0836:            }
0837:
0838:            /** go through the non-pks and for each one see if there is an entry in fields to set */
0839:            public void setNonPKFields(Map fields, boolean setIfEmpty) {
0840:                setAllFields(fields, setIfEmpty, null, Boolean.FALSE);
0841:            }
0842:
0843:            /** Intelligently sets fields on this entity from the Map of fields passed in
0844:             * @param fields The fields Map to get the values from
0845:             * @param setIfEmpty Used to specify whether empty/null values in the field Map should over-write non-empty values in this entity
0846:             * @param namePrefix If not null or empty will be pre-pended to each field name (upper-casing the first letter of the field name first), and that will be used as the fields Map lookup name instead of the field-name
0847:             * @param pks If null, get all values, if TRUE just get PKs, if FALSE just get non-PKs
0848:             */
0849:            public void setAllFields(Map fields, boolean setIfEmpty,
0850:                    String namePrefix, Boolean pks) {
0851:                if (fields == null) {
0852:                    return;
0853:                }
0854:                Iterator iter = null;
0855:                if (pks != null) {
0856:                    if (pks.booleanValue()) {
0857:                        iter = this .getModelEntity().getPksIterator();
0858:                    } else {
0859:                        iter = this .getModelEntity().getNopksIterator();
0860:                    }
0861:                } else {
0862:                    iter = this .getModelEntity().getFieldsIterator();
0863:                }
0864:
0865:                while (iter != null && iter.hasNext()) {
0866:                    ModelField curField = (ModelField) iter.next();
0867:                    String fieldName = curField.getName();
0868:                    String sourceFieldName = null;
0869:                    if (UtilValidate.isNotEmpty(namePrefix)) {
0870:                        sourceFieldName = namePrefix
0871:                                + Character.toUpperCase(fieldName.charAt(0))
0872:                                + fieldName.substring(1);
0873:                    } else {
0874:                        sourceFieldName = curField.getName();
0875:                    }
0876:
0877:                    if (fields.containsKey(sourceFieldName)) {
0878:                        Object field = fields.get(sourceFieldName);
0879:
0880:                        // if (Debug.verboseOn()) Debug.logVerbose("Setting field " + curField.getName() + ": " + field + ", setIfEmpty = " + setIfEmpty, module);
0881:                        if (setIfEmpty) {
0882:                            // if empty string, set to null
0883:                            if (field != null && field instanceof  String
0884:                                    && ((String) field).length() == 0) {
0885:                                this .set(curField.getName(), null);
0886:                            } else {
0887:                                this .set(curField.getName(), field);
0888:                            }
0889:                        } else {
0890:                            // okay, only set if not empty...
0891:                            if (field != null) {
0892:                                // if it's a String then we need to check length, otherwise set it because it's not null
0893:                                if (field instanceof  String) {
0894:                                    String fieldStr = (String) field;
0895:
0896:                                    if (fieldStr.length() > 0) {
0897:                                        this .set(curField.getName(), field);
0898:                                    }
0899:                                } else {
0900:                                    this .set(curField.getName(), field);
0901:                                }
0902:                            }
0903:                        }
0904:                    }
0905:                }
0906:            }
0907:
0908:            /** Returns keys of entity fields
0909:             * @return java.util.Collection
0910:             */
0911:            public Collection getAllKeys() {
0912:                return fields.keySet();
0913:            }
0914:
0915:            /** Returns key/value pairs of entity fields
0916:             * @return java.util.Map
0917:             */
0918:            public Map getAllFields() {
0919:                Map newMap = FastMap.newInstance();
0920:                newMap.putAll(this .fields);
0921:                return newMap;
0922:            }
0923:
0924:            /** Used by clients to specify exactly the fields they are interested in
0925:             * @param keysofFields the name of the fields the client is interested in
0926:             * @return java.util.Map
0927:             */
0928:            public Map getFields(Collection keysofFields) {
0929:                if (keysofFields == null)
0930:                    return null;
0931:                Iterator keys = keysofFields.iterator();
0932:                Object aKey = null;
0933:                Map aMap = FastMap.newInstance();
0934:
0935:                while (keys.hasNext()) {
0936:                    aKey = keys.next();
0937:                    aMap.put(aKey, this .fields.get(aKey));
0938:                }
0939:                return aMap;
0940:            }
0941:
0942:            /** Used by clients to update particular fields in the entity
0943:             * @param keyValuePairs java.util.Map
0944:             */
0945:            public synchronized void setFields(Map keyValuePairs) {
0946:                if (keyValuePairs == null)
0947:                    return;
0948:                Iterator entries = keyValuePairs.entrySet().iterator();
0949:                Map.Entry anEntry = null;
0950:
0951:                // this could be implement with Map.putAll, but we'll leave it like this for the extra features it has
0952:                while (entries.hasNext()) {
0953:                    anEntry = (Map.Entry) entries.next();
0954:                    this .set((String) anEntry.getKey(), anEntry.getValue(),
0955:                            true);
0956:                }
0957:            }
0958:
0959:            public boolean matchesFields(Map keyValuePairs) {
0960:                if (fields == null)
0961:                    return true;
0962:                if (keyValuePairs == null || keyValuePairs.size() == 0)
0963:                    return true;
0964:                Iterator entries = keyValuePairs.entrySet().iterator();
0965:
0966:                while (entries.hasNext()) {
0967:                    Map.Entry anEntry = (Map.Entry) entries.next();
0968:
0969:                    if (!UtilValidate.areEqual(anEntry.getValue(), this .fields
0970:                            .get(anEntry.getKey()))) {
0971:                        return false;
0972:                    }
0973:                }
0974:                return true;
0975:            }
0976:
0977:            /** Used to indicate if locking is enabled for this entity
0978:             * @return True if locking is enabled
0979:             */
0980:            public boolean lockEnabled() {
0981:                return getModelEntity().lock();
0982:            }
0983:
0984:            // ======= XML Related Methods ========
0985:            public static Document makeXmlDocument(Collection values) {
0986:                Document document = UtilXml
0987:                        .makeEmptyXmlDocument("entity-engine-xml");
0988:
0989:                if (document == null)
0990:                    return null;
0991:
0992:                addToXmlDocument(values, document);
0993:                return document;
0994:            }
0995:
0996:            public static int addToXmlDocument(Collection values,
0997:                    Document document) {
0998:                return addToXmlElement(values, document, document
0999:                        .getDocumentElement());
1000:            }
1001:
1002:            public static int addToXmlElement(Collection values,
1003:                    Document document, Element element) {
1004:                if (values == null)
1005:                    return 0;
1006:                if (document == null)
1007:                    return 0;
1008:
1009:                Iterator iter = values.iterator();
1010:                int numberAdded = 0;
1011:
1012:                while (iter.hasNext()) {
1013:                    GenericValue value = (GenericValue) iter.next();
1014:                    Element valueElement = value.makeXmlElement(document);
1015:
1016:                    element.appendChild(valueElement);
1017:                    numberAdded++;
1018:                }
1019:                return numberAdded;
1020:            }
1021:
1022:            /** Makes an XML Element object with an attribute for each field of the entity
1023:             *@param document The XML Document that the new Element will be part of
1024:             *@return org.w3c.dom.Element object representing this generic entity
1025:             */
1026:            public Element makeXmlElement(Document document) {
1027:                return makeXmlElement(document, null);
1028:            }
1029:
1030:            /** Makes an XML Element object with an attribute for each field of the entity
1031:             *@param document The XML Document that the new Element will be part of
1032:             *@param prefix A prefix to put in front of the entity name in the tag name
1033:             *@return org.w3c.dom.Element object representing this generic entity
1034:             */
1035:            public Element makeXmlElement(Document document, String prefix) {
1036:                Element element = null;
1037:
1038:                if (prefix == null)
1039:                    prefix = "";
1040:                if (document != null)
1041:                    element = document.createElement(prefix
1042:                            + this .getEntityName());
1043:                // else element = new ElementImpl(null, this.getEntityName());
1044:                if (element == null)
1045:                    return null;
1046:
1047:                Iterator modelFields = this .getModelEntity()
1048:                        .getFieldsIterator();
1049:                while (modelFields.hasNext()) {
1050:                    ModelField modelField = (ModelField) modelFields.next();
1051:                    String name = modelField.getName();
1052:                    String value = this .getString(name);
1053:
1054:                    if (value != null) {
1055:                        if (value.indexOf('\n') >= 0
1056:                                || value.indexOf('\r') >= 0) {
1057:                            UtilXml.addChildElementCDATAValue(element, name,
1058:                                    value, document);
1059:                        } else {
1060:                            element.setAttribute(name, value);
1061:                        }
1062:                    }
1063:                }
1064:
1065:                return element;
1066:            }
1067:
1068:            /** Writes XML text with an attribute or CDATA element for each field of the entity
1069:             *@param writer A PrintWriter to write to
1070:             *@param prefix A prefix to put in front of the entity name in the tag name
1071:             */
1072:            public void writeXmlText(PrintWriter writer, String prefix) {
1073:                final int indent = 4;
1074:
1075:                if (prefix == null)
1076:                    prefix = "";
1077:
1078:                for (int i = 0; i < indent; i++)
1079:                    writer.print(' ');
1080:                writer.print('<');
1081:                writer.print(prefix);
1082:                writer.print(this .getEntityName());
1083:
1084:                // write attributes immediately and if a CDATA element is needed, put those in a Map for now
1085:                Map cdataMap = FastMap.newInstance();
1086:
1087:                Iterator modelFields = this .getModelEntity()
1088:                        .getFieldsIterator();
1089:                while (modelFields.hasNext()) {
1090:                    ModelField modelField = (ModelField) modelFields.next();
1091:                    String name = modelField.getName();
1092:
1093:                    String type = modelField.getType();
1094:                    if (type != null && type.equals("blob")) {
1095:                        Object obj = get(name);
1096:                        boolean b1 = obj instanceof  byte[];
1097:                        if (b1) {
1098:                            byte[] binData = (byte[]) obj;
1099:                            String strData = new String(Base64
1100:                                    .base64Encode(binData));
1101:                            cdataMap.put(name, strData);
1102:                        } else {
1103:                            Debug.logWarning("Field:" + name
1104:                                    + " is not of type 'byte[]'. obj: " + obj,
1105:                                    module);
1106:                        }
1107:                    } else {
1108:                        String valueStr = this .getString(name);
1109:
1110:                        if (valueStr != null) {
1111:                            StringBuffer value = new StringBuffer(valueStr);
1112:                            boolean needsCdata = false;
1113:
1114:                            // check each character, if line-feed or carriage-return is found set needsCdata to true; also look for invalid characters
1115:                            for (int i = 0; i < value.length(); i++) {
1116:                                char curChar = value.charAt(i);
1117:                                /* Some common character for these invalid values, have seen these are mostly from MS Word, but may be part of some standard:
1118:                                 5 = ...
1119:                                 18 = apostrophe
1120:                                 19 = left quotation mark
1121:                                 20 = right quotation mark
1122:                                 22 = –
1123:                                 23 = -
1124:                                 25 = tm
1125:                                 * 
1126:                                 */
1127:
1128:                                switch (curChar) {
1129:                                case '\'':
1130:                                    value.replace(i, i + 1, "&apos;");
1131:                                    break;
1132:                                case '"':
1133:                                    value.replace(i, i + 1, "&quot;");
1134:                                    break;
1135:                                case '&':
1136:                                    value.replace(i, i + 1, "&amp;");
1137:                                    break;
1138:                                case '<':
1139:                                    value.replace(i, i + 1, "&lt;");
1140:                                    break;
1141:                                case '>':
1142:                                    value.replace(i, i + 1, "&gt;");
1143:                                    break;
1144:                                case 0xA: // newline, \n
1145:                                    needsCdata = true;
1146:                                    break;
1147:                                case 0xD: // carriage return, \r
1148:                                    needsCdata = true;
1149:                                    break;
1150:                                case 0x9: // tab
1151:                                    // do nothing, just catch here so it doesn't get into the default
1152:                                    break;
1153:                                case 0x5: // elipses (...)
1154:                                    value.replace(i, i + 1, "...");
1155:                                    break;
1156:                                case 0x12: // apostrophe
1157:                                    value.replace(i, i + 1, "&apos;");
1158:                                    break;
1159:                                case 0x13: // left quote
1160:                                    value.replace(i, i + 1, "&quot;");
1161:                                    break;
1162:                                case 0x14: // right quote
1163:                                    value.replace(i, i + 1, "&quot;");
1164:                                    break;
1165:                                case 0x16: // big(?) dash -
1166:                                    value.replace(i, i + 1, "-");
1167:                                    break;
1168:                                case 0x17: // dash -
1169:                                    value.replace(i, i + 1, "-");
1170:                                    break;
1171:                                case 0x19: // tm
1172:                                    value.replace(i, i + 1, "tm");
1173:                                    break;
1174:                                default:
1175:                                    if (curChar < 0x20) {
1176:                                        // if it is less that 0x20 at this point it is invalid because the only valid values < 0x20 are 0x9, 0xA, 0xD as caught above
1177:                                        Debug
1178:                                                .logInfo(
1179:                                                        "Removing invalid character ["
1180:                                                                + curChar
1181:                                                                + "] numeric value ["
1182:                                                                + (int) curChar
1183:                                                                + "] for field "
1184:                                                                + name
1185:                                                                + " of entity with PK: "
1186:                                                                + this 
1187:                                                                        .getPrimaryKey()
1188:                                                                        .toString(),
1189:                                                        module);
1190:                                        value.deleteCharAt(i);
1191:                                    } else if (curChar > 0x7F) {
1192:                                        // Replace each char which is out of the ASCII range with a XML entity
1193:                                        String replacement = "&#"
1194:                                                + (int) curChar + ";";
1195:                                        if (Debug.verboseOn()) {
1196:                                            Debug
1197:                                                    .logVerbose(
1198:                                                            "Entity: "
1199:                                                                    + this 
1200:                                                                            .getEntityName()
1201:                                                                    + ", PK: "
1202:                                                                    + this 
1203:                                                                            .getPrimaryKey()
1204:                                                                            .toString()
1205:                                                                    + " -> char ["
1206:                                                                    + curChar
1207:                                                                    + "] replaced with ["
1208:                                                                    + replacement
1209:                                                                    + "]",
1210:                                                            module);
1211:                                        }
1212:                                        value.replace(i, i + 1, replacement);
1213:                                    }
1214:                                }
1215:                            }
1216:
1217:                            if (needsCdata) {
1218:                                // use valueStr instead of the escaped value, not needed or wanted in a CDATA block
1219:                                cdataMap.put(name, valueStr);
1220:                            } else {
1221:                                writer.print(' ');
1222:                                writer.print(name);
1223:                                writer.print("=\"");
1224:                                // encode the value...
1225:                                writer.print(value.toString());
1226:                                writer.print("\"");
1227:                            }
1228:                        }
1229:                    }
1230:                }
1231:
1232:                if (cdataMap.size() == 0) {
1233:                    writer.println("/>");
1234:                } else {
1235:                    writer.println('>');
1236:
1237:                    Iterator cdataIter = cdataMap.entrySet().iterator();
1238:
1239:                    while (cdataIter.hasNext()) {
1240:                        Map.Entry entry = (Map.Entry) cdataIter.next();
1241:
1242:                        for (int i = 0; i < (indent << 1); i++)
1243:                            writer.print(' ');
1244:                        writer.print('<');
1245:                        writer.print((String) entry.getKey());
1246:                        writer.print("><![CDATA[");
1247:                        writer.print((String) entry.getValue());
1248:                        writer.print("]]></");
1249:                        writer.print((String) entry.getKey());
1250:                        writer.println('>');
1251:                    }
1252:
1253:                    // don't forget to close the entity.
1254:                    for (int i = 0; i < indent; i++)
1255:                        writer.print(' ');
1256:                    writer.print("</");
1257:                    writer.print(this .getEntityName());
1258:                    writer.println(">");
1259:                }
1260:            }
1261:
1262:            /** Determines the equality of two GenericEntity objects, overrides the default equals
1263:             *@param  obj  The object (GenericEntity) to compare this two
1264:             *@return      boolean stating if the two objects are equal
1265:             */
1266:            public boolean equals(Object obj) {
1267:                if (obj == null)
1268:                    return false;
1269:
1270:                // from here, use the compareTo method since it is more efficient:
1271:                try {
1272:                    return this .compareTo(obj) == 0;
1273:                } catch (ClassCastException e) {
1274:                    return false;
1275:                }
1276:            }
1277:
1278:            /** Creates a hashCode for the entity, using the default String hashCode and Map hashCode, overrides the default hashCode
1279:             *@return    Hashcode corresponding to this entity
1280:             */
1281:            public int hashCode() {
1282:                // divide both by two (shift to right one bit) to maintain scale and add together
1283:                if (generateHashCode) {
1284:                    cachedHashCode = 0;
1285:                    if (getEntityName() != null) {
1286:                        cachedHashCode += getEntityName().hashCode() >> 1;
1287:                    }
1288:                    cachedHashCode += fields.hashCode() >> 1;
1289:                    generateHashCode = false;
1290:                }
1291:                return cachedHashCode;
1292:            }
1293:
1294:            /** Creates a String for the entity, overrides the default toString
1295:             *@return    String corresponding to this entity
1296:             */
1297:            public String toString() {
1298:                StringBuffer theString = new StringBuffer();
1299:
1300:                theString.append("[GenericEntity:");
1301:                theString.append(getEntityName());
1302:                theString.append(']');
1303:
1304:                Iterator keyNames = new TreeSet(fields.keySet()).iterator();
1305:                while (keyNames.hasNext()) {
1306:                    String curKey = (String) keyNames.next();
1307:                    Object curValue = fields.get(curKey);
1308:                    theString.append('[');
1309:                    theString.append(curKey);
1310:                    theString.append(',');
1311:                    theString.append(curValue);
1312:                    theString.append('(');
1313:                    theString.append(curValue != null ? curValue.getClass()
1314:                            .getName() : "");
1315:                    theString.append(')');
1316:                    theString.append(']');
1317:                }
1318:                return theString.toString();
1319:            }
1320:
1321:            /** Compares this GenericEntity to the passed object
1322:             *@param obj Object to compare this to
1323:             *@return int representing the result of the comparison (-1,0, or 1)
1324:             */
1325:            public int compareTo(Object obj) {
1326:                // if null, it will push to the beginning
1327:                if (obj == null)
1328:                    return -1;
1329:
1330:                // rather than doing an if instanceof, just cast it and let it throw an exception if
1331:                // it fails, this will be faster for the expected case (that it IS a GenericEntity)
1332:                // if not a GenericEntity throw ClassCastException, as the spec says
1333:                GenericEntity that = (GenericEntity) obj;
1334:
1335:                int tempResult = this .entityName.compareTo(that.entityName);
1336:
1337:                // if they did not match, we know the order, otherwise compare the primary keys
1338:                if (tempResult != 0)
1339:                    return tempResult;
1340:
1341:                // both have same entityName, should be the same so let's compare PKs
1342:                Iterator pkIter = getModelEntity().getPksIterator();
1343:                while (pkIter.hasNext()) {
1344:                    ModelField curField = (ModelField) pkIter.next();
1345:                    Comparable this Val = (Comparable) this .fields.get(curField
1346:                            .getName());
1347:                    Comparable thatVal = (Comparable) that.fields.get(curField
1348:                            .getName());
1349:
1350:                    if (this Val == null) {
1351:                        if (thatVal == null)
1352:                            tempResult = 0;
1353:                        // if thisVal is null, but thatVal is not, return 1 to put this earlier in the list
1354:                        else
1355:                            tempResult = 1;
1356:                    } else {
1357:                        // if thatVal is null, put the other earlier in the list
1358:                        if (thatVal == null)
1359:                            tempResult = -1;
1360:                        else
1361:                            tempResult = this Val.compareTo(thatVal);
1362:                    }
1363:                    if (tempResult != 0)
1364:                        return tempResult;
1365:                }
1366:
1367:                // okay, if we got here it means the primaryKeys are exactly the SAME, so compare the rest of the fields
1368:                Iterator nopkIter = getModelEntity().getNopksIterator();
1369:                while (nopkIter.hasNext()) {
1370:                    ModelField curField = (ModelField) nopkIter.next();
1371:                    if (!curField.getIsAutoCreatedInternal()) {
1372:                        Comparable this Val = (Comparable) this .fields
1373:                                .get(curField.getName());
1374:                        Comparable thatVal = (Comparable) that.fields
1375:                                .get(curField.getName());
1376:
1377:                        if (this Val == null) {
1378:                            if (thatVal == null) {
1379:                                tempResult = 0;
1380:                                // if thisVal is null, but thatVal is not, return 1 to put this earlier in the list
1381:                            } else {
1382:                                tempResult = 1;
1383:                            }
1384:                        } else {
1385:                            // if thatVal is null, put the other earlier in the list
1386:                            if (thatVal == null) {
1387:                                tempResult = -1;
1388:                            } else {
1389:                                tempResult = this Val.compareTo(thatVal);
1390:                            }
1391:                        }
1392:                        if (tempResult != 0)
1393:                            return tempResult;
1394:                    }
1395:                }
1396:
1397:                // if we got here it means the two are exactly the same, so return tempResult, which should be 0
1398:                return tempResult;
1399:            }
1400:
1401:            /** Clones this GenericEntity, this is a shallow clone & uses the default shallow HashMap clone
1402:             *@return Object that is a clone of this GenericEntity
1403:             */
1404:            public Object clone() {
1405:                GenericEntity newEntity = new GenericEntity();
1406:                newEntity.init(this );
1407:
1408:                newEntity.setDelegator(internalDelegator);
1409:                return newEntity;
1410:            }
1411:
1412:            // ---- Methods added to implement the Map interface: ----
1413:
1414:            public Object remove(Object key) {
1415:                return this .fields.remove(key);
1416:            }
1417:
1418:            public boolean containsKey(Object key) {
1419:                return this .fields.containsKey(key);
1420:            }
1421:
1422:            public java.util.Set entrySet() {
1423:                return Collections.unmodifiableSet(this .fields.entrySet());
1424:            }
1425:
1426:            public Object put(Object key, Object value) {
1427:                return this .set((String) key, value, true);
1428:            }
1429:
1430:            public void putAll(java.util.Map map) {
1431:                this .setFields(map);
1432:            }
1433:
1434:            public void clear() {
1435:                this .fields.clear();
1436:            }
1437:
1438:            public Object get(Object key) {
1439:                try {
1440:                    return this .get((String) key);
1441:                } catch (IllegalArgumentException e) {
1442:                    if (Debug.verboseOn()) {
1443:                        Debug
1444:                                .logVerbose(
1445:                                        e,
1446:                                        "The field name (or key) ["
1447:                                                + key
1448:                                                + "] is not valid for entity ["
1449:                                                + this .getEntityName()
1450:                                                + "], printing IllegalArgumentException instead of throwing it because Map interface specification does not allow throwing that exception.",
1451:                                        module);
1452:                    } else {
1453:                        Debug
1454:                                .logWarning(
1455:                                        "The field name (or key) ["
1456:                                                + key
1457:                                                + "] is not valid for entity ["
1458:                                                + this .getEntityName()
1459:                                                + "], printing IllegalArgumentException instead of throwing it because Map interface specification does not allow throwing that exception.",
1460:                                        module);
1461:                    }
1462:                    return null;
1463:                }
1464:            }
1465:
1466:            public java.util.Set keySet() {
1467:                return Collections.unmodifiableSet(this .fields.keySet());
1468:            }
1469:
1470:            public boolean isEmpty() {
1471:                return this .fields.isEmpty();
1472:            }
1473:
1474:            public java.util.Collection values() {
1475:                return Collections.unmodifiableCollection(this .fields.values());
1476:            }
1477:
1478:            public boolean containsValue(Object value) {
1479:                return this .fields.containsValue(value);
1480:            }
1481:
1482:            public int size() {
1483:                return this .fields.size();
1484:            }
1485:
1486:            public boolean matches(EntityCondition condition) {
1487:                return condition.entityMatches(this );
1488:            }
1489:
1490:            public static interface NULL {
1491:            }
1492:
1493:            public static class NullGenericEntity extends GenericEntity
1494:                    implements  NULL {
1495:                protected NullGenericEntity() {
1496:                }
1497:
1498:                public String toString() {
1499:                    return "[null-entity]";
1500:                }
1501:            }
1502:
1503:            public static class NullField implements  NULL {
1504:                protected NullField() {
1505:                }
1506:
1507:                public String toString() {
1508:                    return "[null-field]";
1509:                }
1510:            }
1511:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.