Source Code Cross Referenced for FieldMetaData.java in  » Database-ORM » openjpa » org » apache » openjpa » meta » 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 » Database ORM » openjpa » org.apache.openjpa.meta 
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:         */
0019:        package org.apache.openjpa.meta;
0020:
0021:        import java.io.Externalizable;
0022:        import java.io.IOException;
0023:        import java.io.ObjectInput;
0024:        import java.io.ObjectOutput;
0025:        import java.io.Serializable;
0026:        import java.lang.reflect.Constructor;
0027:        import java.lang.reflect.Field;
0028:        import java.lang.reflect.InvocationTargetException;
0029:        import java.lang.reflect.Member;
0030:        import java.lang.reflect.Method;
0031:        import java.lang.reflect.Modifier;
0032:        import java.security.AccessController;
0033:        import java.security.PrivilegedActionException;
0034:        import java.util.ArrayList;
0035:        import java.util.Calendar;
0036:        import java.util.Collection;
0037:        import java.util.Collections;
0038:        import java.util.Comparator;
0039:        import java.util.HashMap;
0040:        import java.util.HashSet;
0041:        import java.util.Iterator;
0042:        import java.util.List;
0043:        import java.util.Map;
0044:        import java.util.Properties;
0045:        import java.util.Set;
0046:        import java.util.TimeZone;
0047:
0048:        import org.apache.commons.collections.comparators.ComparatorChain;
0049:        import org.apache.commons.lang.StringUtils;
0050:        import org.apache.openjpa.conf.OpenJPAConfiguration;
0051:        import org.apache.openjpa.kernel.OpenJPAStateManager;
0052:        import org.apache.openjpa.kernel.StoreContext;
0053:        import org.apache.openjpa.lib.conf.Configurations;
0054:        import org.apache.openjpa.lib.log.Log;
0055:        import org.apache.openjpa.lib.util.J2DoPrivHelper;
0056:        import org.apache.openjpa.lib.util.JavaVersions;
0057:        import org.apache.openjpa.lib.util.Localizer;
0058:        import org.apache.openjpa.lib.util.Options;
0059:        import org.apache.openjpa.lib.xml.Commentable;
0060:        import org.apache.openjpa.util.Exceptions;
0061:        import org.apache.openjpa.util.InternalException;
0062:        import org.apache.openjpa.util.MetaDataException;
0063:        import org.apache.openjpa.util.OpenJPAException;
0064:        import org.apache.openjpa.util.UnsupportedException;
0065:        import org.apache.openjpa.util.ImplHelper;
0066:        import org.apache.openjpa.util.UserException;
0067:
0068:        import serp.util.Strings;
0069:
0070:        /**
0071:         * Metadata for a managed class field.
0072:         *
0073:         * @author Abe White
0074:         */
0075:        public class FieldMetaData extends Extensions implements  ValueMetaData,
0076:                MetaDataContext, MetaDataModes, Commentable {
0077:
0078:            /**
0079:             * Constant specifying that no null-value was given.
0080:             */
0081:            public static final int NULL_UNSET = -1;
0082:
0083:            /**
0084:             * Constant specifying to use a datastore null to persist null values
0085:             * in object fields.
0086:             */
0087:            public static final int NULL_NONE = 0;
0088:
0089:            /**
0090:             * Constant specifying to use a datastore default value to persist null
0091:             * values in object fields.
0092:             */
0093:            public static final int NULL_DEFAULT = 1;
0094:
0095:            /**
0096:             * Constant specifying to throw an exception when attempting to persist
0097:             * null values in object fields.
0098:             */
0099:            public static final int NULL_EXCEPTION = 2;
0100:
0101:            /**
0102:             * Constant specifying the management level of a field.
0103:             */
0104:            public static final int MANAGE_PERSISTENT = 3;
0105:
0106:            /**
0107:             * Constant specifying the management level of a field.
0108:             */
0109:            public static final int MANAGE_TRANSACTIONAL = 1;
0110:
0111:            /**
0112:             * Constant specifying the management level of a field.
0113:             */
0114:            public static final int MANAGE_NONE = 0;
0115:
0116:            private static final Localizer _loc = Localizer
0117:                    .forPackage(FieldMetaData.class);
0118:
0119:            private static final int DFG_FALSE = 1;
0120:            private static final int DFG_TRUE = 2;
0121:            private static final int DFG_EXPLICIT = 4;
0122:
0123:            private static final Method DEFAULT_METHOD;
0124:            static {
0125:                try {
0126:                    DEFAULT_METHOD = Object.class.getMethod("wait",
0127:                            (Class[]) null);
0128:                } catch (Exception e) {
0129:                    // shouldn't ever happen
0130:                    throw new InternalException(e);
0131:                }
0132:            }
0133:
0134:            // name and type
0135:            private final ValueMetaData _val;
0136:            private final ValueMetaData _key;
0137:            private final ValueMetaData _elem;
0138:            private final ClassMetaData _owner;
0139:            private final String _name;
0140:            private Class _dec = null;
0141:            private ClassMetaData _decMeta = null;
0142:            private String _fullName = null;
0143:            private String _embedFullName = null;
0144:            private int _resMode = MODE_NONE;
0145:
0146:            // load/store info
0147:            private String[] _comments = null;
0148:            private int _listIndex = -1;
0149:
0150:            ////////////////////////////////////////////////////////////////////
0151:            // Note: if you add additional state, make sure to add it to copy()
0152:            ////////////////////////////////////////////////////////////////////
0153:
0154:            // misc info
0155:            private Class _proxyClass = null;
0156:            private Object _initializer = null;
0157:            private boolean _transient = false;
0158:            private boolean _primKey = false;
0159:            private Boolean _version = null;
0160:            private int _nullValue = NULL_UNSET;
0161:            private int _manage = MANAGE_PERSISTENT;
0162:            private int _index = -1;
0163:            private int _decIndex = -1;
0164:            private int _pkIndex = -1;
0165:            private boolean _explicit = false;
0166:            private int _dfg = 0;
0167:            private Set _fgSet = null;
0168:            private String[] _fgs = null;
0169:            private String _lfg = null;
0170:            private Boolean _lrs = null;
0171:            private Boolean _stream = null;
0172:            private String _extName = null;
0173:            private String _factName = null;
0174:            private String _extString = null;
0175:            private Map _extValues = Collections.EMPTY_MAP;
0176:            private Map _fieldValues = Collections.EMPTY_MAP;
0177:            private Boolean _enumField = null;
0178:            private Boolean _lobField = null;
0179:            private Boolean _serializableField = null;
0180:            private boolean _generated = false;
0181:
0182:            // Members aren't serializable. Use a proxy that can provide a Member
0183:            // to avoid writing the full Externalizable implementation.
0184:            private MemberProvider _backingMember = null;
0185:
0186:            // Members aren't serializable. Initializing _extMethod and _factMethod to
0187:            // DEFAULT_METHOD is sufficient to trigger lazy population of these fields.
0188:            private transient Method _extMethod = DEFAULT_METHOD;
0189:            private transient Member _factMethod = DEFAULT_METHOD;
0190:
0191:            // intermediate and impl data
0192:            private boolean _intermediate = true;
0193:            private Boolean _implData = Boolean.TRUE;
0194:
0195:            // value generation
0196:            private int _valStrategy = -1;
0197:            private int _upStrategy = -1;
0198:            private String _seqName = ClassMetaData.DEFAULT_STRING;
0199:            private SequenceMetaData _seqMeta = null;
0200:
0201:            // inverses
0202:            private String _mappedBy = null;
0203:            private FieldMetaData _mappedByMeta = null;
0204:            private FieldMetaData[] _inverses = null;
0205:            private String _inverse = ClassMetaData.DEFAULT_STRING;
0206:
0207:            // ordering on load
0208:            private Order[] _orders = null;
0209:            private String _orderDec = null;
0210:            // indicate if this field is used by other field as "order by" value 
0211:            private boolean _usedInOrderBy = false;
0212:
0213:            /**
0214:             * Constructor.
0215:             *
0216:             * @param name the field name
0217:             * @param type the field type
0218:             * @param owner the owning class metadata
0219:             */
0220:            protected FieldMetaData(String name, Class type, ClassMetaData owner) {
0221:                _name = name;
0222:                _owner = owner;
0223:                _dec = null;
0224:                _decMeta = null;
0225:                _val = owner.getRepository().newValueMetaData(this );
0226:                _key = owner.getRepository().newValueMetaData(this );
0227:                _elem = owner.getRepository().newValueMetaData(this );
0228:
0229:                setDeclaredType(type);
0230:            }
0231:
0232:            /**
0233:             * Supply the backing member object; this allows us to utilize
0234:             * parameterized type information if available.
0235:             */
0236:            public void backingMember(Member member) {
0237:                if (member == null)
0238:                    return;
0239:                if (Modifier.isTransient(member.getModifiers()))
0240:                    _transient = true;
0241:
0242:                _backingMember = new MemberProvider(member);
0243:
0244:                Class type;
0245:                Class[] types;
0246:                if (member instanceof  Field) {
0247:                    Field f = (Field) member;
0248:                    type = f.getType();
0249:                    types = JavaVersions.getParameterizedTypes(f);
0250:                } else {
0251:                    Method meth = (Method) member;
0252:                    type = meth.getReturnType();
0253:                    types = JavaVersions.getParameterizedTypes(meth);
0254:                }
0255:
0256:                setDeclaredType(type);
0257:                if (Collection.class.isAssignableFrom(type)
0258:                        && _elem.getDeclaredType() == Object.class
0259:                        && types.length == 1) {
0260:                    _elem.setDeclaredType(types[0]);
0261:                } else if (Map.class.isAssignableFrom(type)
0262:                        && types.length == 2) {
0263:                    if (_key.getDeclaredType() == Object.class)
0264:                        _key.setDeclaredType(types[0]);
0265:                    if (_elem.getDeclaredType() == Object.class)
0266:                        _elem.setDeclaredType(types[1]);
0267:                }
0268:            }
0269:
0270:            /**
0271:             * Return the backing member supplied in {@link #backingMember}.
0272:             */
0273:            public Member getBackingMember() {
0274:                return (_backingMember == null) ? null : _backingMember
0275:                        .getMember();
0276:            }
0277:
0278:            /**
0279:             * The metadata repository.
0280:             */
0281:            public MetaDataRepository getRepository() {
0282:                return _owner.getRepository();
0283:            }
0284:
0285:            /**
0286:             * The class that defines the metadata for this field.
0287:             */
0288:            public ClassMetaData getDefiningMetaData() {
0289:                return _owner;
0290:            }
0291:
0292:            /**
0293:             * The declaring class.
0294:             */
0295:            public Class getDeclaringType() {
0296:                return (_dec == null) ? _owner.getDescribedType() : _dec;
0297:            }
0298:
0299:            /**
0300:             * The declaring class.
0301:             */
0302:            public void setDeclaringType(Class cls) {
0303:                _dec = cls;
0304:                _decMeta = null;
0305:                _fullName = null;
0306:                _embedFullName = null;
0307:            }
0308:
0309:            /**
0310:             * The declaring class.
0311:             */
0312:            public ClassMetaData getDeclaringMetaData() {
0313:                if (_dec == null)
0314:                    return _owner;
0315:                if (_decMeta == null)
0316:                    _decMeta = getRepository().getMetaData(_dec,
0317:                            _owner.getEnvClassLoader(), true);
0318:                return _decMeta;
0319:            }
0320:
0321:            /**
0322:             * The field name.
0323:             */
0324:            public String getName() {
0325:                return _name;
0326:            }
0327:
0328:            /**
0329:             * The field name, qualified by the owning class.
0330:             * @deprecated Use getFullName(boolean) instead.
0331:             */
0332:            public String getFullName() {
0333:                return getFullName(false);
0334:            }
0335:
0336:            /**
0337:             * The field name, qualified by the owning class and optionally the
0338:             * embedding owner's name (if any).
0339:             */
0340:            public String getFullName(boolean embedOwner) {
0341:                if (_fullName == null)
0342:                    _fullName = getDeclaringType().getName() + "." + _name;
0343:                if (embedOwner && _embedFullName == null) {
0344:                    if (_owner.getEmbeddingMetaData() == null)
0345:                        _embedFullName = _fullName;
0346:                    else
0347:                        _embedFullName = _owner.getEmbeddingMetaData()
0348:                                .getFieldMetaData().getFullName(true)
0349:                                + "." + _fullName;
0350:                }
0351:                return (embedOwner) ? _embedFullName : _fullName;
0352:            }
0353:
0354:            /**
0355:             * MetaData about the field value.
0356:             */
0357:            public ValueMetaData getValue() {
0358:                return _val;
0359:            }
0360:
0361:            /**
0362:             * Metadata about the key value.
0363:             */
0364:            public ValueMetaData getKey() {
0365:                return _key;
0366:            }
0367:
0368:            /**
0369:             * Metadata about the element value.
0370:             */
0371:            public ValueMetaData getElement() {
0372:                return _elem;
0373:            }
0374:
0375:            /**
0376:             * Return whether this field is mapped to the datastore. By default,
0377:             * returns true for all persistent fields whose defining class is mapped.
0378:             */
0379:            public boolean isMapped() {
0380:                return _manage == MANAGE_PERSISTENT && _owner.isMapped();
0381:            }
0382:
0383:            /**
0384:             * The type this field was initialized with, and therefore the
0385:             * type to use for proxies when loading data into this field.
0386:             */
0387:            public Class getProxyType() {
0388:                return (_proxyClass == null) ? getDeclaredType() : _proxyClass;
0389:            }
0390:
0391:            /**
0392:             * The type this field was initialized with, and therefore the
0393:             * type to use for proxies when loading data into this field.
0394:             */
0395:            public void setProxyType(Class type) {
0396:                _proxyClass = type;
0397:            }
0398:
0399:            /**
0400:             * The initializer used by the field, or null if none. This
0401:             * is additional information for initializing the field, such as
0402:             * a custom {@link Comparator} used by a {@link Set} or
0403:             * a {@link TimeZone} used by a {@link Calendar}.
0404:             */
0405:            public Object getInitializer() {
0406:                return _initializer;
0407:            }
0408:
0409:            /**
0410:             * The initializer used by the field, or null if none. This
0411:             * is additional information for initializing the field, such as
0412:             * a custom {@link Comparator} used by a {@link Set} or
0413:             * a {@link TimeZone} used by a {@link Calendar}.
0414:             */
0415:            public void setInitializer(Object initializer) {
0416:                _initializer = initializer;
0417:            }
0418:
0419:            /**
0420:             * Return whether this is a transient field.
0421:             */
0422:            public boolean isTransient() {
0423:                return _transient;
0424:            }
0425:
0426:            /**
0427:             * Return whether this is a transient field.
0428:             */
0429:            public void setTransient(boolean trans) {
0430:                _transient = trans;
0431:            }
0432:
0433:            /**
0434:             * The absolute index of this persistent/transactional field.
0435:             */
0436:            public int getIndex() {
0437:                return _index;
0438:            }
0439:
0440:            /**
0441:             * The absolute index of this persistent/transactional field.
0442:             */
0443:            public void setIndex(int index) {
0444:                _index = index;
0445:            }
0446:
0447:            /**
0448:             * The relative index of this persistent/transactional field.
0449:             */
0450:            public int getDeclaredIndex() {
0451:                return _decIndex;
0452:            }
0453:
0454:            /**
0455:             * The relative index of this persistent/transactional field.
0456:             */
0457:            public void setDeclaredIndex(int index) {
0458:                _decIndex = index;
0459:            }
0460:
0461:            /**
0462:             * The index in which this field was listed in the metadata. Defaults to
0463:             * <code>-1</code> if this field was not listed in the metadata.
0464:             */
0465:            public int getListingIndex() {
0466:                return _listIndex;
0467:            }
0468:
0469:            /**
0470:             * The index in which this field was listed in the metadata. Defaults to
0471:             * <code>-1</code> if this field was not listed in the metadata.
0472:             */
0473:            public void setListingIndex(int index) {
0474:                _listIndex = index;
0475:            }
0476:
0477:            /**
0478:             * The absolute primary key index for this field, or -1 if not a primary
0479:             * key. The first primary key field has index 0, the second index 1, etc.
0480:             */
0481:            public int getPrimaryKeyIndex() {
0482:                return _pkIndex;
0483:            }
0484:
0485:            /**
0486:             * The absolute primary key index for this field, or -1 if not a primary
0487:             * key. The first primary key field has index 0, the second index 1, etc.
0488:             */
0489:            public void setPrimaryKeyIndex(int index) {
0490:                _pkIndex = index;
0491:            }
0492:
0493:            /**
0494:             * Return the management level for the field. Will be one of:
0495:             * <ul>
0496:             * <li>{@link #MANAGE_PERSISTENT}: the field is persistent</li>
0497:             * <li>{@link #MANAGE_TRANSACTIONAL}: the field is transactional but not
0498:             * persistent</li>
0499:             * <li>{@link #MANAGE_NONE}: the field is not managed</li>
0500:             * </ul> Defaults to {@link #MANAGE_PERSISTENT}.
0501:             */
0502:            public int getManagement() {
0503:                return _manage;
0504:            }
0505:
0506:            /**
0507:             * Return the management level for the field. Will be one of:
0508:             * <ul>
0509:             * <li>{@link #MANAGE_PERSISTENT}: the field is persistent</li>
0510:             * <li>{@link #MANAGE_TRANSACTIONAL}: the field is transactional but not
0511:             * persistent</li>
0512:             * <li>{@link #MANAGE_NONE}: the field is not managed</li>
0513:             * </ul> 
0514:             * Defaults to {@link #MANAGE_PERSISTENT}.
0515:             */
0516:            public void setManagement(int manage) {
0517:                if ((_manage == MANAGE_NONE) != (manage == MANAGE_NONE))
0518:                    _owner.clearFieldCache();
0519:                _manage = manage;
0520:            }
0521:
0522:            /**
0523:             * Whether this is a primary key field.
0524:             */
0525:            public boolean isPrimaryKey() {
0526:                return _primKey;
0527:            }
0528:
0529:            /**
0530:             * Whether this is a primary key field.
0531:             */
0532:            public void setPrimaryKey(boolean primKey) {
0533:                _primKey = primKey;
0534:            }
0535:
0536:            /**
0537:             * For a primary key field, return the type of the corresponding object id 
0538:             * class field.
0539:             */
0540:            public int getObjectIdFieldTypeCode() {
0541:                ClassMetaData relmeta = getDeclaredTypeMetaData();
0542:                if (relmeta == null)
0543:                    return getDeclaredTypeCode();
0544:                if (relmeta.getIdentityType() == ClassMetaData.ID_DATASTORE) {
0545:                    boolean unwrap = getRepository().getMetaDataFactory()
0546:                            .getDefaults().isDataStoreObjectIdFieldUnwrapped();
0547:                    return (unwrap) ? JavaTypes.LONG : JavaTypes.OBJECT;
0548:                }
0549:                if (relmeta.isOpenJPAIdentity())
0550:                    return relmeta.getPrimaryKeyFields()[0]
0551:                            .getObjectIdFieldTypeCode();
0552:                return JavaTypes.OBJECT;
0553:            }
0554:
0555:            /**
0556:             * For a primary key field, return the type of the corresponding object id 
0557:             * class field.
0558:             */
0559:            public Class getObjectIdFieldType() {
0560:                ClassMetaData relmeta = getDeclaredTypeMetaData();
0561:                if (relmeta == null)
0562:                    return getDeclaredType();
0563:                switch (relmeta.getIdentityType()) {
0564:                case ClassMetaData.ID_DATASTORE:
0565:                    boolean unwrap = getRepository().getMetaDataFactory()
0566:                            .getDefaults().isDataStoreObjectIdFieldUnwrapped();
0567:                    return (unwrap) ? long.class : Object.class;
0568:                case ClassMetaData.ID_APPLICATION:
0569:                    if (relmeta.isOpenJPAIdentity())
0570:                        return relmeta.getPrimaryKeyFields()[0]
0571:                                .getObjectIdFieldType();
0572:                    return (relmeta.getObjectIdType() == null) ? Object.class
0573:                            : relmeta.getObjectIdType();
0574:                default:
0575:                    return Object.class;
0576:                }
0577:            }
0578:
0579:            /**
0580:             * Whether this field holds optimistic version information.
0581:             */
0582:            public boolean isVersion() {
0583:                return _version == Boolean.TRUE;
0584:            }
0585:
0586:            /**
0587:             * Whether this field holds optimistic version information.
0588:             */
0589:            public void setVersion(boolean version) {
0590:                _version = (version) ? Boolean.TRUE : Boolean.FALSE;
0591:            }
0592:
0593:            /**
0594:             * Whether this field is in the default fetch group.
0595:             */
0596:            public boolean isInDefaultFetchGroup() {
0597:                if (_dfg == 0) {
0598:                    if (_manage != MANAGE_PERSISTENT || isPrimaryKey()
0599:                            || isVersion())
0600:                        _dfg = DFG_FALSE;
0601:                    else {
0602:                        // field left as default; dfg setting depends on type
0603:                        switch (getTypeCode()) {
0604:                        case JavaTypes.OBJECT:
0605:                            if (isSerializable() || isEnum())
0606:                                _dfg = DFG_TRUE;
0607:                            else
0608:                                _dfg = DFG_FALSE;
0609:                            break;
0610:                        case JavaTypes.ARRAY:
0611:                            if (isLobArray())
0612:                                _dfg = DFG_TRUE;
0613:                            else
0614:                                _dfg = DFG_FALSE;
0615:                            break;
0616:                        case JavaTypes.COLLECTION:
0617:                        case JavaTypes.MAP:
0618:                        case JavaTypes.PC:
0619:                        case JavaTypes.PC_UNTYPED:
0620:                            _dfg = DFG_FALSE;
0621:                            break;
0622:                        default:
0623:                            _dfg = DFG_TRUE;
0624:                        }
0625:                    }
0626:                }
0627:                return (_dfg & DFG_TRUE) > 0;
0628:            }
0629:
0630:            private boolean isEnum() {
0631:                if (_enumField == null) {
0632:                    Class dt = getDeclaredType();
0633:                    _enumField = JavaVersions.isEnumeration(dt) ? Boolean.TRUE
0634:                            : Boolean.FALSE;
0635:                }
0636:                return _enumField.booleanValue();
0637:            }
0638:
0639:            private boolean isSerializable() {
0640:                if (_serializableField == null) {
0641:                    Class dt = getDeclaredType();
0642:                    if (Serializable.class.isAssignableFrom(dt))
0643:                        _serializableField = Boolean.TRUE;
0644:                    else
0645:                        _serializableField = Boolean.FALSE;
0646:                }
0647:                return _serializableField.booleanValue();
0648:            }
0649:
0650:            private boolean isLobArray() {
0651:                // check for byte[], Byte[], char[], Character[]
0652:                if (_lobField == null) {
0653:                    Class dt = getDeclaredType();
0654:                    if (dt == byte[].class || dt == Byte[].class
0655:                            || dt == char[].class || dt == Character[].class)
0656:                        _lobField = Boolean.TRUE;
0657:                    else
0658:                        _lobField = Boolean.FALSE;
0659:                }
0660:                return _lobField.booleanValue();
0661:            }
0662:
0663:            /**
0664:             * Whether this field is in the default fetch group.
0665:             */
0666:            public void setInDefaultFetchGroup(boolean dfg) {
0667:                if (dfg)
0668:                    _dfg = DFG_TRUE;
0669:                else
0670:                    _dfg = DFG_FALSE;
0671:                _dfg |= DFG_EXPLICIT;
0672:            }
0673:
0674:            /**
0675:             * Whether the default fetch group setting is explicit.
0676:             */
0677:            public boolean isDefaultFetchGroupExplicit() {
0678:                return (_dfg & DFG_EXPLICIT) > 0;
0679:            }
0680:
0681:            /**
0682:             * Whether the default fetch group setting is explicit. Allow setting
0683:             * for testing.
0684:             */
0685:            public void setDefaultFetchGroupExplicit(boolean explicit) {
0686:                if (explicit)
0687:                    _dfg |= DFG_EXPLICIT;
0688:                else
0689:                    _dfg &= ~DFG_EXPLICIT;
0690:            }
0691:
0692:            /**
0693:             * Gets the name of the custom fetch groups those are associated to this 
0694:             * receiver.  This does not include the "default" and "all" fetch groups.
0695:             *
0696:             * @return the set of fetch group names, not including the default and
0697:             * all fetch groups.
0698:             */
0699:            public String[] getCustomFetchGroups() {
0700:                if (_fgs == null) {
0701:                    if (_fgSet == null || _manage != MANAGE_PERSISTENT
0702:                            || isPrimaryKey() || isVersion())
0703:                        _fgs = new String[0];
0704:                    else
0705:                        _fgs = (String[]) _fgSet.toArray(new String[_fgSet
0706:                                .size()]);
0707:                }
0708:                return _fgs;
0709:            }
0710:
0711:            /**
0712:             * The fetch group that is to be loaded when this receiver is loaded, or
0713:             * null if none set.
0714:             */
0715:            public String getLoadFetchGroup() {
0716:                return _lfg;
0717:            }
0718:
0719:            /**
0720:             * The fetch group that is to be loaded when this receiver is loaded, or
0721:             * null if none set.
0722:             */
0723:            public void setLoadFetchGroup(String lfg) {
0724:                if ("".equals(lfg))
0725:                    lfg = null;
0726:                _lfg = lfg;
0727:            }
0728:
0729:            /**
0730:             * Whether this field is in the given fetch group.
0731:             */
0732:            public boolean isInFetchGroup(String fg) {
0733:                if (_manage != MANAGE_PERSISTENT || isPrimaryKey()
0734:                        || isVersion())
0735:                    return false;
0736:                if (FetchGroup.NAME_ALL.equals(fg))
0737:                    return true;
0738:                if (FetchGroup.NAME_DEFAULT.equals(fg))
0739:                    return isInDefaultFetchGroup();
0740:                return _fgSet != null && _fgSet.contains(fg);
0741:            }
0742:
0743:            /**
0744:             * Set whether this field is in the given fetch group.
0745:             *
0746:             * @param fg is the name of a fetch group that must be present in the
0747:             * class that declared this field or any of its persistent superclasses.
0748:             */
0749:            public void setInFetchGroup(String fg, boolean in) {
0750:                if (StringUtils.isEmpty(fg))
0751:                    throw new MetaDataException(_loc.get("empty-fg-name", this ));
0752:                if (fg.equals(FetchGroup.NAME_ALL))
0753:                    return;
0754:                if (fg.equals(FetchGroup.NAME_DEFAULT)) {
0755:                    setInDefaultFetchGroup(in);
0756:                    return;
0757:                }
0758:                if (_owner.getFetchGroup(fg) == null)
0759:                    throw new MetaDataException(_loc
0760:                            .get("unknown-fg", fg, this ));
0761:                if (in && _fgSet == null)
0762:                    _fgSet = new HashSet();
0763:                if ((in && _fgSet.add(fg))
0764:                        || (!in && _fgSet != null && _fgSet.remove(fg)))
0765:                    _fgs = null;
0766:            }
0767:
0768:            /**
0769:             * How the data store should treat null values for this field:
0770:             * <ul>
0771:             * <li>{@link #NULL_UNSET}: no value supplied</li>
0772:             * <li>{@link #NULL_NONE}: leave null values as null in the data store</li>
0773:             * <li>{@link #NULL_EXCEPTION}: throw an exception if this field is null
0774:             * at commit</li>
0775:             * <li>{@link #NULL_DEFAULT}: use the database default if this field is
0776:             * null at commit</li>
0777:             * </ul> Defaults to {@link #NULL_UNSET}.
0778:             */
0779:            public int getNullValue() {
0780:                return _nullValue;
0781:            }
0782:
0783:            /**
0784:             * How the data store should treat null values for this field:
0785:             * <ul>
0786:             * <li>{@link #NULL_UNSET}: no value supplied</li>
0787:             * <li>{@link #NULL_NONE}: leave null values as null in the data store</li>
0788:             * <li>{@link #NULL_EXCEPTION}: throw an exception if this field is null
0789:             * at commit</li>
0790:             * <li>{@link #NULL_DEFAULT}: use the database default if this field is
0791:             * null at commit</li>
0792:             * </ul> Defaults to {@link #NULL_UNSET}.
0793:             */
0794:            public void setNullValue(int nullValue) {
0795:                _nullValue = nullValue;
0796:            }
0797:
0798:            /**
0799:             * Whether this field is explicitly declared in the metadata.
0800:             */
0801:            public boolean isExplicit() {
0802:                return _explicit;
0803:            }
0804:
0805:            /**
0806:             * Whether this field is explicitly declared in the metadata.
0807:             */
0808:            public void setExplicit(boolean explicit) {
0809:                _explicit = explicit;
0810:            }
0811:
0812:            /**
0813:             * The field that this field shares a mapping with.
0814:             */
0815:            public String getMappedBy() {
0816:                return _mappedBy;
0817:            }
0818:
0819:            /**
0820:             * The field that this field shares a mapping with.
0821:             */
0822:            public void setMappedBy(String mapped) {
0823:                _mappedBy = mapped;
0824:                _mappedByMeta = null;
0825:            }
0826:
0827:            /**
0828:             * The field that this field shares a mapping with.
0829:             */
0830:            public FieldMetaData getMappedByMetaData() {
0831:                if (_mappedBy != null && _mappedByMeta == null) {
0832:                    ClassMetaData meta = null;
0833:                    switch (getTypeCode()) {
0834:                    case JavaTypes.PC:
0835:                        meta = getTypeMetaData();
0836:                        break;
0837:                    case JavaTypes.ARRAY:
0838:                    case JavaTypes.COLLECTION:
0839:                    case JavaTypes.MAP:
0840:                        meta = _elem.getTypeMetaData();
0841:                        break;
0842:                    }
0843:
0844:                    FieldMetaData field = (meta == null) ? null : meta
0845:                            .getField(_mappedBy);
0846:                    if (field == null)
0847:                        throw new MetaDataException(_loc.get("no-mapped-by",
0848:                                this , _mappedBy));
0849:                    if (field.getMappedBy() != null)
0850:                        throw new MetaDataException(_loc.get("circ-mapped-by",
0851:                                this , _mappedBy));
0852:                    _mappedByMeta = field;
0853:                }
0854:                return _mappedByMeta;
0855:            }
0856:
0857:            /**
0858:             * Logical inverse field.
0859:             */
0860:            public String getInverse() {
0861:                if (ClassMetaData.DEFAULT_STRING.equals(_inverse))
0862:                    _inverse = null;
0863:                return _inverse;
0864:            }
0865:
0866:            /**
0867:             * Logical inverse field.
0868:             */
0869:            public void setInverse(String inverse) {
0870:                _inverses = null;
0871:                _inverse = inverse;
0872:            }
0873:
0874:            /**
0875:             * Return all inverses of this field.
0876:             */
0877:            public FieldMetaData[] getInverseMetaDatas() {
0878:                if (_inverses == null) {
0879:                    // can't declare both an inverse owner and a logical inverse
0880:                    String inv = getInverse();
0881:                    if (_mappedBy != null && inv != null
0882:                            && !_mappedBy.equals(inv))
0883:                        throw new MetaDataException(_loc.get(
0884:                                "mapped-not-inverse", this ));
0885:
0886:                    // get the metadata for the type on the other side of this relation
0887:                    ClassMetaData meta = null;
0888:                    switch (getTypeCode()) {
0889:                    case JavaTypes.PC:
0890:                        meta = getTypeMetaData();
0891:                        break;
0892:                    case JavaTypes.ARRAY:
0893:                    case JavaTypes.COLLECTION:
0894:                        meta = _elem.getTypeMetaData();
0895:                        break;
0896:                    }
0897:
0898:                    Collection inverses = null;
0899:                    if (meta != null) {
0900:                        // add mapped by and named inverse, if any
0901:                        FieldMetaData field = getMappedByMetaData();
0902:                        if (field != null) {
0903:                            // mapped by field isn't necessarily a pc type, but all
0904:                            // inverses must be
0905:                            if (field.getTypeCode() == JavaTypes.PC
0906:                                    || field.getElement().getTypeCode() == JavaTypes.PC) {
0907:                                inverses = new ArrayList(3);
0908:                                inverses.add(field);
0909:                            }
0910:                        } else if (inv != null) {
0911:                            field = meta.getField(inv);
0912:                            if (field == null)
0913:                                throw new MetaDataException(_loc.get(
0914:                                        "no-inverse", this , inv));
0915:                            inverses = new ArrayList(3);
0916:                            inverses.add(field);
0917:                        }
0918:
0919:                        // scan rel type for fields that name this field as an inverse
0920:                        FieldMetaData[] fields = meta.getFields();
0921:                        Class type = getDeclaringMetaData().getDescribedType();
0922:                        for (int i = 0; i < fields.length; i++) {
0923:                            // skip fields that aren't compatible with our owning class
0924:                            switch (fields[i].getTypeCode()) {
0925:                            case JavaTypes.PC:
0926:                                if (!type.isAssignableFrom(fields[i].getType()))
0927:                                    continue;
0928:                                break;
0929:                            case JavaTypes.COLLECTION:
0930:                            case JavaTypes.ARRAY:
0931:                                if (!type.isAssignableFrom(fields[i]
0932:                                        .getElement().getType()))
0933:                                    continue;
0934:                                break;
0935:                            default:
0936:                                continue;
0937:                            }
0938:
0939:                            // if the field declares us as its inverse and we haven't
0940:                            // already added it (we might have if we also declared it
0941:                            // as our inverse), add it now
0942:                            if (_name.equals(fields[i].getMappedBy())
0943:                                    || _name.equals(fields[i].getInverse())) {
0944:                                if (inverses == null)
0945:                                    inverses = new ArrayList(3);
0946:                                if (!inverses.contains(fields[i]))
0947:                                    inverses.add(fields[i]);
0948:                            }
0949:                        }
0950:                    }
0951:
0952:                    MetaDataRepository repos = getRepository();
0953:                    if (inverses == null)
0954:                        _inverses = repos.EMPTY_FIELDS;
0955:                    else
0956:                        _inverses = (FieldMetaData[]) inverses.toArray(repos
0957:                                .newFieldMetaDataArray(inverses.size()));
0958:                }
0959:                return _inverses;
0960:            }
0961:
0962:            /**
0963:             * The strategy to use for insert value generation.
0964:             * One of the constants from {@link ValueStrategies}.
0965:             */
0966:            public int getValueStrategy() {
0967:                if (_valStrategy == -1)
0968:                    _valStrategy = ValueStrategies.NONE;
0969:                return _valStrategy;
0970:            }
0971:
0972:            /**
0973:             * The strategy to use for insert value generation.
0974:             * One of the constants from {@link ValueStrategies}.
0975:             */
0976:            public void setValueStrategy(int strategy) {
0977:                _valStrategy = strategy;
0978:                if (strategy != ValueStrategies.SEQUENCE)
0979:                    setValueSequenceName(null);
0980:            }
0981:
0982:            /**
0983:             * The value sequence name, or null for none.
0984:             */
0985:            public String getValueSequenceName() {
0986:                if (ClassMetaData.DEFAULT_STRING.equals(_seqName))
0987:                    _seqName = null;
0988:                return _seqName;
0989:            }
0990:
0991:            /**
0992:             * The value sequence name, or null for none.
0993:             */
0994:            public void setValueSequenceName(String seqName) {
0995:                _seqName = seqName;
0996:                _seqMeta = null;
0997:                if (seqName != null)
0998:                    setValueStrategy(ValueStrategies.SEQUENCE);
0999:            }
1000:
1001:            /**
1002:             * Metadata for the value sequence.
1003:             */
1004:            public SequenceMetaData getValueSequenceMetaData() {
1005:                if (_seqMeta == null && getValueSequenceName() != null)
1006:                    _seqMeta = getRepository().getSequenceMetaData(_owner,
1007:                            getValueSequenceName(), true);
1008:                return _seqMeta;
1009:            }
1010:
1011:            /**
1012:             * The strategy to use when updating the field.
1013:             */
1014:            public int getUpdateStrategy() {
1015:                if (isVersion())
1016:                    return UpdateStrategies.RESTRICT;
1017:                if (_upStrategy == -1)
1018:                    _upStrategy = UpdateStrategies.NONE;
1019:                return _upStrategy;
1020:            }
1021:
1022:            /**
1023:             * Set the update strategy.
1024:             */
1025:            public void setUpdateStrategy(int strategy) {
1026:                _upStrategy = strategy;
1027:            }
1028:
1029:            /**
1030:             * Whether this field is backed by a large result set.
1031:             */
1032:            public boolean isLRS() {
1033:                return _lrs == Boolean.TRUE && _manage == MANAGE_PERSISTENT;
1034:            }
1035:
1036:            /**
1037:             * Whether this field is backed by a large result set.
1038:             */
1039:            public void setLRS(boolean lrs) {
1040:                _lrs = (lrs) ? Boolean.TRUE : Boolean.FALSE;
1041:            }
1042:
1043:            /**
1044:             * Whether this field is backed by a stream.
1045:             *
1046:             * @since 1.1.0
1047:             */
1048:            public boolean isStream() {
1049:                return _stream == Boolean.TRUE && _manage == MANAGE_PERSISTENT;
1050:            }
1051:
1052:            /**
1053:             * Whether this field is backed by a stream.
1054:             *
1055:             * @since 1.1.0
1056:             */
1057:            public void setStream(boolean stream) {
1058:                _stream = (stream) ? Boolean.TRUE : Boolean.FALSE;
1059:            }
1060:
1061:            /**
1062:             * Whether this field uses intermediate data when loading/storing
1063:             * information through a {@link OpenJPAStateManager}. Defaults to true.
1064:             *
1065:             * @see OpenJPAStateManager#setIntermediate(int,Object)
1066:             */
1067:            public boolean usesIntermediate() {
1068:                return _intermediate;
1069:            }
1070:
1071:            /**
1072:             * Whether this field uses intermediate data when loading/storing
1073:             * information through a {@link OpenJPAStateManager}. Defaults to true.
1074:             *
1075:             * @see OpenJPAStateManager#setIntermediate(int,Object)
1076:             */
1077:            public void setUsesIntermediate(boolean intermediate) {
1078:                _intermediate = intermediate;
1079:                _owner.clearExtraFieldDataTable();
1080:            }
1081:
1082:            /**
1083:             * Whether this field uses impl data in conjunction with standard
1084:             * field data when acting on a {@link OpenJPAStateManager}.
1085:             * Defaults to {@link Boolean#TRUE} (non-cachable impl data).
1086:             *
1087:             * @return {@link Boolean#FALSE} if this field does not use impl data,
1088:             * {@link Boolean#TRUE} if this field uses non-cachable impl
1089:             * data, or <code>null</code> if this field uses impl data that
1090:             * should be cached across instances
1091:             * @see OpenJPAStateManager#setImplData(int,Object)
1092:             */
1093:            public Boolean usesImplData() {
1094:                return _implData;
1095:            }
1096:
1097:            /**
1098:             * Whether this field uses impl data in conjunction with standard
1099:             * field data when acting on a {@link OpenJPAStateManager}.
1100:             *
1101:             * @see OpenJPAStateManager#setImplData(int,Object)
1102:             * @see #usesImplData
1103:             */
1104:            public void setUsesImplData(Boolean implData) {
1105:                _implData = implData;
1106:                _owner.clearExtraFieldDataTable();
1107:            }
1108:
1109:            /**
1110:             * The orderings for this field to be applied on load, or empty array.
1111:             */
1112:            public Order[] getOrders() {
1113:                if (_orders == null) {
1114:                    if (_orderDec == null)
1115:                        _orders = getRepository().EMPTY_ORDERS;
1116:                    else {
1117:                        String[] decs = Strings.split(_orderDec, ",", 0);
1118:                        Order[] orders = getRepository().newOrderArray(
1119:                                decs.length);
1120:                        int spc;
1121:                        boolean asc;
1122:                        for (int i = 0; i < decs.length; i++) {
1123:                            decs[i] = decs[i].trim();
1124:                            spc = decs[i].indexOf(' ');
1125:                            if (spc == -1)
1126:                                asc = true;
1127:                            else {
1128:                                asc = decs[i].substring(spc + 1).trim()
1129:                                        .toLowerCase().startsWith("asc");
1130:                                decs[i] = decs[i].substring(0, spc);
1131:                            }
1132:                            orders[i] = getRepository().newOrder(this , decs[i],
1133:                                    asc);
1134:                            //set "isUsedInOrderBy" to the field
1135:                            ClassMetaData elemCls = getElement()
1136:                                    .getDeclaredTypeMetaData();
1137:                            FieldMetaData fmd = elemCls
1138:                                    .getDeclaredField(decs[i]);
1139:                            if (fmd != null)
1140:                                fmd.setUsedInOrderBy(true);
1141:                        }
1142:                        _orders = orders;
1143:                    }
1144:                }
1145:                return _orders;
1146:            }
1147:
1148:            /**
1149:             * The orderings for this field to be applied on load.
1150:             */
1151:            public void setOrders(Order[] orders) {
1152:                _orderDec = null;
1153:                _orders = orders;
1154:            }
1155:
1156:            /**
1157:             * String declaring the orderings for this field to be applied on load,
1158:             * or null. The string is of the form:<br />
1159:             * <code>orderable[ asc|desc][, ...]</code><br />
1160:             * The orderable <code>#element</code> is used to denote the value of
1161:             * the field's elements.
1162:             */
1163:            public String getOrderDeclaration() {
1164:                if (_orderDec == null && _orders != null) {
1165:                    StringBuffer buf = new StringBuffer();
1166:                    for (int i = 0; i < _orders.length; i++) {
1167:                        if (i > 0)
1168:                            buf.append(", ");
1169:                        buf.append(_orders[i].getName()).append(" ");
1170:                        buf.append((_orders[i].isAscending()) ? "asc" : "desc");
1171:                    }
1172:                    _orderDec = buf.toString();
1173:                }
1174:                return _orderDec;
1175:            }
1176:
1177:            /**
1178:             * String declaring the orderings for this field to be applied on load,
1179:             * or null. The string is of the form:<br />
1180:             * <code>orderable[ asc|desc][, ...]</code><br />
1181:             * The orderable <code>#element</code> is used to denote the value of
1182:             * the field's elements.
1183:             */
1184:            public void setOrderDeclaration(String dec) {
1185:                _orderDec = StringUtils.trimToNull(dec);
1186:                _orders = null;
1187:            }
1188:
1189:            /**
1190:             * Order this field value when it is loaded.
1191:             */
1192:            public Object order(Object val) {
1193:                if (val == null)
1194:                    return null;
1195:
1196:                Order[] orders = getOrders();
1197:                if (orders.length == 0)
1198:                    return val;
1199:
1200:                // create a comparator for the elements of the value
1201:                Comparator comp;
1202:                if (orders.length == 1)
1203:                    comp = orders[0].getComparator();
1204:                else {
1205:                    List comps = null;
1206:                    Comparator curComp;
1207:                    for (int i = 0; i < orders.length; i++) {
1208:                        curComp = orders[i].getComparator();
1209:                        if (curComp != null) {
1210:                            if (comps == null)
1211:                                comps = new ArrayList(orders.length);
1212:                            if (i != comps.size())
1213:                                throw new MetaDataException(_loc.get(
1214:                                        "mixed-inmem-ordering", this ));
1215:                            comps.add(curComp);
1216:                        }
1217:                    }
1218:                    if (comps == null)
1219:                        comp = null;
1220:                    else
1221:                        comp = new ComparatorChain(comps);
1222:                }
1223:
1224:                if (comp == null)
1225:                    return val;
1226:
1227:                // sort
1228:                switch (getTypeCode()) {
1229:                case JavaTypes.ARRAY:
1230:                    List l = JavaTypes.toList(val, _elem.getType(), true);
1231:                    Collections.sort(l, comp);
1232:                    return JavaTypes.toArray(l, _elem.getType());
1233:                case JavaTypes.COLLECTION:
1234:                    if (val instanceof  List)
1235:                        Collections.sort((List) val, comp);
1236:                    return val;
1237:                default:
1238:                    throw new MetaDataException(_loc.get("cant-order", this ));
1239:                }
1240:            }
1241:
1242:            /**
1243:             * Whether the field is externalized.
1244:             */
1245:            public boolean isExternalized() {
1246:                return getExternalizerMethod() != null
1247:                        || getExternalValueMap() != null;
1248:            }
1249:
1250:            /**
1251:             * Convert the given field value to its external value through the
1252:             * provided externalizer, or return the value as-is if no externalizer.
1253:             */
1254:            public Object getExternalValue(Object val, StoreContext ctx) {
1255:                Map extValues = getExternalValueMap();
1256:                if (extValues != null) {
1257:                    Object foundVal = extValues.get(val);
1258:                    if (foundVal == null) {
1259:                        throw new UserException(_loc.get(
1260:                                "bad-externalized-value", new Object[] { val,
1261:                                        extValues.keySet(), this  })).setFatal(
1262:                                true).setFailedObject(val);
1263:                    } else {
1264:                        return foundVal;
1265:                    }
1266:                }
1267:
1268:                Method externalizer = getExternalizerMethod();
1269:                if (externalizer == null)
1270:                    return val;
1271:
1272:                // special case for queries: allow the given value to pass through
1273:                // as-is if it is already in externalized form
1274:                if (val != null
1275:                        && getType().isInstance(val)
1276:                        && (!getDeclaredType().isInstance(val) || getDeclaredType() == Object.class))
1277:                    return val;
1278:
1279:                try {
1280:                    // either invoke the static toExternal(val[, ctx]) method, or the
1281:                    // non-static val.toExternal([ctx]) method
1282:                    if (Modifier.isStatic(externalizer.getModifiers())) {
1283:                        if (externalizer.getParameterTypes().length == 1)
1284:                            return externalizer.invoke(null,
1285:                                    new Object[] { val });
1286:                        return externalizer.invoke(null, new Object[] { val,
1287:                                ctx });
1288:                    }
1289:                    if (val == null)
1290:                        return null;
1291:                    if (externalizer.getParameterTypes().length == 0)
1292:                        return externalizer.invoke(val, (Object[]) null);
1293:                    return externalizer.invoke(val, new Object[] { ctx });
1294:                } catch (OpenJPAException ke) {
1295:                    throw ke;
1296:                } catch (Exception e) {
1297:                    throw new MetaDataException(_loc.get("externalizer-err",
1298:                            this , Exceptions.toString(val), e.toString()))
1299:                            .setCause(e);
1300:                }
1301:            }
1302:
1303:            /**
1304:             * Return the result of passing the given external value through the
1305:             * factory to get the field value. If no factory is present,
1306:             * the given value is returned as-is.
1307:             */
1308:            public Object getFieldValue(Object val, StoreContext ctx) {
1309:                Map fieldValues = getFieldValueMap();
1310:                if (fieldValues != null)
1311:                    return fieldValues.get(val);
1312:
1313:                Member factory = getFactoryMethod();
1314:                if (factory == null)
1315:                    return val;
1316:
1317:                try {
1318:                    if (val == null && getNullValue() == NULL_DEFAULT)
1319:                        return AccessController.doPrivileged(J2DoPrivHelper
1320:                                .newInstanceAction(getDeclaredType()));
1321:
1322:                    // invoke either the constructor for the field type,
1323:                    // or the static type.toField(val[, ctx]) method
1324:                    if (factory instanceof  Constructor) {
1325:                        if (val == null)
1326:                            return null;
1327:                        return ((Constructor) factory)
1328:                                .newInstance(new Object[] { val });
1329:                    }
1330:
1331:                    Method meth = (Method) factory;
1332:                    if (meth.getParameterTypes().length == 1)
1333:                        return meth.invoke(null, new Object[] { val });
1334:                    return meth.invoke(null, new Object[] { val, ctx });
1335:                } catch (Exception e) {
1336:                    // unwrap cause
1337:                    if (e instanceof  InvocationTargetException) {
1338:                        Throwable t = ((InvocationTargetException) e)
1339:                                .getTargetException();
1340:                        if (t instanceof  Error)
1341:                            throw (Error) t;
1342:                        e = (Exception) t;
1343:
1344:                        // allow null values to cause NPEs and illegal arg exceptions
1345:                        // without error
1346:                        if (val == null
1347:                                && (e instanceof  NullPointerException || e instanceof  IllegalArgumentException))
1348:                            return null;
1349:                    }
1350:
1351:                    if (e instanceof  OpenJPAException)
1352:                        throw (OpenJPAException) e;
1353:                    if (e instanceof  PrivilegedActionException)
1354:                        e = ((PrivilegedActionException) e).getException();
1355:                    throw new MetaDataException(_loc.get("factory-err", this ,
1356:                            Exceptions.toString(val), e.toString()))
1357:                            .setCause(e);
1358:                }
1359:            }
1360:
1361:            /**
1362:             * The name of this field's externalizer, or null if none.
1363:             */
1364:            public String getExternalizer() {
1365:                return _extName;
1366:            }
1367:
1368:            /**
1369:             * The name of this field's externalizer, or null if none.
1370:             */
1371:            public void setExternalizer(String externalizer) {
1372:                _extName = externalizer;
1373:                _extMethod = DEFAULT_METHOD;
1374:            }
1375:
1376:            /**
1377:             * The name of this field's factory, or null if none.
1378:             */
1379:            public String getFactory() {
1380:                return _factName;
1381:            }
1382:
1383:            /**
1384:             * The name of this field's factory, or null if none.
1385:             */
1386:            public void setFactory(String factory) {
1387:                _factName = factory;
1388:                _factMethod = DEFAULT_METHOD;
1389:            }
1390:
1391:            /**
1392:             * Properties string mapping field values to external values.
1393:             */
1394:            public String getExternalValues() {
1395:                return _extString;
1396:            }
1397:
1398:            /**
1399:             * Properties string mapping field values to external values.
1400:             */
1401:            public void setExternalValues(String values) {
1402:                _extString = values;
1403:                _extValues = null;
1404:            }
1405:
1406:            /**
1407:             * Return the mapping of field values to external values.
1408:             */
1409:            public Map getExternalValueMap() {
1410:                parseExternalValues();
1411:                return _extValues;
1412:            }
1413:
1414:            /**
1415:             * Return the mapping of external values to field values.
1416:             */
1417:            public Map getFieldValueMap() {
1418:                parseExternalValues();
1419:                return _fieldValues;
1420:            }
1421:
1422:            /**
1423:             * Parse external values into maps.
1424:             */
1425:            private void parseExternalValues() {
1426:                if (_extValues != Collections.EMPTY_MAP
1427:                        && _fieldValues != Collections.EMPTY_MAP)
1428:                    return;
1429:
1430:                if (_extString == null) {
1431:                    _extValues = null;
1432:                    _fieldValues = null;
1433:                    return;
1434:                }
1435:
1436:                // parse string into options; this takes care of proper trimming etc
1437:                Options values = Configurations.parseProperties(_extString);
1438:                if (values.isEmpty())
1439:                    throw new MetaDataException(_loc.get("no-external-values",
1440:                            this , _extString));
1441:
1442:                Map extValues = new HashMap((int) (values.size() * 1.33 + 1));
1443:                Map fieldValues = new HashMap((int) (values.size() * 1.33 + 1));
1444:                Map.Entry entry;
1445:                Object extValue, fieldValue;
1446:                for (Iterator itr = values.entrySet().iterator(); itr.hasNext();) {
1447:                    entry = (Map.Entry) itr.next();
1448:                    fieldValue = transform((String) entry.getKey(),
1449:                            getDeclaredTypeCode());
1450:                    extValue = transform((String) entry.getValue(),
1451:                            getTypeCode());
1452:
1453:                    extValues.put(fieldValue, extValue);
1454:                    fieldValues.put(extValue, fieldValue);
1455:                }
1456:
1457:                _extValues = extValues;
1458:                _fieldValues = fieldValues;
1459:            }
1460:
1461:            /**
1462:             * Return the string value converted to the given type code. The string
1463:             * must be non-null and trimmed.
1464:             */
1465:            private Object transform(String val, int typeCode) {
1466:                if ("null".equals(val))
1467:                    return null;
1468:
1469:                switch (typeCode) {
1470:                case JavaTypes.BOOLEAN:
1471:                case JavaTypes.BOOLEAN_OBJ:
1472:                    return Boolean.valueOf(val);
1473:                case JavaTypes.BYTE:
1474:                case JavaTypes.BYTE_OBJ:
1475:                    return Byte.valueOf(val);
1476:                case JavaTypes.INT:
1477:                case JavaTypes.INT_OBJ:
1478:                    return Integer.valueOf(val);
1479:                case JavaTypes.LONG:
1480:                case JavaTypes.LONG_OBJ:
1481:                    return Long.valueOf(val);
1482:                case JavaTypes.SHORT:
1483:                case JavaTypes.SHORT_OBJ:
1484:                    return Short.valueOf(val);
1485:                case JavaTypes.DOUBLE:
1486:                case JavaTypes.DOUBLE_OBJ:
1487:                    return Double.valueOf(val);
1488:                case JavaTypes.FLOAT:
1489:                case JavaTypes.FLOAT_OBJ:
1490:                    return Float.valueOf(val);
1491:                case JavaTypes.CHAR:
1492:                case JavaTypes.CHAR_OBJ:
1493:                    return new Character(val.charAt(0));
1494:                case JavaTypes.STRING:
1495:                    return val;
1496:                }
1497:                throw new MetaDataException(_loc.get("bad-external-type", this ));
1498:            }
1499:
1500:            /**
1501:             * The externalizer method.
1502:             */
1503:            public Method getExternalizerMethod() {
1504:                if (_manage != MANAGE_PERSISTENT)
1505:                    return null;
1506:                if (_extMethod == DEFAULT_METHOD) {
1507:                    if (_extName != null) {
1508:                        _extMethod = findMethod(_extName);
1509:                        if (_extMethod == null)
1510:                            throw new MetaDataException(_loc.get(
1511:                                    "bad-externalizer", this , _extName));
1512:                    } else
1513:                        _extMethod = null;
1514:                }
1515:                return _extMethod;
1516:            }
1517:
1518:            /**
1519:             * The factory method or constructor.
1520:             */
1521:            public Member getFactoryMethod() {
1522:                if (_manage != MANAGE_PERSISTENT)
1523:                    return null;
1524:                if (_factMethod == DEFAULT_METHOD) {
1525:                    if (getExternalizerMethod() == null)
1526:                        _factMethod = null;
1527:                    else {
1528:                        try {
1529:                            if (_factName == null)
1530:                                _factMethod = getDeclaredType().getConstructor(
1531:                                        new Class[] { getType() });
1532:                            else
1533:                                _factMethod = findMethod(_factName);
1534:                        } catch (OpenJPAException ke) {
1535:                            throw ke;
1536:                        } catch (Exception e) {
1537:                        }
1538:
1539:                        if (!(_factMethod instanceof  Constructor)
1540:                                && !(_factMethod instanceof  Method))
1541:                            throw new MetaDataException(_loc.get("bad-factory",
1542:                                    this ));
1543:                    }
1544:                }
1545:                return _factMethod;
1546:            }
1547:
1548:            /**
1549:             * Find the method for the specified name. Possible forms are:
1550:             * <ul>
1551:             * <li>toExternalString</li>
1552:             * <li>MyFactoryClass.toExternalString</li>
1553:             * <li>com.company.MyFactoryClass.toExternalString</li>
1554:             * </ul>
1555:             *
1556:             * @param method the name of the method to locate
1557:             * @return the method for invocation
1558:             */
1559:            private Method findMethod(String method) {
1560:                if (StringUtils.isEmpty(method))
1561:                    return null;
1562:
1563:                // get class name and get package name divide on the last '.', so the
1564:                // names don't apply in this case, but the methods do what we want
1565:                String methodName = Strings.getClassName(method);
1566:                String clsName = Strings.getPackageName(method);
1567:
1568:                Class cls = null;
1569:                Class owner = _owner.getDescribedType();
1570:
1571:                if (clsName.length() == 0)
1572:                    cls = getDeclaredType();
1573:                else if (clsName.equals(owner.getName())
1574:                        || clsName.equals(Strings.getClassName(owner)))
1575:                    cls = owner;
1576:                else
1577:                    cls = JavaTypes.classForName(clsName, this );
1578:
1579:                // find the named method
1580:                Method[] methods = cls.getMethods();
1581:                Class[] params;
1582:                for (int i = 0; i < methods.length; i++) {
1583:                    if (methods[i].getName().equals(methodName)) {
1584:                        params = methods[i].getParameterTypes();
1585:
1586:                        // static factory methods require one argument or one argument
1587:                        // plus a ctx; non-static methods require zero arguments or
1588:                        // just a ctx
1589:                        if (Modifier.isStatic(methods[i].getModifiers())
1590:                                && (params.length == 1 || (params.length == 2 && isStoreContextParameter(params[1]))))
1591:                            return methods[i];
1592:                        if (!Modifier.isStatic(methods[i].getModifiers())
1593:                                && (params.length == 0 || (params.length == 1 && isStoreContextParameter(params[0]))))
1594:                            return methods[i];
1595:                    }
1596:                }
1597:
1598:                return null;
1599:            }
1600:
1601:            /**
1602:             * Return true if the given type is a store context type; we can't
1603:             * use the standard <code>isAssignableFrom</code> because of classloader
1604:             * oddness.
1605:             */
1606:            private static boolean isStoreContextParameter(Class type) {
1607:                return StoreContext.class.getName().equals(type.getName());
1608:            }
1609:
1610:            public boolean equals(Object other) {
1611:                if (other == this )
1612:                    return true;
1613:                if (!(other instanceof  FieldMetaData))
1614:                    return false;
1615:                return getFullName(true).equals(
1616:                        ((FieldMetaData) other).getFullName(true));
1617:            }
1618:
1619:            public int hashCode() {
1620:                return getFullName(true).hashCode();
1621:            }
1622:
1623:            public int compareTo(Object other) {
1624:                if (other == null)
1625:                    return 1;
1626:                return getFullName(true).compareTo(
1627:                        ((FieldMetaData) other).getFullName(true));
1628:            }
1629:
1630:            public String toString() {
1631:                return getFullName(true);
1632:            }
1633:
1634:            ////////////////////////
1635:            // Resolve and validate
1636:            ////////////////////////
1637:
1638:            /**
1639:             * Resolve mode for this field.
1640:             */
1641:            public int getResolve() {
1642:                return _resMode;
1643:            }
1644:
1645:            /**
1646:             * Resolve mode for this field.
1647:             */
1648:            public void setResolve(int mode) {
1649:                _resMode = mode;
1650:            }
1651:
1652:            /**
1653:             * Resolve mode for this field.
1654:             */
1655:            public void setResolve(int mode, boolean on) {
1656:                if (mode == MODE_NONE)
1657:                    _resMode = mode;
1658:                else if (on)
1659:                    _resMode |= mode;
1660:                else
1661:                    _resMode &= ~mode;
1662:            }
1663:
1664:            /**
1665:             * Resolve and validate metadata. Return true if already resolved.
1666:             */
1667:            public boolean resolve(int mode) {
1668:                if ((_resMode & mode) == mode)
1669:                    return true;
1670:                int cur = _resMode;
1671:                _resMode |= mode;
1672:
1673:                Log log = getRepository().getLog();
1674:                if (log.isTraceEnabled())
1675:                    log.trace(_loc.get("resolve-field", _owner + "@"
1676:                            + System.identityHashCode(_owner) + "." + _name));
1677:
1678:                // we only perform actions for metadata mode
1679:                if ((mode & MODE_META) == 0 || (cur & MODE_META) != 0)
1680:                    return false;
1681:
1682:                Method externalizer = getExternalizerMethod();
1683:                if (externalizer != null)
1684:                    setType(externalizer.getReturnType());
1685:
1686:                // only pass on metadata resolve mode so that metadata is always
1687:                // resolved before any other resolve modes our subclasses pass along
1688:                _val.resolve(MODE_META);
1689:                _key.resolve(MODE_META);
1690:                _elem.resolve(MODE_META);
1691:
1692:                MetaDataRepository repos = getRepository();
1693:                int validate = repos.getValidate();
1694:                if ((validate & MetaDataRepository.VALIDATE_META) != 0
1695:                        && (!ImplHelper.isManagedType(repos.getConfiguration(),
1696:                                _owner.getDescribedType()) || (validate & MetaDataRepository.VALIDATE_UNENHANCED) == 0)) {
1697:                    validateLRS();
1698:                    if ((validate & repos.VALIDATE_RUNTIME) == 0)
1699:                        validateSupportedType();
1700:                    validateValue();
1701:                    validateExtensionKeys();
1702:                }
1703:                return false;
1704:            }
1705:
1706:            /**
1707:             * Validate that this field can be used for LRS.
1708:             */
1709:            private void validateLRS() {
1710:                if (!isLRS())
1711:                    return;
1712:
1713:                // can't use lrs for arrays
1714:                if (getTypeCode() == JavaTypes.ARRAY)
1715:                    throw new MetaDataException(_loc.get("bad-lrs-array", this ));
1716:
1717:                // can't use lrs for extranalized vals
1718:                if (getExternalizerMethod() != null)
1719:                    throw new MetaDataException(_loc
1720:                            .get("bad-lrs-extern", this ));
1721:
1722:                // can't use lrs for concrete types
1723:                if (getType() != Collection.class && getType() != Map.class
1724:                        && getType() != Set.class)
1725:                    throw new MetaDataException(_loc.get("bad-lrs-concrete",
1726:                            this ));
1727:            }
1728:
1729:            /**
1730:             * Validate that this field is supported by the runtime.
1731:             */
1732:            private void validateSupportedType() {
1733:                // log warnings about things we don't handle
1734:                OpenJPAConfiguration conf = getRepository().getConfiguration();
1735:                Collection opts = conf.supportedOptions();
1736:                Log log = conf.getLog(conf.LOG_METADATA);
1737:                switch (getTypeCode()) {
1738:                case JavaTypes.PC:
1739:                    if (isEmbedded()
1740:                            && !opts.contains(conf.OPTION_EMBEDDED_RELATION)) {
1741:                        setEmbedded(false);
1742:                        if (log.isWarnEnabled())
1743:                            log.warn(_loc.get("cant-embed", this ));
1744:                    } else if (isEmbedded()
1745:                            && getDeclaredTypeCode() != JavaTypes.PC) {
1746:                        setEmbedded(false);
1747:                        if (log.isWarnEnabled())
1748:                            log.warn(_loc.get("cant-embed-extern", this ));
1749:                    }
1750:                    break;
1751:                case JavaTypes.COLLECTION:
1752:                    if (!opts.contains(conf.OPTION_TYPE_COLLECTION))
1753:                        throw new UnsupportedException(_loc.get(
1754:                                "type-not-supported", "Collection", this ));
1755:                    if (_elem.isEmbeddedPC()
1756:                            && !opts
1757:                                    .contains(conf.OPTION_EMBEDDED_COLLECTION_RELATION)) {
1758:                        _elem.setEmbedded(false);
1759:                        if (log.isWarnEnabled())
1760:                            log.warn(_loc.get("cant-embed-element", this ));
1761:                    }
1762:                    break;
1763:                case JavaTypes.ARRAY:
1764:                    if (!opts.contains(conf.OPTION_TYPE_ARRAY))
1765:                        throw new UnsupportedException(_loc.get(
1766:                                "type-not-supported", "Array", this ));
1767:                    if (_elem.isEmbeddedPC()
1768:                            && !opts
1769:                                    .contains(conf.OPTION_EMBEDDED_COLLECTION_RELATION)) {
1770:                        _elem.setEmbedded(false);
1771:                        if (log.isWarnEnabled())
1772:                            log.warn(_loc.get("cant-embed-element", this ));
1773:                    }
1774:                    break;
1775:                case JavaTypes.MAP:
1776:                    if (!opts.contains(conf.OPTION_TYPE_MAP))
1777:                        throw new UnsupportedException(_loc.get(
1778:                                "type-not-supported", "Map", this ));
1779:                    if (_elem.isEmbeddedPC()
1780:                            && !opts
1781:                                    .contains(conf.OPTION_EMBEDDED_MAP_RELATION)) {
1782:                        _elem.setEmbedded(false);
1783:                        if (log.isWarnEnabled())
1784:                            log.warn(_loc.get("cant-embed-element", this ));
1785:                    }
1786:                    if (_key.isEmbeddedPC()
1787:                            && !opts
1788:                                    .contains(conf.OPTION_EMBEDDED_MAP_RELATION)) {
1789:                        _key.setEmbedded(false);
1790:                        if (log.isWarnEnabled())
1791:                            log.warn(_loc.get("cant-embed-key", this ));
1792:                    }
1793:                    break;
1794:                }
1795:            }
1796:
1797:            /**
1798:             * Validate our value strategy.
1799:             */
1800:            private void validateValue() {
1801:                if (getExternalizerMethod() != null
1802:                        && getExternalValueMap() != null)
1803:                    throw new MetaDataException(_loc.get("extern-externvalues",
1804:                            this ));
1805:                if (getValueStrategy() == ValueStrategies.SEQUENCE
1806:                        && getValueSequenceName() == null)
1807:                    throw new MetaDataException(_loc.get("no-seq-name", this ));
1808:                ValueStrategies.assertSupported(getValueStrategy(), this ,
1809:                        "value strategy");
1810:            }
1811:
1812:            /**
1813:             * Copy state from the given field to this one. Do not copy mapping
1814:             * information.
1815:             */
1816:            public void copy(FieldMetaData field) {
1817:                super .copy(field);
1818:
1819:                _intermediate = field.usesIntermediate();
1820:                _implData = field.usesImplData();
1821:
1822:                // copy field-level info; use get methods to force resolution of
1823:                // lazy data
1824:                _proxyClass = field.getProxyType();
1825:                _initializer = field.getInitializer();
1826:                _transient = field.isTransient();
1827:                _nullValue = field.getNullValue();
1828:                _manage = field.getManagement();
1829:                _explicit = field.isExplicit();
1830:                _extName = field.getExternalizer();
1831:                _extMethod = DEFAULT_METHOD;
1832:                _factName = field.getFactory();
1833:                _factMethod = DEFAULT_METHOD;
1834:                _extString = field.getExternalValues();
1835:                _extValues = Collections.EMPTY_MAP;
1836:                _fieldValues = Collections.EMPTY_MAP;
1837:                _primKey = field.isPrimaryKey();
1838:                _backingMember = field._backingMember;
1839:                _enumField = field._enumField;
1840:                _lobField = field._lobField;
1841:                _serializableField = field._serializableField;
1842:                _generated = field._generated;
1843:
1844:                // embedded fields can't be versions
1845:                if (_owner.getEmbeddingMetaData() == null && _version == null)
1846:                    _version = (field.isVersion()) ? Boolean.TRUE
1847:                            : Boolean.FALSE;
1848:
1849:                // only copy this data if not already set explicitly in this instance
1850:                if (_dfg == 0) {
1851:                    _dfg = (field.isInDefaultFetchGroup()) ? DFG_TRUE
1852:                            : DFG_FALSE;
1853:                    if (field.isDefaultFetchGroupExplicit())
1854:                        _dfg |= DFG_EXPLICIT;
1855:                }
1856:                if (_fgSet == null && field._fgSet != null)
1857:                    _fgSet = new HashSet(field._fgSet);
1858:                if (_lfg == null)
1859:                    _lfg = field.getLoadFetchGroup();
1860:                if (_lrs == null)
1861:                    _lrs = (field.isLRS()) ? Boolean.TRUE : Boolean.FALSE;
1862:                if (_valStrategy == -1)
1863:                    _valStrategy = field.getValueStrategy();
1864:                if (_upStrategy == -1)
1865:                    _upStrategy = field.getUpdateStrategy();
1866:                if (ClassMetaData.DEFAULT_STRING.equals(_seqName)) {
1867:                    _seqName = field.getValueSequenceName();
1868:                    _seqMeta = null;
1869:                }
1870:                if (ClassMetaData.DEFAULT_STRING.equals(_inverse))
1871:                    _inverse = field.getInverse();
1872:
1873:                // copy value metadata
1874:                _val.copy(field);
1875:                _key.copy(field.getKey());
1876:                _elem.copy(field.getElement());
1877:            }
1878:
1879:            protected void addExtensionKeys(Collection exts) {
1880:                getRepository().getMetaDataFactory()
1881:                        .addFieldExtensionKeys(exts);
1882:            }
1883:
1884:            ///////////////
1885:            // Commentable
1886:            ///////////////
1887:
1888:            public String[] getComments() {
1889:                return (_comments == null) ? EMPTY_COMMENTS : _comments;
1890:            }
1891:
1892:            public void setComments(String[] comments) {
1893:                _comments = comments;
1894:            }
1895:
1896:            ////////////////////////////////
1897:            // ValueMetaData implementation
1898:            ////////////////////////////////
1899:
1900:            public FieldMetaData getFieldMetaData() {
1901:                return this ;
1902:            }
1903:
1904:            public Class getType() {
1905:                return _val.getType();
1906:            }
1907:
1908:            public void setType(Class type) {
1909:                _val.setType(type);
1910:                if (type.isArray())
1911:                    _elem.setType(type.getComponentType());
1912:                else if (type == Properties.class) {
1913:                    _key.setType(String.class);
1914:                    _elem.setType(String.class);
1915:                }
1916:            }
1917:
1918:            public int getTypeCode() {
1919:                return _val.getTypeCode();
1920:            }
1921:
1922:            public void setTypeCode(int code) {
1923:                _val.setTypeCode(code);
1924:            }
1925:
1926:            public boolean isTypePC() {
1927:                return _val.isTypePC();
1928:            }
1929:
1930:            public ClassMetaData getTypeMetaData() {
1931:                return _val.getTypeMetaData();
1932:            }
1933:
1934:            public Class getDeclaredType() {
1935:                return _val.getDeclaredType();
1936:            }
1937:
1938:            public void setDeclaredType(Class type) {
1939:                _val.setDeclaredType(type);
1940:                if (type.isArray())
1941:                    _elem.setDeclaredType(type.getComponentType());
1942:                else if (type == Properties.class) {
1943:                    _key.setDeclaredType(String.class);
1944:                    _elem.setDeclaredType(String.class);
1945:                }
1946:            }
1947:
1948:            public int getDeclaredTypeCode() {
1949:                return _val.getDeclaredTypeCode();
1950:            }
1951:
1952:            public void setDeclaredTypeCode(int type) {
1953:                _val.setDeclaredTypeCode(type);
1954:            }
1955:
1956:            public boolean isDeclaredTypePC() {
1957:                return _val.isDeclaredTypePC();
1958:            }
1959:
1960:            public ClassMetaData getDeclaredTypeMetaData() {
1961:                return _val.getDeclaredTypeMetaData();
1962:            }
1963:
1964:            public boolean isEmbedded() {
1965:                return _val.isEmbedded();
1966:            }
1967:
1968:            public void setEmbedded(boolean embedded) {
1969:                _val.setEmbedded(embedded);
1970:            }
1971:
1972:            public boolean isEmbeddedPC() {
1973:                return _val.isEmbeddedPC();
1974:            }
1975:
1976:            public ClassMetaData getEmbeddedMetaData() {
1977:                return _val.getEmbeddedMetaData();
1978:            }
1979:
1980:            public ClassMetaData addEmbeddedMetaData() {
1981:                return _val.addEmbeddedMetaData();
1982:            }
1983:
1984:            public int getCascadeDelete() {
1985:                return _val.getCascadeDelete();
1986:            }
1987:
1988:            public void setCascadeDelete(int delete) {
1989:                _val.setCascadeDelete(delete);
1990:            }
1991:
1992:            public int getCascadePersist() {
1993:                return _val.getCascadePersist();
1994:            }
1995:
1996:            public void setCascadePersist(int persist) {
1997:                _val.setCascadePersist(persist);
1998:            }
1999:
2000:            public int getCascadeAttach() {
2001:                return _val.getCascadeAttach();
2002:            }
2003:
2004:            public void setCascadeAttach(int attach) {
2005:                _val.setCascadeAttach(attach);
2006:            }
2007:
2008:            public int getCascadeRefresh() {
2009:                return _val.getCascadeRefresh();
2010:            }
2011:
2012:            public void setCascadeRefresh(int refresh) {
2013:                _val.setCascadeRefresh(refresh);
2014:            }
2015:
2016:            public boolean isSerialized() {
2017:                return _val.isSerialized();
2018:            }
2019:
2020:            public void setSerialized(boolean serialized) {
2021:                _val.setSerialized(serialized);
2022:            }
2023:
2024:            public String getValueMappedBy() {
2025:                return _val.getValueMappedBy();
2026:            }
2027:
2028:            public void setValueMappedBy(String mapped) {
2029:                _val.setValueMappedBy(mapped);
2030:            }
2031:
2032:            public FieldMetaData getValueMappedByMetaData() {
2033:                return _val.getValueMappedByMetaData();
2034:            }
2035:
2036:            public Class getTypeOverride() {
2037:                return _val.getTypeOverride();
2038:            }
2039:
2040:            public void setTypeOverride(Class type) {
2041:                _val.setTypeOverride(type);
2042:            }
2043:
2044:            public void copy(ValueMetaData vmd) {
2045:                _val.copy(vmd);
2046:            }
2047:
2048:            /**
2049:             * Check if this field is used by other field as "order by" value.
2050:             *
2051:             * @since 1.1.0
2052:             */
2053:            public boolean isUsedInOrderBy() {
2054:                return _usedInOrderBy;
2055:            }
2056:
2057:            /**
2058:             * Whether this field is used by other field as "order by" value .
2059:             *
2060:             * @since 1.1.0
2061:             */
2062:            public void setUsedInOrderBy(boolean isUsed) {
2063:                _usedInOrderBy = isUsed;
2064:            }
2065:
2066:            /**
2067:             * Serializable wrapper around a {@link Method} or {@link Field}. For 
2068:             * space considerations, this does not support {@link Constructor}s.
2069:             */
2070:            public static class MemberProvider implements  Externalizable {
2071:
2072:                private transient Member _member;
2073:
2074:                public MemberProvider() {
2075:                    // for externalization
2076:                }
2077:
2078:                MemberProvider(Member member) {
2079:                    if (member instanceof  Constructor)
2080:                        throw new IllegalArgumentException();
2081:
2082:                    _member = member;
2083:                }
2084:
2085:                public Member getMember() {
2086:                    return _member;
2087:                }
2088:
2089:                public void readExternal(ObjectInput in) throws IOException,
2090:                        ClassNotFoundException {
2091:                    boolean isField = in.readBoolean();
2092:                    Class cls = (Class) in.readObject();
2093:                    String memberName = (String) in.readObject();
2094:                    try {
2095:                        if (isField)
2096:                            _member = (Field) AccessController
2097:                                    .doPrivileged(J2DoPrivHelper
2098:                                            .getDeclaredFieldAction(cls,
2099:                                                    memberName));
2100:                        else {
2101:                            Class[] parameterTypes = (Class[]) in.readObject();
2102:                            _member = (Method) AccessController
2103:                                    .doPrivileged(J2DoPrivHelper
2104:                                            .getDeclaredMethodAction(cls,
2105:                                                    memberName, parameterTypes));
2106:                        }
2107:                    } catch (SecurityException e) {
2108:                        IOException ioe = new IOException(e.getMessage());
2109:                        ioe.initCause(e);
2110:                        throw ioe;
2111:                    } catch (PrivilegedActionException pae) {
2112:                        IOException ioe = new IOException(pae.getException()
2113:                                .getMessage());
2114:                        ioe.initCause(pae);
2115:                        throw ioe;
2116:                    }
2117:                }
2118:
2119:                public void writeExternal(ObjectOutput out) throws IOException {
2120:                    boolean isField = _member instanceof  Field;
2121:                    out.writeBoolean(isField);
2122:                    out.writeObject(_member.getDeclaringClass());
2123:                    out.writeObject(_member.getName());
2124:                    if (!isField)
2125:                        out.writeObject(((Method) _member).getParameterTypes());
2126:                }
2127:            }
2128:
2129:            public boolean isValueGenerated() {
2130:                return _generated;
2131:            }
2132:
2133:            public void setValueGenerated(boolean generated) {
2134:                this._generated = generated;
2135:            }
2136:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.