Source Code Cross Referenced for AnnotationPersistenceMappingParser.java in  » Database-ORM » openjpa » org » apache » openjpa » persistence » jdbc » 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.persistence.jdbc 
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.persistence.jdbc;
0020:
0021:        import java.lang.annotation.Annotation;
0022:        import java.lang.reflect.AnnotatedElement;
0023:        import java.lang.reflect.Modifier;
0024:        import java.security.AccessController;
0025:        import java.sql.Types;
0026:        import java.util.ArrayList;
0027:        import java.util.Arrays;
0028:        import java.util.HashMap;
0029:        import java.util.List;
0030:        import java.util.Map;
0031:        import javax.persistence.AssociationOverride;
0032:        import javax.persistence.AssociationOverrides;
0033:        import javax.persistence.AttributeOverride;
0034:        import javax.persistence.AttributeOverrides;
0035:        import javax.persistence.ColumnResult;
0036:        import javax.persistence.DiscriminatorColumn;
0037:        import javax.persistence.DiscriminatorValue;
0038:        import javax.persistence.EntityResult;
0039:        import javax.persistence.EnumType;
0040:        import javax.persistence.Enumerated;
0041:        import javax.persistence.FieldResult;
0042:        import javax.persistence.Inheritance;
0043:        import javax.persistence.JoinColumn;
0044:        import javax.persistence.JoinColumns;
0045:        import javax.persistence.JoinTable;
0046:        import javax.persistence.PrimaryKeyJoinColumn;
0047:        import javax.persistence.PrimaryKeyJoinColumns;
0048:        import javax.persistence.SecondaryTable;
0049:        import javax.persistence.SecondaryTables;
0050:        import javax.persistence.SqlResultSetMapping;
0051:        import javax.persistence.SqlResultSetMappings;
0052:        import javax.persistence.Table;
0053:        import javax.persistence.TableGenerator;
0054:        import javax.persistence.Temporal;
0055:        import javax.persistence.UniqueConstraint;
0056:
0057:        import org.apache.commons.lang.StringUtils;
0058:        import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
0059:        import org.apache.openjpa.jdbc.kernel.EagerFetchModes;
0060:        import org.apache.openjpa.jdbc.meta.ClassMapping;
0061:        import org.apache.openjpa.jdbc.meta.ClassMappingInfo;
0062:        import org.apache.openjpa.jdbc.meta.Discriminator;
0063:        import org.apache.openjpa.jdbc.meta.FieldMapping;
0064:        import org.apache.openjpa.jdbc.meta.MappingInfo;
0065:        import org.apache.openjpa.jdbc.meta.MappingRepository;
0066:        import org.apache.openjpa.jdbc.meta.QueryResultMapping;
0067:        import org.apache.openjpa.jdbc.meta.SequenceMapping;
0068:        import org.apache.openjpa.jdbc.meta.ValueMapping;
0069:        import org.apache.openjpa.jdbc.meta.ValueMappingInfo;
0070:        import org.apache.openjpa.jdbc.meta.strats.EnumValueHandler;
0071:        import org.apache.openjpa.jdbc.meta.strats.FlatClassStrategy;
0072:        import org.apache.openjpa.jdbc.meta.strats.FullClassStrategy;
0073:        import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
0074:        import org.apache.openjpa.jdbc.schema.Column;
0075:        import org.apache.openjpa.jdbc.schema.Unique;
0076:        import org.apache.openjpa.jdbc.sql.DBDictionary;
0077:        import org.apache.openjpa.lib.log.Log;
0078:        import org.apache.openjpa.lib.util.J2DoPriv5Helper;
0079:        import org.apache.openjpa.lib.util.Localizer;
0080:        import org.apache.openjpa.meta.ClassMetaData;
0081:        import org.apache.openjpa.meta.FieldMetaData;
0082:        import org.apache.openjpa.meta.JavaTypes;
0083:        import org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser;
0084:        import static org.apache.openjpa.persistence.jdbc.MappingTag.*;
0085:        import org.apache.openjpa.util.InternalException;
0086:        import org.apache.openjpa.util.MetaDataException;
0087:        import org.apache.openjpa.util.UnsupportedException;
0088:        import org.apache.openjpa.util.UserException;
0089:
0090:        /**
0091:         * Persistence annotation mapping parser.
0092:         *
0093:         * @author Pinaki Poddar
0094:         * @author Steve Kim
0095:         * @author Abe White
0096:         * @nojavadoc
0097:         */
0098:        public class AnnotationPersistenceMappingParser extends
0099:                AnnotationPersistenceMetaDataParser {
0100:
0101:            protected static final int TRUE = 1;
0102:            protected static final int FALSE = 2;
0103:
0104:            private static final Localizer _loc = Localizer
0105:                    .forPackage(AnnotationPersistenceMappingParser.class);
0106:
0107:            private static final Map<Class, MappingTag> _tags = new HashMap<Class, MappingTag>();
0108:
0109:            static {
0110:                _tags.put(AssociationOverride.class, ASSOC_OVERRIDE);
0111:                _tags.put(AssociationOverrides.class, ASSOC_OVERRIDES);
0112:                _tags.put(AttributeOverride.class, ATTR_OVERRIDE);
0113:                _tags.put(AttributeOverrides.class, ATTR_OVERRIDES);
0114:                _tags.put(javax.persistence.Column.class, COL);
0115:                _tags.put(ColumnResult.class, COLUMN_RESULT);
0116:                _tags.put(DiscriminatorColumn.class, DISCRIM_COL);
0117:                _tags.put(DiscriminatorValue.class, DISCRIM_VAL);
0118:                _tags.put(ElementColumn.class, ELEM_COL);
0119:                _tags.put(ElementColumns.class, ELEM_COLS);
0120:                _tags.put(ElementEmbeddedMapping.class, ELEM_EMBEDDED_MAPPING);
0121:                _tags.put(ElementStrategy.class, ELEM_STRAT);
0122:                _tags.put(EntityResult.class, ENTITY_RESULT);
0123:                _tags.put(Enumerated.class, ENUMERATED);
0124:                _tags.put(FieldResult.class, FIELD_RESULT);
0125:                _tags.put(Inheritance.class, INHERITANCE);
0126:                _tags.put(JoinColumn.class, JOIN_COL);
0127:                _tags.put(JoinColumns.class, JOIN_COLS);
0128:                _tags.put(JoinTable.class, JOIN_TABLE);
0129:                _tags.put(KeyColumn.class, KEY_COL);
0130:                _tags.put(KeyColumns.class, KEY_COLS);
0131:                _tags.put(KeyClassCriteria.class, KEY_CLASS_CRIT);
0132:                _tags.put(KeyEmbeddedMapping.class, KEY_EMBEDDED_MAPPING);
0133:                _tags.put(KeyForeignKey.class, KEY_FK);
0134:                _tags.put(KeyIndex.class, KEY_INDEX);
0135:                _tags.put(KeyJoinColumn.class, KEY_JOIN_COL);
0136:                _tags.put(KeyJoinColumns.class, KEY_JOIN_COLS);
0137:                _tags.put(KeyNonpolymorphic.class, KEY_NONPOLY);
0138:                _tags.put(KeyStrategy.class, KEY_STRAT);
0139:                _tags.put(PrimaryKeyJoinColumn.class, PK_JOIN_COL);
0140:                _tags.put(PrimaryKeyJoinColumns.class, PK_JOIN_COLS);
0141:                _tags.put(SecondaryTable.class, SECONDARY_TABLE);
0142:                _tags.put(SecondaryTables.class, SECONDARY_TABLES);
0143:                _tags.put(SqlResultSetMapping.class, SQL_RESULT_SET_MAPPING);
0144:                _tags.put(SqlResultSetMappings.class, SQL_RESULT_SET_MAPPINGS);
0145:                _tags.put(Table.class, TABLE);
0146:                _tags.put(Temporal.class, TEMPORAL);
0147:                _tags.put(TableGenerator.class, TABLE_GEN);
0148:                _tags.put(ClassCriteria.class, CLASS_CRIT);
0149:                _tags.put(Columns.class, COLS);
0150:                _tags.put(ContainerTable.class, CONTAINER_TABLE);
0151:                _tags.put(DataStoreIdColumn.class, DATASTORE_ID_COL);
0152:                _tags.put(DiscriminatorStrategy.class, DISCRIM_STRAT);
0153:                _tags.put(EagerFetchMode.class, EAGER_FETCH_MODE);
0154:                _tags.put(ElementClassCriteria.class, ELEM_CLASS_CRIT);
0155:                _tags.put(ElementForeignKey.class, ELEM_FK);
0156:                _tags.put(ElementIndex.class, ELEM_INDEX);
0157:                _tags.put(ElementJoinColumn.class, ELEM_JOIN_COL);
0158:                _tags.put(ElementJoinColumns.class, ELEM_JOIN_COLS);
0159:                _tags.put(ElementNonpolymorphic.class, ELEM_NONPOLY);
0160:                _tags.put(EmbeddedMapping.class, EMBEDDED_MAPPING);
0161:                _tags.put(ForeignKey.class, FK);
0162:                _tags.put(Index.class, INDEX);
0163:                _tags.put(MappingOverride.class, MAPPING_OVERRIDE);
0164:                _tags.put(MappingOverrides.class, MAPPING_OVERRIDES);
0165:                _tags.put(Nonpolymorphic.class, NONPOLY);
0166:                _tags.put(OrderColumn.class, ORDER_COL);
0167:                _tags.put(Strategy.class, STRAT);
0168:                _tags.put(SubclassFetchMode.class, SUBCLASS_FETCH_MODE);
0169:                _tags.put(Unique.class, UNIQUE);
0170:                _tags.put(VersionColumn.class, VERSION_COL);
0171:                _tags.put(VersionColumns.class, VERSION_COLS);
0172:                _tags.put(VersionStrategy.class, VERSION_STRAT);
0173:                _tags.put(XEmbeddedMapping.class, X_EMBEDDED_MAPPING);
0174:                _tags.put(XJoinColumn.class, X_JOIN_COL);
0175:                _tags.put(XJoinColumns.class, X_JOIN_COLS);
0176:                _tags.put(XMappingOverride.class, X_MAPPING_OVERRIDE);
0177:                _tags.put(XMappingOverrides.class, X_MAPPING_OVERRIDES);
0178:                _tags.put(XSecondaryTable.class, X_SECONDARY_TABLE);
0179:                _tags.put(XSecondaryTables.class, X_SECONDARY_TABLES);
0180:                _tags.put(XTable.class, X_TABLE);
0181:            }
0182:
0183:            public AnnotationPersistenceMappingParser(JDBCConfiguration conf) {
0184:                super (conf);
0185:            }
0186:
0187:            @Override
0188:            protected void parsePackageMappingAnnotations(Package pkg) {
0189:                MappingTag tag;
0190:                for (Annotation anno : pkg.getDeclaredAnnotations()) {
0191:                    tag = _tags.get(anno.annotationType());
0192:                    if (tag == null) {
0193:                        handleUnknownPackageMappingAnnotation(pkg, anno);
0194:                        continue;
0195:                    }
0196:
0197:                    switch (tag) {
0198:                    case TABLE_GEN:
0199:                        parseTableGenerator(pkg, (TableGenerator) anno);
0200:                        break;
0201:                    default:
0202:                        throw new UnsupportedException(_loc.get("unsupported",
0203:                                pkg, anno.toString()));
0204:                    }
0205:                }
0206:            }
0207:
0208:            /**
0209:             * Allow subclasses to handle unknown annotations.
0210:             */
0211:            protected boolean handleUnknownPackageMappingAnnotation(
0212:                    Package pkg, Annotation anno) {
0213:                return false;
0214:            }
0215:
0216:            /**
0217:             * Parse @TableGenerator.
0218:             */
0219:            private void parseTableGenerator(AnnotatedElement el,
0220:                    TableGenerator gen) {
0221:                String name = gen.name();
0222:                if (StringUtils.isEmpty(name))
0223:                    throw new MetaDataException(_loc.get("no-gen-name", el));
0224:
0225:                Log log = getLog();
0226:                if (log.isTraceEnabled())
0227:                    log.trace(_loc.get("parse-gen", name));
0228:
0229:                SequenceMapping meta = (SequenceMapping) getRepository()
0230:                        .getCachedSequenceMetaData(name);
0231:                if (meta != null) {
0232:                    if (log.isWarnEnabled())
0233:                        log.warn(_loc.get("dup-gen", name, el));
0234:                    return;
0235:                }
0236:
0237:                meta = (SequenceMapping) getRepository().addSequenceMetaData(
0238:                        name);
0239:                meta.setSequencePlugin(SequenceMapping.IMPL_VALUE_TABLE);
0240:                meta.setTable(toTableName(gen.schema(), gen.table()));
0241:                meta.setPrimaryKeyColumn(gen.pkColumnName());
0242:                meta.setSequenceColumn(gen.valueColumnName());
0243:                meta.setPrimaryKeyValue(gen.pkColumnValue());
0244:                meta.setInitialValue(gen.initialValue());
0245:                meta.setAllocate(gen.allocationSize());
0246:                meta.setSource(getSourceFile(), (el instanceof  Class) ? el
0247:                        : null, meta.SRC_ANNOTATIONS);
0248:
0249:                //### EJB3
0250:                if (gen.uniqueConstraints().length > 0 && log.isWarnEnabled())
0251:                    log.warn(_loc.get("unique-constraints", name));
0252:            }
0253:
0254:            @Override
0255:            protected void parseClassMappingAnnotations(ClassMetaData meta) {
0256:                ClassMapping cm = (ClassMapping) meta;
0257:                Class cls = cm.getDescribedType();
0258:
0259:                MappingTag tag;
0260:                for (Annotation anno : cls.getDeclaredAnnotations()) {
0261:                    tag = _tags.get(anno.annotationType());
0262:                    if (tag == null) {
0263:                        handleUnknownClassMappingAnnotation(cm, anno);
0264:                        continue;
0265:                    }
0266:
0267:                    switch (tag) {
0268:                    case ASSOC_OVERRIDE:
0269:                        parseAssociationOverrides(cm,
0270:                                (AssociationOverride) anno);
0271:                        break;
0272:                    case ASSOC_OVERRIDES:
0273:                        parseAssociationOverrides(cm,
0274:                                ((AssociationOverrides) anno).value());
0275:                        break;
0276:                    case ATTR_OVERRIDE:
0277:                        parseAttributeOverrides(cm, (AttributeOverride) anno);
0278:                        break;
0279:                    case ATTR_OVERRIDES:
0280:                        parseAttributeOverrides(cm, ((AttributeOverrides) anno)
0281:                                .value());
0282:                        break;
0283:                    case DISCRIM_COL:
0284:                        parseDiscriminatorColumn(cm, (DiscriminatorColumn) anno);
0285:                        break;
0286:                    case DISCRIM_VAL:
0287:                        cm.getDiscriminator().getMappingInfo().setValue(
0288:                                ((DiscriminatorValue) anno).value());
0289:                        if (Modifier.isAbstract(cm.getDescribedType()
0290:                                .getModifiers())
0291:                                && getLog().isInfoEnabled()) {
0292:                            getLog().info(
0293:                                    _loc.get("discriminator-on-abstract-class",
0294:                                            cm.getDescribedType().getName()));
0295:                        }
0296:                        break;
0297:                    case INHERITANCE:
0298:                        parseInheritance(cm, (Inheritance) anno);
0299:                        break;
0300:                    case PK_JOIN_COL:
0301:                        parsePrimaryKeyJoinColumns(cm,
0302:                                (PrimaryKeyJoinColumn) anno);
0303:                        break;
0304:                    case PK_JOIN_COLS:
0305:                        parsePrimaryKeyJoinColumns(cm,
0306:                                ((PrimaryKeyJoinColumns) anno).value());
0307:                        break;
0308:                    case SECONDARY_TABLE:
0309:                        parseSecondaryTables(cm, (SecondaryTable) anno);
0310:                        break;
0311:                    case SECONDARY_TABLES:
0312:                        parseSecondaryTables(cm, ((SecondaryTables) anno)
0313:                                .value());
0314:                        break;
0315:                    case SQL_RESULT_SET_MAPPING:
0316:                        parseSQLResultSetMappings(cm,
0317:                                (SqlResultSetMapping) anno);
0318:                        break;
0319:                    case SQL_RESULT_SET_MAPPINGS:
0320:                        parseSQLResultSetMappings(cm,
0321:                                ((SqlResultSetMappings) anno).value());
0322:                        break;
0323:                    case TABLE:
0324:                        parseTable(cm, (Table) anno);
0325:                        break;
0326:                    case TABLE_GEN:
0327:                        parseTableGenerator(cls, (TableGenerator) anno);
0328:                        break;
0329:                    case DATASTORE_ID_COL:
0330:                        parseDataStoreIdColumn(cm, (DataStoreIdColumn) anno);
0331:                        break;
0332:                    case DISCRIM_STRAT:
0333:                        cm.getDiscriminator().getMappingInfo().setStrategy(
0334:                                ((DiscriminatorStrategy) anno).value());
0335:                        break;
0336:                    case FK:
0337:                        parseForeignKey(cm.getMappingInfo(), (ForeignKey) anno);
0338:                        break;
0339:                    case MAPPING_OVERRIDE:
0340:                        parseMappingOverrides(cm, (MappingOverride) anno);
0341:                        break;
0342:                    case MAPPING_OVERRIDES:
0343:                        parseMappingOverrides(cm, ((MappingOverrides) anno)
0344:                                .value());
0345:                        break;
0346:                    case STRAT:
0347:                        cm.getMappingInfo().setStrategy(
0348:                                ((Strategy) anno).value());
0349:                        break;
0350:                    case SUBCLASS_FETCH_MODE:
0351:                        cm
0352:                                .setSubclassFetchMode(toEagerFetchModeConstant(((SubclassFetchMode) anno)
0353:                                        .value()));
0354:                        break;
0355:                    case VERSION_COL:
0356:                        parseVersionColumns(cm, (VersionColumn) anno);
0357:                        break;
0358:                    case VERSION_COLS:
0359:                        parseVersionColumns(cm, ((VersionColumns) anno).value());
0360:                        break;
0361:                    case VERSION_STRAT:
0362:                        cm.getVersion().getMappingInfo().setStrategy(
0363:                                ((VersionStrategy) anno).value());
0364:                        break;
0365:                    case X_MAPPING_OVERRIDE:
0366:                        parseMappingOverrides(cm, (XMappingOverride) anno);
0367:                        break;
0368:                    case X_MAPPING_OVERRIDES:
0369:                        parseMappingOverrides(cm, ((XMappingOverrides) anno)
0370:                                .value());
0371:                        break;
0372:                    case X_TABLE:
0373:                    case X_SECONDARY_TABLE:
0374:                    case X_SECONDARY_TABLES:
0375:                        // no break; not supported yet
0376:                    default:
0377:                        throw new UnsupportedException(_loc.get("unsupported",
0378:                                cm, anno));
0379:                    }
0380:                }
0381:            }
0382:
0383:            /**
0384:             * Allow subclasses to handle unknown annotations.
0385:             */
0386:            protected boolean handleUnknownClassMappingAnnotation(
0387:                    ClassMapping cls, Annotation anno) {
0388:                return false;
0389:            }
0390:
0391:            /**
0392:             * Parse @AssociationOverride(s).
0393:             */
0394:            private void parseAssociationOverrides(ClassMapping cm,
0395:                    AssociationOverride... assocs) {
0396:                FieldMapping sup;
0397:                JoinColumn[] scols;
0398:                int unique;
0399:                List<Column> jcols;
0400:                for (AssociationOverride assoc : assocs) {
0401:                    if (StringUtils.isEmpty(assoc.name()))
0402:                        throw new MetaDataException(_loc.get(
0403:                                "no-override-name", cm));
0404:                    sup = (FieldMapping) cm.getDefinedSuperclassField(assoc
0405:                            .name());
0406:                    if (sup == null)
0407:                        sup = (FieldMapping) cm.addDefinedSuperclassField(assoc
0408:                                .name(), Object.class, Object.class);
0409:                    scols = assoc.joinColumns();
0410:                    if (scols == null || scols.length == 0)
0411:                        continue;
0412:
0413:                    jcols = new ArrayList<Column>(scols.length);
0414:                    unique = 0;
0415:                    for (JoinColumn scol : scols) {
0416:                        unique |= (scol.unique()) ? TRUE : FALSE;
0417:                        jcols.add(newColumn(scol));
0418:                    }
0419:                    setColumns(sup, sup.getValueInfo(), jcols, unique);
0420:                }
0421:            }
0422:
0423:            /**
0424:             * Parse @AttributeOverride(s).
0425:             */
0426:            private void parseAttributeOverrides(ClassMapping cm,
0427:                    AttributeOverride... attrs) {
0428:                FieldMapping sup;
0429:                for (AttributeOverride attr : attrs) {
0430:                    if (StringUtils.isEmpty(attr.name()))
0431:                        throw new MetaDataException(_loc.get(
0432:                                "no-override-name", cm));
0433:                    sup = (FieldMapping) cm.getDefinedSuperclassField(attr
0434:                            .name());
0435:                    if (sup == null)
0436:                        sup = (FieldMapping) cm.addDefinedSuperclassField(attr
0437:                                .name(), Object.class, Object.class);
0438:                    if (attr.column() != null)
0439:                        parseColumns(sup, attr.column());
0440:                }
0441:            }
0442:
0443:            /**
0444:             * Parse inheritance @PrimaryKeyJoinColumn(s).
0445:             */
0446:            private void parsePrimaryKeyJoinColumns(ClassMapping cm,
0447:                    PrimaryKeyJoinColumn... joins) {
0448:                List<Column> cols = new ArrayList<Column>(joins.length);
0449:                for (PrimaryKeyJoinColumn join : joins)
0450:                    cols.add(newColumn(join));
0451:                cm.getMappingInfo().setColumns(cols);
0452:            }
0453:
0454:            /**
0455:             * Create a new schema column with information from the given annotation.
0456:             */
0457:            private static Column newColumn(PrimaryKeyJoinColumn join) {
0458:                Column col = new Column();
0459:                col.setFlag(Column.FLAG_PK_JOIN, true);
0460:                if (!StringUtils.isEmpty(join.name()))
0461:                    col.setName(join.name());
0462:                if (!StringUtils.isEmpty(join.columnDefinition()))
0463:                    col.setTypeName(join.columnDefinition());
0464:                if (!StringUtils.isEmpty(join.referencedColumnName()))
0465:                    col.setTarget(join.referencedColumnName());
0466:                return col;
0467:            }
0468:
0469:            /**
0470:             * Parse @SecondaryTable(s).
0471:             */
0472:            private void parseSecondaryTables(ClassMapping cm,
0473:                    SecondaryTable... tables) {
0474:                ClassMappingInfo info = cm.getMappingInfo();
0475:                Log log = getLog();
0476:
0477:                String name;
0478:                List<Column> joins;
0479:                boolean warnUnique = false;
0480:                for (SecondaryTable table : tables) {
0481:                    name = table.name();
0482:                    if (StringUtils.isEmpty(name))
0483:                        throw new MetaDataException(_loc.get("second-name", cm));
0484:                    if (!StringUtils.isEmpty(table.schema()))
0485:                        name = table.schema() + "." + name;
0486:                    if (table.pkJoinColumns().length > 0) {
0487:                        joins = new ArrayList<Column>(
0488:                                table.pkJoinColumns().length);
0489:                        for (PrimaryKeyJoinColumn join : table.pkJoinColumns())
0490:                            joins.add(newColumn(join));
0491:                        info.setSecondaryTableJoinColumns(name, joins);
0492:                    }
0493:                    warnUnique |= table.uniqueConstraints().length > 0;
0494:                }
0495:
0496:                //### EJB3
0497:                if (warnUnique && log.isWarnEnabled())
0498:                    log.warn(_loc.get("unique-constraints", cm));
0499:            }
0500:
0501:            /**
0502:             * Set class table.
0503:             */
0504:            private void parseTable(ClassMapping cm, Table table) {
0505:                String tableName = toTableName(table.schema(), table.name());
0506:                if (tableName != null)
0507:                    cm.getMappingInfo().setTableName(tableName);
0508:
0509:                for (UniqueConstraint uniqueConstraint : table
0510:                        .uniqueConstraints()) {
0511:                    Unique unique = newUnique(cm, null, uniqueConstraint
0512:                            .columnNames());
0513:                    cm.getMappingInfo().addUnique(unique);
0514:                }
0515:            }
0516:
0517:            /**
0518:             * Form a qualified table name from a schema and table name.
0519:             */
0520:            private static String toTableName(String schema, String table) {
0521:                if (StringUtils.isEmpty(table))
0522:                    return null;
0523:                if (StringUtils.isEmpty(schema))
0524:                    return table;
0525:                return schema + "." + table;
0526:            }
0527:
0528:            /**
0529:             * Parses the given annotation to create and cache a
0530:             * {@link SQLResultSetMappingMetaData}.
0531:             */
0532:            private void parseSQLResultSetMappings(ClassMapping cm,
0533:                    SqlResultSetMapping... annos) {
0534:                MappingRepository repos = (MappingRepository) getRepository();
0535:                Log log = getLog();
0536:                for (SqlResultSetMapping anno : annos) {
0537:                    if (log.isTraceEnabled())
0538:                        log.trace(_loc.get("parse-sqlrsmapping", anno.name()));
0539:
0540:                    QueryResultMapping result = repos
0541:                            .getCachedQueryResultMapping(null, anno.name());
0542:                    if (result != null) {
0543:                        if (log.isWarnEnabled())
0544:                            log.warn(_loc.get("dup-sqlrsmapping", anno.name(),
0545:                                    cm));
0546:                        continue;
0547:                    }
0548:
0549:                    result = repos.addQueryResultMapping(null, anno.name());
0550:                    result.setSource(getSourceFile(), cm.getDescribedType(),
0551:                            result.SRC_ANNOTATIONS);
0552:
0553:                    for (EntityResult entity : anno.entities()) {
0554:                        QueryResultMapping.PCResult entityResult = result
0555:                                .addPCResult(entity.entityClass());
0556:                        if (!StringUtils.isEmpty(entity.discriminatorColumn()))
0557:                            entityResult.addMapping(entityResult.DISCRIMINATOR,
0558:                                    entity.discriminatorColumn());
0559:
0560:                        for (FieldResult field : entity.fields())
0561:                            entityResult.addMapping(field.name(), field
0562:                                    .column());
0563:                    }
0564:                    for (ColumnResult column : anno.columns())
0565:                        result.addColumnResult(column.name());
0566:                }
0567:            }
0568:
0569:            /**
0570:             * Parse @DiscriminatorColumn.
0571:             */
0572:            private void parseDiscriminatorColumn(ClassMapping cm,
0573:                    DiscriminatorColumn dcol) {
0574:                Column col = new Column();
0575:                if (!StringUtils.isEmpty(dcol.name()))
0576:                    col.setName(dcol.name());
0577:                if (!StringUtils.isEmpty(dcol.columnDefinition()))
0578:                    col.setTypeName(dcol.columnDefinition());
0579:                Discriminator discrim = cm.getDiscriminator();
0580:                switch (dcol.discriminatorType()) {
0581:                case CHAR:
0582:                    col.setJavaType(JavaTypes.CHAR);
0583:                    discrim.setJavaType(JavaTypes.CHAR);
0584:                    break;
0585:                case INTEGER:
0586:                    col.setJavaType(JavaTypes.INT);
0587:                    if (dcol.length() != 31)
0588:                        col.setSize(dcol.length());
0589:                    discrim.setJavaType(JavaTypes.INT);
0590:                    break;
0591:                default:
0592:                    col.setJavaType(JavaTypes.STRING);
0593:                    col.setSize(dcol.length());
0594:                    discrim.setJavaType(JavaTypes.STRING);
0595:                }
0596:                cm.getDiscriminator().getMappingInfo().setColumns(
0597:                        Arrays.asList(new Column[] { col }));
0598:            }
0599:
0600:            /**
0601:             * Parse @Inheritance.
0602:             */
0603:            private void parseInheritance(ClassMapping cm, Inheritance inherit) {
0604:                ClassMappingInfo info = cm.getMappingInfo();
0605:                switch (inherit.strategy()) {
0606:                case SINGLE_TABLE:
0607:                    info.setHierarchyStrategy(FlatClassStrategy.ALIAS);
0608:                    break;
0609:                case JOINED:
0610:                    info.setHierarchyStrategy(VerticalClassStrategy.ALIAS);
0611:                    break;
0612:                case TABLE_PER_CLASS:
0613:                    info.setHierarchyStrategy(FullClassStrategy.ALIAS);
0614:                    break;
0615:                default:
0616:                    throw new InternalException();
0617:                }
0618:            }
0619:
0620:            /**
0621:             * Parse class-level @MappingOverride(s).
0622:             */
0623:            private void parseMappingOverrides(ClassMapping cm,
0624:                    MappingOverride... overs) {
0625:                FieldMapping sup;
0626:                for (MappingOverride over : overs) {
0627:                    if (StringUtils.isEmpty(over.name()))
0628:                        throw new MetaDataException(_loc.get(
0629:                                "no-override-name", cm));
0630:                    sup = (FieldMapping) cm.getDefinedSuperclassField(over
0631:                            .name());
0632:                    if (sup == null)
0633:                        sup = (FieldMapping) cm.addDefinedSuperclassField(over
0634:                                .name(), Object.class, Object.class);
0635:                    populate(sup, over);
0636:                }
0637:            }
0638:
0639:            /**
0640:             * Populate the given field from override data.
0641:             */
0642:            private void populate(FieldMapping fm, MappingOverride over) {
0643:                if (over.containerTable().specified())
0644:                    parseContainerTable(fm, over.containerTable());
0645:                parseColumns(fm, over.columns());
0646:                parseXJoinColumns(fm, fm.getValueInfo(), true, over
0647:                        .joinColumns());
0648:                parseElementJoinColumns(fm, over.elementJoinColumns());
0649:            }
0650:
0651:            /**
0652:             * Parse datastore identity information in @DataStoreIdColumn.
0653:             */
0654:            private void parseDataStoreIdColumn(ClassMapping cm,
0655:                    DataStoreIdColumn id) {
0656:                Column col = new Column();
0657:                if (!StringUtils.isEmpty(id.name()))
0658:                    col.setName(id.name());
0659:                if (!StringUtils.isEmpty(id.columnDefinition()))
0660:                    col.setTypeName(id.columnDefinition());
0661:                if (id.precision() != 0)
0662:                    col.setSize(id.precision());
0663:                col.setFlag(Column.FLAG_UNINSERTABLE, !id.insertable());
0664:                col.setFlag(Column.FLAG_UNUPDATABLE, !id.updatable());
0665:                cm.getMappingInfo().setColumns(
0666:                        Arrays.asList(new Column[] { col }));
0667:            }
0668:
0669:            /**
0670:             * Parse the given foreign key.
0671:             */
0672:            private void parseForeignKey(MappingInfo info, ForeignKey fk) {
0673:                parseForeignKey(info, fk.name(), fk.enabled(), fk.deferred(),
0674:                        fk.deleteAction(), fk.updateAction());
0675:            }
0676:
0677:            /**
0678:             * Set foreign key data on the given mapping info.
0679:             */
0680:            protected void parseForeignKey(MappingInfo info, String name,
0681:                    boolean enabled, boolean deferred,
0682:                    ForeignKeyAction deleteAction, ForeignKeyAction updateAction) {
0683:                if (!enabled) {
0684:                    info.setCanForeignKey(false);
0685:                    return;
0686:                }
0687:
0688:                org.apache.openjpa.jdbc.schema.ForeignKey fk = new org.apache.openjpa.jdbc.schema.ForeignKey();
0689:                if (!StringUtils.isEmpty(name))
0690:                    fk.setName(name);
0691:                fk.setDeferred(deferred);
0692:                fk.setDeleteAction(toForeignKeyAction(deleteAction));
0693:                fk.setUpdateAction(toForeignKeyAction(updateAction));
0694:                info.setForeignKey(fk);
0695:            }
0696:
0697:            /**
0698:             * Convert our FK action enum to an internal OpenJPA action.
0699:             */
0700:            private int toForeignKeyAction(ForeignKeyAction action) {
0701:                switch (action) {
0702:                case RESTRICT:
0703:                    return org.apache.openjpa.jdbc.schema.ForeignKey.ACTION_RESTRICT;
0704:                case CASCADE:
0705:                    return org.apache.openjpa.jdbc.schema.ForeignKey.ACTION_CASCADE;
0706:                case NULL:
0707:                    return org.apache.openjpa.jdbc.schema.ForeignKey.ACTION_NULL;
0708:                case DEFAULT:
0709:                    return org.apache.openjpa.jdbc.schema.ForeignKey.ACTION_DEFAULT;
0710:                default:
0711:                    throw new InternalException();
0712:                }
0713:            }
0714:
0715:            /**
0716:             * Parse the given index.
0717:             */
0718:            private void parseIndex(MappingInfo info, Index idx) {
0719:                parseIndex(info, idx.name(), idx.enabled(), idx.unique());
0720:            }
0721:
0722:            /**
0723:             * Set index data on the given mapping info.
0724:             */
0725:            protected void parseIndex(MappingInfo info, String name,
0726:                    boolean enabled, boolean unique) {
0727:                if (!enabled) {
0728:                    info.setCanIndex(false);
0729:                    return;
0730:                }
0731:
0732:                org.apache.openjpa.jdbc.schema.Index idx = new org.apache.openjpa.jdbc.schema.Index();
0733:                if (!StringUtils.isEmpty(name))
0734:                    idx.setName(name);
0735:                idx.setUnique(unique);
0736:                info.setIndex(idx);
0737:            }
0738:
0739:            /**
0740:             * Set unique data on the given mapping info.
0741:             */
0742:            private void parseUnique(FieldMapping fm,
0743:                    org.apache.openjpa.persistence.jdbc.Unique anno) {
0744:                ValueMappingInfo info = fm.getValueInfo();
0745:                if (!anno.enabled()) {
0746:                    info.setCanUnique(false);
0747:                    return;
0748:                }
0749:
0750:                org.apache.openjpa.jdbc.schema.Unique unq = new org.apache.openjpa.jdbc.schema.Unique();
0751:                if (!StringUtils.isEmpty(anno.name()))
0752:                    unq.setName(anno.name());
0753:                unq.setDeferred(anno.deferred());
0754:                info.setUnique(unq);
0755:            }
0756:
0757:            /**
0758:             * Parse @VersionColumn(s).
0759:             */
0760:            private void parseVersionColumns(ClassMapping cm,
0761:                    VersionColumn... vcols) {
0762:                if (vcols.length == 0)
0763:                    return;
0764:
0765:                List<Column> cols = new ArrayList<Column>(vcols.length);
0766:                for (VersionColumn vcol : vcols)
0767:                    cols.add(newColumn(vcol));
0768:                cm.getVersion().getMappingInfo().setColumns(cols);
0769:            }
0770:
0771:            /**
0772:             * Create a new schema column with information from the given annotation.
0773:             */
0774:            private static Column newColumn(VersionColumn anno) {
0775:                Column col = new Column();
0776:                if (!StringUtils.isEmpty(anno.name()))
0777:                    col.setName(anno.name());
0778:                if (!StringUtils.isEmpty(anno.columnDefinition()))
0779:                    col.setTypeName(anno.columnDefinition());
0780:                if (anno.precision() != 0)
0781:                    col.setSize(anno.precision());
0782:                else if (anno.length() != 255)
0783:                    col.setSize(anno.length());
0784:                col.setNotNull(!anno.nullable());
0785:                col.setDecimalDigits(anno.scale());
0786:                col.setFlag(Column.FLAG_UNINSERTABLE, !anno.insertable());
0787:                col.setFlag(Column.FLAG_UNUPDATABLE, !anno.updatable());
0788:                return col;
0789:            }
0790:
0791:            /**
0792:             * Parse class-level @XMappingOverride(s).
0793:             */
0794:            private void parseMappingOverrides(ClassMapping cm,
0795:                    XMappingOverride... overs) {
0796:                FieldMapping sup;
0797:                for (XMappingOverride over : overs) {
0798:                    if (StringUtils.isEmpty(over.name()))
0799:                        throw new MetaDataException(_loc.get(
0800:                                "no-override-name", cm));
0801:                    sup = (FieldMapping) cm.getDefinedSuperclassField(over
0802:                            .name());
0803:                    if (sup == null)
0804:                        sup = (FieldMapping) cm.addDefinedSuperclassField(over
0805:                                .name(), Object.class, Object.class);
0806:                    populate(sup, over);
0807:                }
0808:            }
0809:
0810:            /**
0811:             * Populate the given field from override data.
0812:             */
0813:            private void populate(FieldMapping fm, XMappingOverride over) {
0814:                if (over.containerTable().specified())
0815:                    parseContainerTable(fm, over.containerTable());
0816:                parseColumns(fm, over.columns());
0817:                parseXJoinColumns(fm, fm.getValueInfo(), true, over
0818:                        .joinColumns());
0819:                parseElementColumns(fm, over.elementColumns());
0820:                parseElementJoinColumns(fm, over.elementJoinColumns());
0821:                parseKeyColumns(fm, over.keyColumns());
0822:                parseKeyJoinColumns(fm, over.keyJoinColumns());
0823:            }
0824:
0825:            /**
0826:             * Parse @ElementColumn(s).
0827:             */
0828:            private void parseElementColumns(FieldMapping fm,
0829:                    ElementColumn... pcols) {
0830:                if (pcols.length == 0)
0831:                    return;
0832:
0833:                List<Column> cols = new ArrayList<Column>(pcols.length);
0834:                int unique = 0;
0835:                for (int i = 0; i < pcols.length; i++) {
0836:                    cols.add(newColumn(pcols[i]));
0837:                    unique |= (pcols[i].unique()) ? TRUE : FALSE;
0838:                }
0839:                setColumns(fm, fm.getElementMapping().getValueInfo(), cols,
0840:                        unique);
0841:            }
0842:
0843:            /**
0844:             * Create a new schema column with information from the given annotation.
0845:             */
0846:            private static Column newColumn(ElementColumn anno) {
0847:                Column col = new Column();
0848:                if (!StringUtils.isEmpty(anno.name()))
0849:                    col.setName(anno.name());
0850:                if (!StringUtils.isEmpty(anno.columnDefinition()))
0851:                    col.setTypeName(anno.columnDefinition());
0852:                if (anno.precision() != 0)
0853:                    col.setSize(anno.precision());
0854:                else if (anno.length() != 255)
0855:                    col.setSize(anno.length());
0856:                col.setNotNull(!anno.nullable());
0857:                col.setDecimalDigits(anno.scale());
0858:                col.setFlag(Column.FLAG_UNINSERTABLE, !anno.insertable());
0859:                col.setFlag(Column.FLAG_UNUPDATABLE, !anno.updatable());
0860:                return col;
0861:            }
0862:
0863:            /**
0864:             * Parse @KeyJoinColumn(s).
0865:             */
0866:            private void parseKeyJoinColumns(FieldMapping fm,
0867:                    KeyJoinColumn... joins) {
0868:                if (joins.length == 0)
0869:                    return;
0870:
0871:                List<Column> cols = new ArrayList<Column>(joins.length);
0872:                int unique = 0;
0873:                for (int i = 0; i < joins.length; i++) {
0874:                    cols.add(newColumn(joins[i]));
0875:                    unique |= (joins[i].unique()) ? TRUE : FALSE;
0876:                }
0877:                setColumns(fm, fm.getKeyMapping().getValueInfo(), cols, unique);
0878:            }
0879:
0880:            /**
0881:             *  Create a new schema column with information from the given annotation.
0882:             */
0883:            private static Column newColumn(KeyJoinColumn join) {
0884:                Column col = new Column();
0885:                if (!StringUtils.isEmpty(join.name()))
0886:                    col.setName(join.name());
0887:                if (!StringUtils.isEmpty(join.columnDefinition()))
0888:                    col.setName(join.columnDefinition());
0889:                if (!StringUtils.isEmpty(join.referencedColumnName()))
0890:                    col.setTarget(join.referencedColumnName());
0891:                if (!StringUtils.isEmpty(join.referencedAttributeName()))
0892:                    col.setTargetField(join.referencedAttributeName());
0893:                col.setNotNull(!join.nullable());
0894:                col.setFlag(Column.FLAG_UNINSERTABLE, !join.insertable());
0895:                col.setFlag(Column.FLAG_UNUPDATABLE, !join.updatable());
0896:                return col;
0897:            }
0898:
0899:            /**
0900:             * Translate the fetch mode enum value to the internal OpenJPA constant.
0901:             */
0902:            private static int toEagerFetchModeConstant(FetchMode mode) {
0903:                switch (mode) {
0904:                case NONE:
0905:                    return EagerFetchModes.EAGER_NONE;
0906:                case JOIN:
0907:                    return EagerFetchModes.EAGER_JOIN;
0908:                case PARALLEL:
0909:                    return EagerFetchModes.EAGER_PARALLEL;
0910:                default:
0911:                    throw new InternalException();
0912:                }
0913:            }
0914:
0915:            @Override
0916:            protected void parseLobMapping(FieldMetaData fmd) {
0917:                Column col = new Column();
0918:                if (fmd.getDeclaredTypeCode() == JavaTypes.STRING
0919:                        || fmd.getDeclaredType() == char[].class
0920:                        || fmd.getDeclaredType() == Character[].class)
0921:                    col.setType(Types.CLOB);
0922:                else
0923:                    col.setType(Types.BLOB);
0924:                ((FieldMapping) fmd).getValueInfo().setColumns(
0925:                        Arrays.asList(new Column[] { col }));
0926:            }
0927:
0928:            @Override
0929:            protected void parseMemberMappingAnnotations(FieldMetaData fmd) {
0930:                FieldMapping fm = (FieldMapping) fmd;
0931:                AnnotatedElement el = (AnnotatedElement) getRepository()
0932:                        .getMetaDataFactory().getDefaults().getBackingMember(
0933:                                fmd);
0934:
0935:                MappingTag tag;
0936:                for (Annotation anno : el.getDeclaredAnnotations()) {
0937:                    tag = _tags.get(anno.annotationType());
0938:                    if (tag == null) {
0939:                        handleUnknownMemberMappingAnnotation(fm, anno);
0940:                        continue;
0941:                    }
0942:
0943:                    switch (tag) {
0944:                    case ASSOC_OVERRIDE:
0945:                        parseAssociationOverrides(fm,
0946:                                (AssociationOverride) anno);
0947:                        break;
0948:                    case ASSOC_OVERRIDES:
0949:                        parseAssociationOverrides(fm,
0950:                                ((AssociationOverrides) anno).value());
0951:                        break;
0952:                    case ATTR_OVERRIDE:
0953:                        parseAttributeOverrides(fm, (AttributeOverride) anno);
0954:                        break;
0955:                    case ATTR_OVERRIDES:
0956:                        parseAttributeOverrides(fm, ((AttributeOverrides) anno)
0957:                                .value());
0958:                        break;
0959:                    case COL:
0960:                        parseColumns(fm, (javax.persistence.Column) anno);
0961:                        break;
0962:                    case COLS:
0963:                        parseColumns(fm, ((Columns) anno).value());
0964:                        break;
0965:                    case ENUMERATED:
0966:                        parseEnumerated(fm, (Enumerated) anno);
0967:                        break;
0968:                    case JOIN_COL:
0969:                        parseJoinColumns(fm, fm.getValueInfo(), true,
0970:                                (JoinColumn) anno);
0971:                        break;
0972:                    case JOIN_COLS:
0973:                        parseJoinColumns(fm, fm.getValueInfo(), true,
0974:                                ((JoinColumns) anno).value());
0975:                        break;
0976:                    case JOIN_TABLE:
0977:                        parseJoinTable(fm, (JoinTable) anno);
0978:                        break;
0979:                    case KEY_CLASS_CRIT:
0980:                        fm.getKeyMapping().getValueInfo().setUseClassCriteria(
0981:                                ((KeyClassCriteria) anno).value());
0982:                        break;
0983:                    case KEY_COL:
0984:                        parseKeyColumns(fm, (KeyColumn) anno);
0985:                        break;
0986:                    case KEY_COLS:
0987:                        parseKeyColumns(fm, ((KeyColumns) anno).value());
0988:                        break;
0989:                    case KEY_EMBEDDED_MAPPING:
0990:                        KeyEmbeddedMapping kembed = (KeyEmbeddedMapping) anno;
0991:                        parseEmbeddedMapping(fm.getKeyMapping(), kembed
0992:                                .nullIndicatorColumnName(), kembed
0993:                                .nullIndicatorAttributeName(), kembed
0994:                                .overrides());
0995:                        break;
0996:                    case KEY_FK:
0997:                        KeyForeignKey kfk = (KeyForeignKey) anno;
0998:                        parseForeignKey(fm.getKeyMapping().getValueInfo(), kfk
0999:                                .name(), kfk.enabled(), kfk.deferred(), kfk
1000:                                .deleteAction(), kfk.updateAction());
1001:                        break;
1002:                    case KEY_INDEX:
1003:                        KeyIndex kidx = (KeyIndex) anno;
1004:                        parseIndex(fm.getKeyMapping().getValueInfo(), kidx
1005:                                .name(), kidx.enabled(), kidx.unique());
1006:                        break;
1007:                    case KEY_JOIN_COL:
1008:                        parseKeyJoinColumns(fm, (KeyJoinColumn) anno);
1009:                        break;
1010:                    case KEY_JOIN_COLS:
1011:                        parseKeyJoinColumns(fm, ((KeyJoinColumns) anno).value());
1012:                        break;
1013:                    case KEY_NONPOLY:
1014:                        fm
1015:                                .getKeyMapping()
1016:                                .setPolymorphic(
1017:                                        toPolymorphicConstant(((KeyNonpolymorphic) anno)
1018:                                                .value()));
1019:                        break;
1020:                    case KEY_STRAT:
1021:                        fm.getKeyMapping().getValueInfo().setStrategy(
1022:                                ((KeyStrategy) anno).value());
1023:                        break;
1024:                    case PK_JOIN_COL:
1025:                        parsePrimaryKeyJoinColumns(fm,
1026:                                (PrimaryKeyJoinColumn) anno);
1027:                        break;
1028:                    case PK_JOIN_COLS:
1029:                        parsePrimaryKeyJoinColumns(fm,
1030:                                ((PrimaryKeyJoinColumns) anno).value());
1031:                        break;
1032:                    case TABLE_GEN:
1033:                        parseTableGenerator(el, (TableGenerator) anno);
1034:                        break;
1035:                    case TEMPORAL:
1036:                        parseTemporal(fm, (Temporal) anno);
1037:                        break;
1038:                    case CLASS_CRIT:
1039:                        fm.getValueInfo().setUseClassCriteria(
1040:                                ((ClassCriteria) anno).value());
1041:                        break;
1042:                    case CONTAINER_TABLE:
1043:                        parseContainerTable(fm, (ContainerTable) anno);
1044:                        break;
1045:                    case EAGER_FETCH_MODE:
1046:                        fm
1047:                                .setEagerFetchMode(toEagerFetchModeConstant(((EagerFetchMode) anno)
1048:                                        .value()));
1049:                        break;
1050:                    case ELEM_CLASS_CRIT:
1051:                        fm.getElementMapping().getValueInfo()
1052:                                .setUseClassCriteria(
1053:                                        ((ElementClassCriteria) anno).value());
1054:                        break;
1055:                    case ELEM_COL:
1056:                        parseElementColumns(fm, (ElementColumn) anno);
1057:                        break;
1058:                    case ELEM_COLS:
1059:                        parseElementColumns(fm, ((ElementColumns) anno).value());
1060:                        break;
1061:                    case ELEM_EMBEDDED_MAPPING:
1062:                        ElementEmbeddedMapping ee = (ElementEmbeddedMapping) anno;
1063:                        parseEmbeddedMapping(fm.getElementMapping(), ee
1064:                                .nullIndicatorAttributeName(), ee
1065:                                .nullIndicatorColumnName(), ee.overrides());
1066:                        break;
1067:                    case ELEM_FK:
1068:                        ElementForeignKey efk = (ElementForeignKey) anno;
1069:                        parseForeignKey(fm.getElementMapping().getValueInfo(),
1070:                                efk.name(), efk.enabled(), efk.deferred(), efk
1071:                                        .deleteAction(), efk.updateAction());
1072:                        break;
1073:                    case ELEM_INDEX:
1074:                        ElementIndex eidx = (ElementIndex) anno;
1075:                        parseIndex(fm.getElementMapping().getValueInfo(), eidx
1076:                                .name(), eidx.enabled(), eidx.unique());
1077:                        break;
1078:                    case ELEM_JOIN_COL:
1079:                        parseElementJoinColumns(fm, (ElementJoinColumn) anno);
1080:                        break;
1081:                    case ELEM_JOIN_COLS:
1082:                        parseElementJoinColumns(fm, ((ElementJoinColumns) anno)
1083:                                .value());
1084:                        break;
1085:                    case ELEM_NONPOLY:
1086:                        fm
1087:                                .getElementMapping()
1088:                                .setPolymorphic(
1089:                                        toPolymorphicConstant(((ElementNonpolymorphic) anno)
1090:                                                .value()));
1091:                        break;
1092:                    case ELEM_STRAT:
1093:                        fm.getElementMapping().getValueInfo().setStrategy(
1094:                                ((ElementStrategy) anno).value());
1095:                        break;
1096:                    case EMBEDDED_MAPPING:
1097:                        parseEmbeddedMapping(fm, (EmbeddedMapping) anno);
1098:                        break;
1099:                    case FK:
1100:                        parseForeignKey(fm.getValueInfo(), (ForeignKey) anno);
1101:                        break;
1102:                    case INDEX:
1103:                        parseIndex(fm.getValueInfo(), (Index) anno);
1104:                        break;
1105:                    case NONPOLY:
1106:                        fm
1107:                                .setPolymorphic(toPolymorphicConstant(((Nonpolymorphic) anno)
1108:                                        .value()));
1109:                        break;
1110:                    case ORDER_COL:
1111:                        parseOrderColumn(fm, (OrderColumn) anno);
1112:                        break;
1113:                    case STRAT:
1114:                        fm.getValueInfo()
1115:                                .setStrategy(((Strategy) anno).value());
1116:                        break;
1117:                    case UNIQUE:
1118:                        parseUnique(
1119:                                fm,
1120:                                (org.apache.openjpa.persistence.jdbc.Unique) anno);
1121:                        break;
1122:                    case X_EMBEDDED_MAPPING:
1123:                        XEmbeddedMapping embed = (XEmbeddedMapping) anno;
1124:                        parseEmbeddedMapping(fm, embed
1125:                                .nullIndicatorColumnName(), embed
1126:                                .nullIndicatorAttributeName(), embed
1127:                                .overrides());
1128:                        break;
1129:                    case X_JOIN_COL:
1130:                        parseXJoinColumns(fm, fm.getValueInfo(), true,
1131:                                (XJoinColumn) anno);
1132:                        break;
1133:                    case X_JOIN_COLS:
1134:                        parseXJoinColumns(fm, fm.getValueInfo(), true,
1135:                                ((XJoinColumns) anno).value());
1136:                        break;
1137:                    default:
1138:                        throw new UnsupportedException(_loc.get("unsupported",
1139:                                fm, anno.toString()));
1140:                    }
1141:                }
1142:            }
1143:
1144:            /**
1145:             * Allow subclasses to handle unknown annotations.
1146:             */
1147:            protected boolean handleUnknownMemberMappingAnnotation(
1148:                    FieldMapping fm, Annotation anno) {
1149:                return false;
1150:            }
1151:
1152:            /**
1153:             * Return the {@link ValueMapping} <code>POLY_*</code> constant for
1154:             * the given enum value.
1155:             */
1156:            protected static int toPolymorphicConstant(NonpolymorphicType val) {
1157:                switch (val) {
1158:                case EXACT:
1159:                    return ValueMapping.POLY_FALSE;
1160:                case JOINABLE:
1161:                    return ValueMapping.POLY_JOINABLE;
1162:                case FALSE:
1163:                    return ValueMapping.POLY_TRUE;
1164:                default:
1165:                    throw new InternalException();
1166:                }
1167:            }
1168:
1169:            /**
1170:             * Parse given @AssociationOverride annotations on an embedded mapping.
1171:             */
1172:            private void parseAssociationOverrides(FieldMapping fm,
1173:                    AssociationOverride... assocs) {
1174:                ClassMapping embed = fm.getEmbeddedMapping();
1175:                if (embed == null)
1176:                    throw new MetaDataException(_loc.get("not-embedded", fm));
1177:
1178:                FieldMapping efm;
1179:                JoinColumn[] ecols;
1180:                int unique;
1181:                List<Column> jcols;
1182:                for (AssociationOverride assoc : assocs) {
1183:                    efm = embed.getFieldMapping(assoc.name());
1184:                    if (efm == null)
1185:                        throw new MetaDataException(_loc.get(
1186:                                "embed-override-name", fm, assoc.name()));
1187:                    ecols = assoc.joinColumns();
1188:                    if (ecols == null || ecols.length == 0)
1189:                        continue;
1190:
1191:                    unique = 0;
1192:                    jcols = new ArrayList<Column>(ecols.length);
1193:                    for (JoinColumn ecol : ecols) {
1194:                        unique |= (ecol.unique()) ? TRUE : FALSE;
1195:                        jcols.add(newColumn(ecol));
1196:                    }
1197:                    setColumns(efm, efm.getValueInfo(), jcols, unique);
1198:                }
1199:            }
1200:
1201:            /**
1202:             * Parse given @AttributeOverride annotations on an embedded mapping.
1203:             */
1204:            private void parseAttributeOverrides(FieldMapping fm,
1205:                    AttributeOverride... attrs) {
1206:                ClassMapping embed = fm.getEmbeddedMapping();
1207:                if (embed == null)
1208:                    throw new MetaDataException(_loc.get("not-embedded", fm));
1209:
1210:                FieldMapping efm;
1211:                for (AttributeOverride attr : attrs) {
1212:                    efm = embed.getFieldMapping(attr.name());
1213:                    if (efm == null)
1214:                        throw new MetaDataException(_loc.get(
1215:                                "embed-override-name", fm, attr.name()));
1216:                    if (attr.column() != null)
1217:                        parseColumns(efm, attr.column());
1218:                }
1219:            }
1220:
1221:            /**
1222:             * Parse @Enumerated.
1223:             */
1224:            private void parseEnumerated(FieldMapping fm, Enumerated anno) {
1225:                String strat = EnumValueHandler.class.getName()
1226:                        + "(StoreOrdinal="
1227:                        + String.valueOf(anno.value() == EnumType.ORDINAL)
1228:                        + ")";
1229:                fm.getValueInfo().setStrategy(strat);
1230:            }
1231:
1232:            /**
1233:             * Parse @Temporal.
1234:             */
1235:            private void parseTemporal(FieldMapping fm, Temporal anno) {
1236:                List cols = fm.getValueInfo().getColumns();
1237:                if (!cols.isEmpty() && cols.size() != 1)
1238:                    throw new MetaDataException(_loc.get("num-cols-mismatch",
1239:                            fm, String.valueOf(cols.size()), "1"));
1240:                if (cols.isEmpty()) {
1241:                    cols = Arrays.asList(new Column[] { new Column() });
1242:                    fm.getValueInfo().setColumns(cols);
1243:                }
1244:
1245:                Column col = (Column) cols.get(0);
1246:                switch (anno.value()) {
1247:                case DATE:
1248:                    col.setType(Types.DATE);
1249:                    break;
1250:                case TIME:
1251:                    col.setType(Types.TIME);
1252:                    break;
1253:                case TIMESTAMP:
1254:                    col.setType(Types.TIMESTAMP);
1255:                    break;
1256:                }
1257:            }
1258:
1259:            /**
1260:             * Parse @Column(s).
1261:             */
1262:            protected void parseColumns(FieldMapping fm,
1263:                    javax.persistence.Column... pcols) {
1264:                if (pcols.length == 0)
1265:                    return;
1266:
1267:                // might already have some column information from mapping annotation
1268:                List cols = fm.getValueInfo().getColumns();
1269:                if (!cols.isEmpty() && cols.size() != pcols.length)
1270:                    throw new MetaDataException(_loc.get("num-cols-mismatch",
1271:                            fm, String.valueOf(cols.size()), String
1272:                                    .valueOf(pcols.length)));
1273:
1274:                // cache the JAXB XmlType class if it is present so we do not
1275:                // have a hard-wired dependency on JAXB here
1276:                Class xmlTypeClass = null;
1277:                try {
1278:                    xmlTypeClass = Class
1279:                            .forName("javax.xml.bind.annotation.XmlType");
1280:                } catch (Exception e) {
1281:                }
1282:
1283:                int unique = 0;
1284:                String secondary = null;
1285:                for (int i = 0; i < pcols.length; i++) {
1286:                    if (cols.size() > i)
1287:                        setupColumn((Column) cols.get(i), pcols[i]);
1288:                    else {
1289:                        if (cols.isEmpty())
1290:                            cols = new ArrayList<Column>(pcols.length);
1291:                        cols.add(newColumn(pcols[i]));
1292:                    }
1293:
1294:                    if (xmlTypeClass != null
1295:                            && StringUtils.isEmpty(pcols[i].columnDefinition())
1296:                            && ((Boolean) AccessController
1297:                                    .doPrivileged(J2DoPriv5Helper
1298:                                            .isAnnotationPresentAction(fm
1299:                                                    .getDeclaredType(),
1300:                                                    xmlTypeClass)))
1301:                                    .booleanValue()) {
1302:                        DBDictionary dict = ((MappingRepository) getRepository())
1303:                                .getDBDictionary();
1304:                        if (dict.supportsXMLColumn)
1305:                            // column maps to xml type
1306:                            ((Column) cols.get(i))
1307:                                    .setTypeName(dict.xmlTypeName);
1308:                    }
1309:
1310:                    unique |= (pcols[i].unique()) ? TRUE : FALSE;
1311:                    secondary = trackSecondaryTable(fm, secondary, pcols[i]
1312:                            .table(), i);
1313:                }
1314:
1315:                setColumns(fm, fm.getValueInfo(), cols, unique);
1316:                if (secondary != null)
1317:                    fm.getMappingInfo().setTableName(secondary);
1318:            }
1319:
1320:            /**
1321:             * Create a new schema column with information from the given annotation.
1322:             */
1323:            private static Column newColumn(javax.persistence.Column anno) {
1324:                Column col = new Column();
1325:                setupColumn(col, anno);
1326:                return col;
1327:            }
1328:
1329:            /**
1330:             * Setup the given column with information from the given annotation.
1331:             */
1332:            private static void setupColumn(Column col,
1333:                    javax.persistence.Column anno) {
1334:                if (!StringUtils.isEmpty(anno.name()))
1335:                    col.setName(anno.name());
1336:                if (!StringUtils.isEmpty(anno.columnDefinition()))
1337:                    col.setTypeName(anno.columnDefinition());
1338:                if (anno.precision() != 0)
1339:                    col.setSize(anno.precision());
1340:                else if (anno.length() != 255)
1341:                    col.setSize(anno.length());
1342:                col.setNotNull(!anno.nullable());
1343:                col.setDecimalDigits(anno.scale());
1344:                col.setFlag(Column.FLAG_UNINSERTABLE, !anno.insertable());
1345:                col.setFlag(Column.FLAG_UNUPDATABLE, !anno.updatable());
1346:            }
1347:
1348:            /**
1349:             * Set the given columns as the columns for <code>fm</code>.
1350:             *
1351:             * @param unique bitwise combination of TRUE and FALSE for the
1352:             * unique attribute of each column
1353:             */
1354:            protected void setColumns(FieldMapping fm, MappingInfo info,
1355:                    List<Column> cols, int unique) {
1356:                info.setColumns(cols);
1357:                if (unique == TRUE)
1358:                    info.setUnique(new org.apache.openjpa.jdbc.schema.Unique());
1359:
1360:                //### EJB3
1361:                Log log = getLog();
1362:                if (log.isWarnEnabled() && unique == (TRUE | FALSE))
1363:                    log.warn(_loc.get("inconsist-col-attrs", fm));
1364:            }
1365:
1366:            /**
1367:             * Helper to track the secondary table for a set of columns.
1368:             *
1369:             * @param secondary secondary table for last column
1370:             * @param colSecondary secondary table for current column
1371:             * @return secondary table for field
1372:             */
1373:            private String trackSecondaryTable(FieldMapping fm,
1374:                    String secondary, String colSecondary, int col) {
1375:                if (StringUtils.isEmpty(colSecondary))
1376:                    colSecondary = null;
1377:                if (col == 0)
1378:                    return colSecondary;
1379:                if (!StringUtils.equalsIgnoreCase(secondary, colSecondary))
1380:                    throw new MetaDataException(_loc
1381:                            .get("second-inconsist", fm));
1382:                return secondary;
1383:            }
1384:
1385:            /**
1386:             * Parse @JoinTable.
1387:             */
1388:            private void parseJoinTable(FieldMapping fm, JoinTable join) {
1389:                fm.getMappingInfo().setTableName(
1390:                        toTableName(join.schema(), join.name()));
1391:                parseJoinColumns(fm, fm.getMappingInfo(), false, join
1392:                        .joinColumns());
1393:                parseJoinColumns(fm, fm.getElementMapping().getValueInfo(),
1394:                        false, join.inverseJoinColumns());
1395:            }
1396:
1397:            /**
1398:             * Parse given @JoinColumn annotations.
1399:             */
1400:            private void parseJoinColumns(FieldMapping fm, MappingInfo info,
1401:                    boolean secondaryAllowed, JoinColumn... joins) {
1402:                if (joins.length == 0)
1403:                    return;
1404:
1405:                List<Column> cols = new ArrayList<Column>(joins.length);
1406:                int unique = 0;
1407:                String secondary = null;
1408:                for (int i = 0; i < joins.length; i++) {
1409:                    cols.add(newColumn(joins[i]));
1410:                    unique |= (joins[i].unique()) ? TRUE : FALSE;
1411:                    secondary = trackSecondaryTable(fm, secondary, joins[i]
1412:                            .table(), i);
1413:                    if (!secondaryAllowed && secondary != null)
1414:                        throw new MetaDataException(_loc.get("bad-second", fm));
1415:                }
1416:
1417:                setColumns(fm, info, cols, unique);
1418:                if (secondary != null)
1419:                    fm.getMappingInfo().setTableName(secondary);
1420:            }
1421:
1422:            /**
1423:             * Create a new schema column with information from the given annotation.
1424:             */
1425:            private static Column newColumn(JoinColumn join) {
1426:                Column col = new Column();
1427:                if (!StringUtils.isEmpty(join.name()))
1428:                    col.setName(join.name());
1429:                if (!StringUtils.isEmpty(join.columnDefinition()))
1430:                    col.setTypeName(join.columnDefinition());
1431:                if (!StringUtils.isEmpty(join.referencedColumnName()))
1432:                    col.setTarget(join.referencedColumnName());
1433:                col.setNotNull(!join.nullable());
1434:                col.setFlag(Column.FLAG_UNINSERTABLE, !join.insertable());
1435:                col.setFlag(Column.FLAG_UNUPDATABLE, !join.updatable());
1436:                return col;
1437:            }
1438:
1439:            /**
1440:             * Parse @KeyColumn(s).
1441:             */
1442:            private void parseKeyColumns(FieldMapping fm, KeyColumn... pcols) {
1443:                if (pcols.length == 0)
1444:                    return;
1445:
1446:                List<Column> cols = new ArrayList<Column>(pcols.length);
1447:                int unique = 0;
1448:                for (int i = 0; i < pcols.length; i++) {
1449:                    cols.add(newColumn(pcols[i]));
1450:                    unique |= (pcols[i].unique()) ? TRUE : FALSE;
1451:                }
1452:                setColumns(fm, fm.getKeyMapping().getValueInfo(), cols, unique);
1453:            }
1454:
1455:            /**
1456:             * Create a new schema column with information from the given annotation.
1457:             */
1458:            private static Column newColumn(KeyColumn anno) {
1459:                Column col = new Column();
1460:                if (!StringUtils.isEmpty(anno.name()))
1461:                    col.setName(anno.name());
1462:                if (!StringUtils.isEmpty(anno.columnDefinition()))
1463:                    col.setTypeName(anno.columnDefinition());
1464:                if (anno.precision() != 0)
1465:                    col.setSize(anno.precision());
1466:                else if (anno.length() != 255)
1467:                    col.setSize(anno.length());
1468:                col.setNotNull(!anno.nullable());
1469:                col.setDecimalDigits(anno.scale());
1470:                col.setFlag(Column.FLAG_UNINSERTABLE, !anno.insertable());
1471:                col.setFlag(Column.FLAG_UNUPDATABLE, !anno.updatable());
1472:                return col;
1473:            }
1474:
1475:            /**
1476:             * Parse given @PrimaryKeyJoinColumn annotations.
1477:             */
1478:            private void parsePrimaryKeyJoinColumns(FieldMapping fm,
1479:                    PrimaryKeyJoinColumn... joins) {
1480:                List<Column> cols = new ArrayList<Column>(joins.length);
1481:                for (PrimaryKeyJoinColumn join : joins)
1482:                    cols.add(newColumn(join));
1483:                setColumns(fm, fm.getValueInfo(), cols, 0);
1484:            }
1485:
1486:            /**
1487:             * Parse given @XJoinColumn annotations.
1488:             */
1489:            protected void parseXJoinColumns(FieldMapping fm, MappingInfo info,
1490:                    boolean secondaryAllowed, XJoinColumn... joins) {
1491:                if (joins.length == 0)
1492:                    return;
1493:
1494:                List<Column> cols = new ArrayList<Column>(joins.length);
1495:                int unique = 0;
1496:                String secondary = null;
1497:                for (int i = 0; i < joins.length; i++) {
1498:                    cols.add(newColumn(joins[i]));
1499:                    unique |= (joins[i].unique()) ? TRUE : FALSE;
1500:                    secondary = trackSecondaryTable(fm, secondary, joins[i]
1501:                            .table(), i);
1502:                    if (!secondaryAllowed && secondary != null)
1503:                        throw new MetaDataException(_loc.get("bad-second", fm));
1504:                }
1505:
1506:                setColumns(fm, info, cols, unique);
1507:                if (secondary != null)
1508:                    fm.getMappingInfo().setTableName(secondary);
1509:            }
1510:
1511:            /**
1512:             * Create a new schema column with information from the given annotation.
1513:             */
1514:            private static Column newColumn(XJoinColumn join) {
1515:                Column col = new Column();
1516:                if (!StringUtils.isEmpty(join.name()))
1517:                    col.setName(join.name());
1518:                if (!StringUtils.isEmpty(join.columnDefinition()))
1519:                    col.setTypeName(join.columnDefinition());
1520:                if (!StringUtils.isEmpty(join.referencedColumnName()))
1521:                    col.setTarget(join.referencedColumnName());
1522:                if (!StringUtils.isEmpty(join.referencedAttributeName()))
1523:                    col.setTargetField(join.referencedAttributeName());
1524:                col.setNotNull(!join.nullable());
1525:                col.setFlag(Column.FLAG_UNINSERTABLE, !join.insertable());
1526:                col.setFlag(Column.FLAG_UNUPDATABLE, !join.updatable());
1527:                return col;
1528:            }
1529:
1530:            /**
1531:             * Parse embedded info for the given mapping.
1532:             */
1533:            private void parseEmbeddedMapping(FieldMapping fm,
1534:                    EmbeddedMapping anno) {
1535:                ClassMapping embed = fm.getEmbeddedMapping();
1536:                if (embed == null)
1537:                    throw new MetaDataException(_loc.get("not-embedded", fm));
1538:
1539:                FieldMapping efm;
1540:                for (MappingOverride over : anno.overrides()) {
1541:                    efm = embed.getFieldMapping(over.name());
1542:                    if (efm == null)
1543:                        throw new MetaDataException(_loc.get(
1544:                                "embed-override-name", fm, over.name()));
1545:                    populate(efm, over);
1546:                }
1547:
1548:                String nullInd = null;
1549:                if (!StringUtils.isEmpty(anno.nullIndicatorAttributeName()))
1550:                    nullInd = anno.nullIndicatorAttributeName();
1551:                else if (!StringUtils.isEmpty(anno.nullIndicatorColumnName()))
1552:                    nullInd = anno.nullIndicatorColumnName();
1553:                if (nullInd == null)
1554:                    return;
1555:
1556:                ValueMappingInfo info = fm.getValueInfo();
1557:                populateNullIndicator(nullInd, info);
1558:            }
1559:
1560:            /**
1561:             * Parse embedded info for the given mapping.
1562:             */
1563:            private void parseEmbeddedMapping(ValueMapping vm,
1564:                    String nullIndicatorAttribute, String nullIndicatorColumn,
1565:                    XMappingOverride[] overrides) {
1566:                ClassMapping embed = vm.getEmbeddedMapping();
1567:                if (embed == null)
1568:                    throw new MetaDataException(_loc.get("not-embedded", vm));
1569:
1570:                FieldMapping efm;
1571:                for (XMappingOverride over : overrides) {
1572:                    efm = embed.getFieldMapping(over.name());
1573:                    if (efm == null)
1574:                        throw new MetaDataException(_loc.get(
1575:                                "embed-override-name", vm, over.name()));
1576:                    populate(efm, over);
1577:                }
1578:
1579:                String nullInd = null;
1580:                if (!StringUtils.isEmpty(nullIndicatorAttribute))
1581:                    nullInd = nullIndicatorAttribute;
1582:                else if (!StringUtils.isEmpty(nullIndicatorColumn))
1583:                    nullInd = nullIndicatorColumn;
1584:                if (nullInd == null)
1585:                    return;
1586:
1587:                ValueMappingInfo info = vm.getValueInfo();
1588:                populateNullIndicator(nullInd, info);
1589:            }
1590:
1591:            private void populateNullIndicator(String nullInd,
1592:                    ValueMappingInfo info) {
1593:                if ("false".equals(nullInd))
1594:                    info.setCanIndicateNull(false);
1595:                else {
1596:                    Column col = new Column();
1597:                    if (!"true".equals(nullInd))
1598:                        col.setName(nullInd);
1599:                    info.setColumns(Arrays.asList(new Column[] { col }));
1600:                }
1601:            }
1602:
1603:            /**
1604:             * Parse @ContainerTable.
1605:             */
1606:            protected void parseContainerTable(FieldMapping fm,
1607:                    ContainerTable ctbl) {
1608:                fm.getMappingInfo().setTableName(
1609:                        toTableName(ctbl.schema(), ctbl.name()));
1610:                parseXJoinColumns(fm, fm.getMappingInfo(), false, ctbl
1611:                        .joinColumns());
1612:                if (ctbl.joinForeignKey().specified())
1613:                    parseForeignKey(fm.getMappingInfo(), ctbl.joinForeignKey());
1614:                if (ctbl.joinIndex().specified())
1615:                    parseIndex(fm.getMappingInfo(), ctbl.joinIndex());
1616:            }
1617:
1618:            /**
1619:             * Parse @OrderColumn.
1620:             */
1621:            private void parseOrderColumn(FieldMapping fm, OrderColumn order) {
1622:                if (!order.enabled()) {
1623:                    fm.getMappingInfo().setCanOrderColumn(false);
1624:                    return;
1625:                }
1626:
1627:                Column col = new Column();
1628:                if (!StringUtils.isEmpty(order.name()))
1629:                    col.setName(order.name());
1630:                if (!StringUtils.isEmpty(order.columnDefinition()))
1631:                    col.setTypeName(order.columnDefinition());
1632:                if (order.precision() != 0)
1633:                    col.setSize(order.precision());
1634:                col.setFlag(Column.FLAG_UNINSERTABLE, !order.insertable());
1635:                col.setFlag(Column.FLAG_UNUPDATABLE, !order.updatable());
1636:                fm.getMappingInfo().setOrderColumn(col);
1637:            }
1638:
1639:            /**
1640:             * Parse @ElementJoinColumn(s).
1641:             */
1642:            protected void parseElementJoinColumns(FieldMapping fm,
1643:                    ElementJoinColumn... joins) {
1644:                if (joins.length == 0)
1645:                    return;
1646:
1647:                List<Column> cols = new ArrayList<Column>(joins.length);
1648:                int unique = 0;
1649:                for (int i = 0; i < joins.length; i++) {
1650:                    cols.add(newColumn(joins[i]));
1651:                    unique |= (joins[i].unique()) ? TRUE : FALSE;
1652:                }
1653:                setColumns(fm, fm.getElementMapping().getValueInfo(), cols,
1654:                        unique);
1655:            }
1656:
1657:            /**
1658:             * Create a new schema column with information from the given annotation.
1659:             */
1660:            private static Column newColumn(ElementJoinColumn join) {
1661:                Column col = new Column();
1662:                if (!StringUtils.isEmpty(join.name()))
1663:                    col.setName(join.name());
1664:                if (!StringUtils.isEmpty(join.columnDefinition()))
1665:                    col.setTypeName(join.columnDefinition());
1666:                if (!StringUtils.isEmpty(join.referencedColumnName()))
1667:                    col.setTarget(join.referencedColumnName());
1668:                if (!StringUtils.isEmpty(join.referencedAttributeName()))
1669:                    col.setTargetField(join.referencedAttributeName());
1670:                col.setNotNull(!join.nullable());
1671:                col.setFlag(Column.FLAG_UNINSERTABLE, !join.insertable());
1672:                col.setFlag(Column.FLAG_UNUPDATABLE, !join.updatable());
1673:                return col;
1674:            }
1675:
1676:            private static Unique newUnique(ClassMapping cm, String name,
1677:                    String[] columnNames) {
1678:                if (columnNames == null || columnNames.length == 0)
1679:                    return null;
1680:                Unique uniqueConstraint = new Unique();
1681:                uniqueConstraint.setName(name);
1682:                for (int i = 0; i < columnNames.length; i++) {
1683:                    if (StringUtils.isEmpty(columnNames[i]))
1684:                        throw new UserException(_loc.get("empty-unique-column",
1685:                                Arrays.toString(columnNames), cm));
1686:                    Column column = new Column();
1687:                    column.setName(columnNames[i]);
1688:                    uniqueConstraint.addColumn(column);
1689:                }
1690:                return uniqueConstraint;
1691:            }
1692:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.