Source Code Cross Referenced for XMLPersistenceMetaDataParser.java in  » Database-ORM » openjpa » org » apache » openjpa » persistence » 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 
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;
0020:
0021:        import java.lang.reflect.Field;
0022:        import java.lang.reflect.Member;
0023:        import java.lang.reflect.Method;
0024:        import java.security.AccessController;
0025:        import java.security.PrivilegedActionException;
0026:        import java.util.ArrayList;
0027:        import java.util.Collection;
0028:        import java.util.EnumSet;
0029:        import java.util.HashMap;
0030:        import java.util.Map;
0031:        import java.util.Set;
0032:        import java.util.Stack;
0033:        import javax.persistence.CascadeType;
0034:        import javax.persistence.GenerationType;
0035:        import static javax.persistence.CascadeType.*;
0036:
0037:        import org.apache.commons.lang.StringUtils;
0038:        import org.xml.sax.Attributes;
0039:        import org.xml.sax.SAXException;
0040:        import org.apache.openjpa.conf.OpenJPAConfiguration;
0041:        import org.apache.openjpa.enhance.PersistenceCapable;
0042:        import org.apache.openjpa.event.BeanLifecycleCallbacks;
0043:        import org.apache.openjpa.event.LifecycleCallbacks;
0044:        import org.apache.openjpa.event.LifecycleEvent;
0045:        import org.apache.openjpa.event.MethodLifecycleCallbacks;
0046:        import org.apache.openjpa.kernel.QueryLanguages;
0047:        import org.apache.openjpa.kernel.jpql.JPQLParser;
0048:        import org.apache.openjpa.lib.conf.Configurations;
0049:        import org.apache.openjpa.lib.log.Log;
0050:        import org.apache.openjpa.lib.meta.CFMetaDataParser;
0051:        import org.apache.openjpa.lib.util.J2DoPrivHelper;
0052:        import org.apache.openjpa.lib.util.Localizer;
0053:        import org.apache.openjpa.meta.ClassMetaData;
0054:        import org.apache.openjpa.meta.DelegatingMetaDataFactory;
0055:        import org.apache.openjpa.meta.FieldMetaData;
0056:        import org.apache.openjpa.meta.JavaTypes;
0057:        import org.apache.openjpa.meta.LifecycleMetaData;
0058:        import org.apache.openjpa.meta.MetaDataDefaults;
0059:        import org.apache.openjpa.meta.MetaDataFactory;
0060:        import static org.apache.openjpa.meta.MetaDataModes.*;
0061:        import org.apache.openjpa.meta.MetaDataRepository;
0062:        import org.apache.openjpa.meta.Order;
0063:        import org.apache.openjpa.meta.QueryMetaData;
0064:        import org.apache.openjpa.meta.SequenceMetaData;
0065:        import org.apache.openjpa.meta.ValueMetaData;
0066:        import static org.apache.openjpa.persistence.MetaDataTag.*;
0067:        import static org.apache.openjpa.persistence.PersistenceStrategy.*;
0068:        import org.apache.openjpa.util.ImplHelper;
0069:
0070:        /**
0071:         * Custom SAX parser used by the system to quickly parse persistence i
0072:         * metadata files.
0073:         *
0074:         * @author Steve Kim
0075:         * @nojavadoc
0076:         */
0077:        public class XMLPersistenceMetaDataParser extends CFMetaDataParser
0078:                implements  PersistenceMetaDataFactory.Parser {
0079:
0080:            // parse constants
0081:            protected static final String ELEM_PKG = "package";
0082:            protected static final String ELEM_ACCESS = "access";
0083:            protected static final String ELEM_ATTRS = "attributes";
0084:            protected static final String ELEM_LISTENER = "entity-listener";
0085:            protected static final String ELEM_CASCADE = "cascade";
0086:            protected static final String ELEM_CASCADE_ALL = "cascade-all";
0087:            protected static final String ELEM_CASCADE_PER = "cascade-persist";
0088:            protected static final String ELEM_CASCADE_MER = "cascade-merge";
0089:            protected static final String ELEM_CASCADE_REM = "cascade-remove";
0090:            protected static final String ELEM_CASCADE_REF = "cascade-refresh";
0091:            protected static final String ELEM_PU_META = "persistence-unit-metadata";
0092:            protected static final String ELEM_PU_DEF = "persistence-unit-defaults";
0093:            protected static final String ELEM_XML_MAP_META_COMPLETE = "xml-mapping-metadata-complete";
0094:
0095:            private static final Map<String, Object> _elems = new HashMap<String, Object>();
0096:
0097:            static {
0098:                _elems.put(ELEM_PKG, ELEM_PKG);
0099:                _elems.put(ELEM_ACCESS, ELEM_ACCESS);
0100:                _elems.put(ELEM_ATTRS, ELEM_ATTRS);
0101:                _elems.put(ELEM_LISTENER, ELEM_LISTENER);
0102:                _elems.put(ELEM_CASCADE, ELEM_CASCADE);
0103:                _elems.put(ELEM_CASCADE_ALL, ELEM_CASCADE_ALL);
0104:                _elems.put(ELEM_CASCADE_PER, ELEM_CASCADE_PER);
0105:                _elems.put(ELEM_CASCADE_REM, ELEM_CASCADE_REM);
0106:                _elems.put(ELEM_CASCADE_MER, ELEM_CASCADE_MER);
0107:                _elems.put(ELEM_CASCADE_REF, ELEM_CASCADE_REF);
0108:                _elems.put(ELEM_PU_META, ELEM_PU_META);
0109:                _elems.put(ELEM_PU_DEF, ELEM_PU_DEF);
0110:                _elems.put(ELEM_XML_MAP_META_COMPLETE,
0111:                        ELEM_XML_MAP_META_COMPLETE);
0112:
0113:                _elems.put("entity-listeners", ENTITY_LISTENERS);
0114:                _elems.put("pre-persist", PRE_PERSIST);
0115:                _elems.put("post-persist", POST_PERSIST);
0116:                _elems.put("pre-remove", PRE_REMOVE);
0117:                _elems.put("post-remove", POST_REMOVE);
0118:                _elems.put("pre-update", PRE_UPDATE);
0119:                _elems.put("post-update", POST_UPDATE);
0120:                _elems.put("post-load", POST_LOAD);
0121:                _elems.put("exclude-default-listeners",
0122:                        EXCLUDE_DEFAULT_LISTENERS);
0123:                _elems.put("exclude-superclass-listeners",
0124:                        EXCLUDE_SUPERCLASS_LISTENERS);
0125:
0126:                _elems.put("named-query", QUERY);
0127:                _elems.put("named-native-query", NATIVE_QUERY);
0128:                _elems.put("query-hint", QUERY_HINT);
0129:                _elems.put("query", QUERY_STRING);
0130:
0131:                _elems.put("flush-mode", FLUSH_MODE);
0132:                _elems.put("sequence-generator", SEQ_GENERATOR);
0133:
0134:                _elems.put("id", ID);
0135:                _elems.put("id-class", ID_CLASS);
0136:                _elems.put("embedded-id", EMBEDDED_ID);
0137:                _elems.put("version", VERSION);
0138:                _elems.put("generated-value", GENERATED_VALUE);
0139:                _elems.put("map-key", MAP_KEY);
0140:                _elems.put("order-by", ORDER_BY);
0141:                _elems.put("lob", LOB);
0142:
0143:                _elems.put("basic", BASIC);
0144:                _elems.put("many-to-one", MANY_ONE);
0145:                _elems.put("one-to-one", ONE_ONE);
0146:                _elems.put("embedded", EMBEDDED);
0147:                _elems.put("one-to-many", ONE_MANY);
0148:                _elems.put("many-to-many", MANY_MANY);
0149:                _elems.put("transient", TRANSIENT);
0150:            }
0151:
0152:            private static final Localizer _loc = Localizer
0153:                    .forPackage(XMLPersistenceMetaDataParser.class);
0154:
0155:            private final OpenJPAConfiguration _conf;
0156:            private MetaDataRepository _repos = null;
0157:            private AnnotationPersistenceMetaDataParser _parser = null;
0158:            private ClassLoader _envLoader = null;
0159:            private int _mode = MODE_NONE;
0160:            private boolean _override = false;
0161:
0162:            private final Stack _elements = new Stack();
0163:            private final Stack _parents = new Stack();
0164:
0165:            private Class _cls = null;
0166:            private int _fieldPos = 0;
0167:            private int _clsPos = 0;
0168:            private int _access = ClassMetaData.ACCESS_UNKNOWN;
0169:            private PersistenceStrategy _strategy = null;
0170:            private Set<CascadeType> _cascades = null;
0171:            private Set<CascadeType> _pkgCascades = null;
0172:
0173:            private Class _listener = null;
0174:            private Collection<LifecycleCallbacks>[] _callbacks = null;
0175:            private int[] _highs = null;
0176:
0177:            /**
0178:             * Constructor; supply configuration.
0179:             */
0180:            public XMLPersistenceMetaDataParser(OpenJPAConfiguration conf) {
0181:                _conf = conf;
0182:                setValidating(true);
0183:                setLog(conf.getLog(OpenJPAConfiguration.LOG_METADATA));
0184:                setParseComments(true);
0185:                setMode(MODE_META | MODE_MAPPING | MODE_QUERY);
0186:                setParseText(true);
0187:            }
0188:
0189:            /**
0190:             * Configuration supplied on construction.
0191:             */
0192:            public OpenJPAConfiguration getConfiguration() {
0193:                return _conf;
0194:            }
0195:
0196:            /**
0197:             * The annotation parser. When class is discovered in an XML file,
0198:             * we first parse any annotations present, then override with the XML.
0199:             */
0200:            public AnnotationPersistenceMetaDataParser getAnnotationParser() {
0201:                return _parser;
0202:            }
0203:
0204:            /**
0205:             * The annotation parser. When class is discovered in an XML file,
0206:             * we first parse any annotations present, then override with the XML.
0207:             */
0208:            public void setAnnotationParser(
0209:                    AnnotationPersistenceMetaDataParser parser) {
0210:                _parser = parser;
0211:            }
0212:
0213:            /**
0214:             * Returns the repository for this parser. If none has been set, creates
0215:             * a new repository and sets it.
0216:             */
0217:            public MetaDataRepository getRepository() {
0218:                if (_repos == null) {
0219:                    MetaDataRepository repos = _conf
0220:                            .newMetaDataRepositoryInstance();
0221:                    MetaDataFactory mdf = repos.getMetaDataFactory();
0222:                    if (mdf instanceof  DelegatingMetaDataFactory)
0223:                        mdf = ((DelegatingMetaDataFactory) mdf)
0224:                                .getInnermostDelegate();
0225:                    if (mdf instanceof  PersistenceMetaDataFactory)
0226:                        ((PersistenceMetaDataFactory) mdf).setXMLParser(this );
0227:                    _repos = repos;
0228:                }
0229:                return _repos;
0230:            }
0231:
0232:            /**
0233:             * Set the metadata repository for this parser.
0234:             */
0235:            public void setRepository(MetaDataRepository repos) {
0236:                _repos = repos;
0237:                if (repos != null
0238:                        && (repos.getValidate() & repos.VALIDATE_RUNTIME) != 0)
0239:                    setParseComments(false);
0240:            }
0241:
0242:            /**
0243:             * Return the environmental class loader to pass on to parsed
0244:             * metadata instances.
0245:             */
0246:            public ClassLoader getEnvClassLoader() {
0247:                return _envLoader;
0248:            }
0249:
0250:            /**
0251:             * Set the environmental class loader to pass on to parsed
0252:             * metadata instances.
0253:             */
0254:            public void setEnvClassLoader(ClassLoader loader) {
0255:                _envLoader = loader;
0256:            }
0257:
0258:            /**
0259:             * Whether to allow later parses of mapping information to override
0260:             * earlier information for the same class. Defaults to false. Useful
0261:             * when a tool is mapping a class, so that .jdo file partial mapping
0262:             * information can be used even when mappings are stored in .orm files
0263:             * or other locations.
0264:             */
0265:            public boolean getMappingOverride() {
0266:                return _override;
0267:            }
0268:
0269:            /**
0270:             * Whether to allow later parses of mapping information to override
0271:             * earlier information for the same class. Defaults to false. Useful
0272:             * when a tool is mapping a class, so that .jdo file partial mapping
0273:             * information can be used even when mappings are stored in .orm files
0274:             * or other locations.
0275:             */
0276:            public void setMappingOverride(boolean override) {
0277:                _override = override;
0278:            }
0279:
0280:            /**
0281:             * The parse mode according to the expected document type. The
0282:             * mode constants act as bit flags, and therefore can be combined.
0283:             */
0284:            public int getMode() {
0285:                return _mode;
0286:            }
0287:
0288:            /**
0289:             * The parse mode according to the expected document type.
0290:             */
0291:            public void setMode(int mode, boolean on) {
0292:                if (mode == MODE_NONE)
0293:                    setMode(MODE_NONE);
0294:                else if (on)
0295:                    setMode(_mode | mode);
0296:                else
0297:                    setMode(_mode & ~mode);
0298:            }
0299:
0300:            /**
0301:             * The parse mode according to the expected document type.
0302:             */
0303:            public void setMode(int mode) {
0304:                _mode = mode;
0305:                if (_parser != null)
0306:                    _parser.setMode(mode);
0307:            }
0308:
0309:            /**
0310:             * Convenience method for interpreting {@link #getMode}.
0311:             */
0312:            protected boolean isMetaDataMode() {
0313:                return (_mode & MODE_META) != 0;
0314:            }
0315:
0316:            /**
0317:             * Convenience method for interpreting {@link #getMode}.
0318:             */
0319:            protected boolean isQueryMode() {
0320:                return (_mode & MODE_QUERY) != 0;
0321:            }
0322:
0323:            /**
0324:             * Convenience method for interpreting {@link #getMode}.
0325:             */
0326:            protected boolean isMappingMode() {
0327:                return (_mode & MODE_MAPPING) != 0;
0328:            }
0329:
0330:            /**
0331:             * Returns true if we're in mapping mode or in metadata mode with
0332:             * mapping override enabled.
0333:             */
0334:            protected boolean isMappingOverrideMode() {
0335:                return isMappingMode() || (_override && isMetaDataMode());
0336:            }
0337:
0338:            ///////////////
0339:            // XML parsing
0340:            ///////////////
0341:
0342:            /**
0343:             * Push a parse element onto the stack.
0344:             */
0345:            protected void pushElement(Object elem) {
0346:                _elements.push(elem);
0347:            }
0348:
0349:            /**
0350:             * Pop a parse element from the stack.
0351:             */
0352:            protected Object popElement() {
0353:                return _elements.pop();
0354:            }
0355:
0356:            /**
0357:             * Return the current element being parsed. May be a class metadata,
0358:             * field metadata, query metadata, etc.
0359:             */
0360:            protected Object currentElement() {
0361:                if (_elements.isEmpty())
0362:                    return null;
0363:                return _elements.peek();
0364:            }
0365:
0366:            /**
0367:             * Return the current {@link PersistenceStrategy} if any.
0368:             */
0369:            protected PersistenceStrategy currentStrategy() {
0370:                return _strategy;
0371:            }
0372:
0373:            /**
0374:             * Return the tag of the current parent element.
0375:             */
0376:            protected Object currentParent() {
0377:                if (_parents.isEmpty())
0378:                    return null;
0379:                return _parents.peek();
0380:            }
0381:
0382:            /**
0383:             * Return whether we're running the parser at runtime.
0384:             */
0385:            protected boolean isRuntime() {
0386:                return (getRepository().getValidate() & MetaDataRepository.VALIDATE_RUNTIME) != 0;
0387:            }
0388:
0389:            @Override
0390:            protected Object getSchemaSource() {
0391:                return XMLPersistenceMetaDataParser.class
0392:                        .getResourceAsStream("orm-xsd.rsrc");
0393:            }
0394:
0395:            @Override
0396:            protected String getPackageAttributeName() {
0397:                return null;
0398:            }
0399:
0400:            @Override
0401:            protected String getClassAttributeName() {
0402:                return "class";
0403:            }
0404:
0405:            @Override
0406:            protected int getClassElementDepth() {
0407:                return 1;
0408:            }
0409:
0410:            @Override
0411:            protected boolean isClassElementName(String name) {
0412:                return "entity".equals(name) || "embeddable".equals(name)
0413:                        || "mapped-superclass".equals(name);
0414:            }
0415:
0416:            @Override
0417:            protected void reset() {
0418:                super .reset();
0419:                _elements.clear();
0420:                _parents.clear();
0421:                _cls = null;
0422:                _fieldPos = 0;
0423:                _clsPos = 0;
0424:
0425:                _access = ClassMetaData.ACCESS_UNKNOWN;
0426:                _strategy = null;
0427:                _listener = null;
0428:                _callbacks = null;
0429:                _highs = null;
0430:                _cascades = null;
0431:                _pkgCascades = null;
0432:            }
0433:
0434:            @Override
0435:            protected boolean startSystemElement(String name, Attributes attrs)
0436:                    throws SAXException {
0437:                Object tag = (Object) _elems.get(name);
0438:                boolean ret = false;
0439:                if (tag == null) {
0440:                    if (isMappingOverrideMode())
0441:                        tag = startSystemMappingElement(name, attrs);
0442:                    ret = tag != null;
0443:                } else if (tag instanceof  MetaDataTag) {
0444:                    switch ((MetaDataTag) tag) {
0445:                    case QUERY:
0446:                        ret = startNamedQuery(attrs);
0447:                        break;
0448:                    case QUERY_HINT:
0449:                        ret = startQueryHint(attrs);
0450:                        break;
0451:                    case NATIVE_QUERY:
0452:                        ret = startNamedNativeQuery(attrs);
0453:                        break;
0454:                    case QUERY_STRING:
0455:                        ret = startQueryString(attrs);
0456:                        break;
0457:                    case SEQ_GENERATOR:
0458:                        ret = startSequenceGenerator(attrs);
0459:                        break;
0460:                    case FLUSH_MODE:
0461:                        ret = startFlushMode(attrs);
0462:                        break;
0463:                    case ENTITY_LISTENERS:
0464:                        ret = startEntityListeners(attrs);
0465:                        break;
0466:                    case PRE_PERSIST:
0467:                    case POST_PERSIST:
0468:                    case PRE_REMOVE:
0469:                    case POST_REMOVE:
0470:                    case PRE_UPDATE:
0471:                    case POST_UPDATE:
0472:                    case POST_LOAD:
0473:                        ret = startCallback((MetaDataTag) tag, attrs);
0474:                        break;
0475:                    default:
0476:                        warnUnsupportedTag(name);
0477:                    }
0478:                } else if (tag == ELEM_PU_META || tag == ELEM_PU_DEF)
0479:                    ret = isMetaDataMode();
0480:                else if (tag == ELEM_XML_MAP_META_COMPLETE)
0481:                    setAnnotationParser(null);
0482:                else if (tag == ELEM_ACCESS)
0483:                    ret = _mode != MODE_QUERY;
0484:                else if (tag == ELEM_LISTENER)
0485:                    ret = startEntityListener(attrs);
0486:                else if (tag == ELEM_CASCADE)
0487:                    ret = isMetaDataMode();
0488:                else if (tag == ELEM_CASCADE_ALL || tag == ELEM_CASCADE_PER
0489:                        || tag == ELEM_CASCADE_MER || tag == ELEM_CASCADE_REM
0490:                        || tag == ELEM_CASCADE_REF)
0491:                    ret = startCascade(tag, attrs);
0492:
0493:                if (ret)
0494:                    _parents.push(tag);
0495:                return ret;
0496:            }
0497:
0498:            @Override
0499:            protected void endSystemElement(String name) throws SAXException {
0500:                Object tag = _elems.get(name);
0501:                if (tag == null && isMappingOverrideMode())
0502:                    endSystemMappingElement(name);
0503:                else if (tag instanceof  MetaDataTag) {
0504:                    switch ((MetaDataTag) tag) {
0505:                    case QUERY:
0506:                        endNamedQuery();
0507:                        break;
0508:                    case QUERY_HINT:
0509:                        endQueryHint();
0510:                        break;
0511:                    case NATIVE_QUERY:
0512:                        endNamedNativeQuery();
0513:                        break;
0514:                    case QUERY_STRING:
0515:                        endQueryString();
0516:                        break;
0517:                    case SEQ_GENERATOR:
0518:                        endSequenceGenerator();
0519:                        break;
0520:                    }
0521:                } else if (tag == ELEM_ACCESS)
0522:                    endAccess();
0523:                else if (tag == ELEM_LISTENER)
0524:                    endEntityListener();
0525:
0526:                _parents.pop();
0527:            }
0528:
0529:            /**
0530:             * Implement to parse a mapping element outside of any class.
0531:             *
0532:             * @return the tag for the given element, or null to skip the element
0533:             */
0534:            protected Object startSystemMappingElement(String name,
0535:                    Attributes attrs) throws SAXException {
0536:                return null;
0537:            }
0538:
0539:            /**
0540:             * Implement to parse a mapping element outside of any class.
0541:             */
0542:            protected void endSystemMappingElement(String name)
0543:                    throws SAXException {
0544:            }
0545:
0546:            @Override
0547:            protected boolean startClassElement(String name, Attributes attrs)
0548:                    throws SAXException {
0549:                Object tag = (Object) _elems.get(name);
0550:                boolean ret = false;
0551:                if (tag == null) {
0552:                    if (isMappingOverrideMode())
0553:                        tag = startClassMappingElement(name, attrs);
0554:                    ret = tag != null;
0555:                } else if (tag instanceof  MetaDataTag) {
0556:                    switch ((MetaDataTag) tag) {
0557:                    case GENERATED_VALUE:
0558:                        ret = startGeneratedValue(attrs);
0559:                        break;
0560:                    case ID:
0561:                        ret = startId(attrs);
0562:                        break;
0563:                    case EMBEDDED_ID:
0564:                        ret = startEmbeddedId(attrs);
0565:                        break;
0566:                    case ID_CLASS:
0567:                        ret = startIdClass(attrs);
0568:                        break;
0569:                    case LOB:
0570:                        ret = startLob(attrs);
0571:                        break;
0572:                    case QUERY:
0573:                        ret = startNamedQuery(attrs);
0574:                        break;
0575:                    case QUERY_HINT:
0576:                        ret = startQueryHint(attrs);
0577:                        break;
0578:                    case NATIVE_QUERY:
0579:                        ret = startNamedNativeQuery(attrs);
0580:                        break;
0581:                    case QUERY_STRING:
0582:                        ret = startQueryString(attrs);
0583:                        break;
0584:                    case SEQ_GENERATOR:
0585:                        ret = startSequenceGenerator(attrs);
0586:                        break;
0587:                    case VERSION:
0588:                        ret = startVersion(attrs);
0589:                        break;
0590:                    case MAP_KEY:
0591:                        ret = startMapKey(attrs);
0592:                        break;
0593:                    case FLUSH_MODE:
0594:                        ret = startFlushMode(attrs);
0595:                        break;
0596:                    case ORDER_BY:
0597:                    case ENTITY_LISTENERS:
0598:                        ret = isMetaDataMode();
0599:                        break;
0600:                    case EXCLUDE_DEFAULT_LISTENERS:
0601:                        ret = startExcludeDefaultListeners(attrs);
0602:                        break;
0603:                    case EXCLUDE_SUPERCLASS_LISTENERS:
0604:                        ret = startExcludeSuperclassListeners(attrs);
0605:                        break;
0606:                    case PRE_PERSIST:
0607:                    case POST_PERSIST:
0608:                    case PRE_REMOVE:
0609:                    case POST_REMOVE:
0610:                    case PRE_UPDATE:
0611:                    case POST_UPDATE:
0612:                    case POST_LOAD:
0613:                        ret = startCallback((MetaDataTag) tag, attrs);
0614:                        break;
0615:                    default:
0616:                        warnUnsupportedTag(name);
0617:                    }
0618:                } else if (tag instanceof  PersistenceStrategy) {
0619:                    PersistenceStrategy ps = (PersistenceStrategy) tag;
0620:                    ret = startStrategy(ps, attrs);
0621:                    if (ret)
0622:                        _strategy = ps;
0623:                } else if (tag == ELEM_LISTENER)
0624:                    ret = startEntityListener(attrs);
0625:                else if (tag == ELEM_ATTRS)
0626:                    ret = _mode != MODE_QUERY;
0627:                else if (tag == ELEM_CASCADE)
0628:                    ret = isMetaDataMode();
0629:                else if (tag == ELEM_CASCADE_ALL || tag == ELEM_CASCADE_PER
0630:                        || tag == ELEM_CASCADE_MER || tag == ELEM_CASCADE_REM
0631:                        || tag == ELEM_CASCADE_REF)
0632:                    ret = startCascade(tag, attrs);
0633:
0634:                if (ret)
0635:                    _parents.push(tag);
0636:                return ret;
0637:            }
0638:
0639:            @Override
0640:            protected void endClassElement(String name) throws SAXException {
0641:                Object tag = _elems.get(name);
0642:                if (tag == null && isMappingOverrideMode())
0643:                    endClassMappingElement(name);
0644:                else if (tag instanceof  MetaDataTag) {
0645:                    switch ((MetaDataTag) tag) {
0646:                    case GENERATED_VALUE:
0647:                        endGeneratedValue();
0648:                        break;
0649:                    case ID:
0650:                        endId();
0651:                        break;
0652:                    case EMBEDDED_ID:
0653:                        endEmbeddedId();
0654:                        break;
0655:                    case ID_CLASS:
0656:                        endIdClass();
0657:                        break;
0658:                    case LOB:
0659:                        endLob();
0660:                        break;
0661:                    case QUERY:
0662:                        endNamedQuery();
0663:                        break;
0664:                    case QUERY_HINT:
0665:                        endQueryHint();
0666:                        break;
0667:                    case NATIVE_QUERY:
0668:                        endNamedNativeQuery();
0669:                        break;
0670:                    case QUERY_STRING:
0671:                        endQueryString();
0672:                        break;
0673:                    case SEQ_GENERATOR:
0674:                        endSequenceGenerator();
0675:                        break;
0676:                    case VERSION:
0677:                        endVersion();
0678:                        break;
0679:                    case ORDER_BY:
0680:                        endOrderBy();
0681:                        break;
0682:                    }
0683:                } else if (tag instanceof  PersistenceStrategy)
0684:                    endStrategy((PersistenceStrategy) tag);
0685:                else if (tag == ELEM_ACCESS)
0686:                    endAccess();
0687:                else if (tag == ELEM_LISTENER)
0688:                    endEntityListener();
0689:
0690:                _parents.pop();
0691:            }
0692:
0693:            /**
0694:             * Log warning about an unsupported tag.
0695:             */
0696:            private void warnUnsupportedTag(String name) {
0697:                Log log = getLog();
0698:                if (log.isInfoEnabled())
0699:                    log.trace(_loc.get("unsupported-tag", name));
0700:            }
0701:
0702:            /**
0703:             * Implement to parse a mapping element within a class.
0704:             *
0705:             * @return the tag for the given element, or null to skip element
0706:             */
0707:            protected Object startClassMappingElement(String name,
0708:                    Attributes attrs) throws SAXException {
0709:                return null;
0710:            }
0711:
0712:            /**
0713:             * Implement to parse a mapping element within a class.
0714:             */
0715:            protected void endClassMappingElement(String name)
0716:                    throws SAXException {
0717:            }
0718:
0719:            @Override
0720:            protected boolean startClass(String elem, Attributes attrs)
0721:                    throws SAXException {
0722:                super .startClass(elem, attrs);
0723:
0724:                // query mode only?
0725:                _cls = classForName(currentClassName());
0726:                if (_mode == MODE_QUERY) {
0727:                    if (_parser != null
0728:                            && !"true".equals(attrs
0729:                                    .getValue("metadata-complete")))
0730:                        _parser.parse(_cls);
0731:                    return true;
0732:                }
0733:
0734:                Log log = getLog();
0735:                if (log.isTraceEnabled())
0736:                    log.trace(_loc.get("parse-class", _cls.getName()));
0737:
0738:                MetaDataRepository repos = getRepository();
0739:                ClassMetaData meta = repos.getCachedMetaData(_cls);
0740:                if (meta != null
0741:                        && ((isMetaDataMode() && (meta.getSourceMode() & MODE_META) != 0) || (isMappingMode() && (meta
0742:                                .getSourceMode() & MODE_MAPPING) != 0))) {
0743:                    if (log.isWarnEnabled())
0744:                        log.warn(_loc
0745:                                .get("dup-metadata", _cls, getSourceName()));
0746:                    _cls = null;
0747:                    return false;
0748:                }
0749:
0750:                // if we don't know the access type, check to see if a superclass
0751:                // has already defined the access type
0752:                int defaultAccess = _access;
0753:                if (defaultAccess == ClassMetaData.ACCESS_UNKNOWN) {
0754:                    ClassMetaData sup = repos.getCachedMetaData(_cls
0755:                            .getSuperclass());
0756:                    if (sup != null)
0757:                        defaultAccess = sup.getAccessType();
0758:                }
0759:
0760:                if (meta == null) {
0761:                    // add metadata for this type
0762:                    int access = toAccessType(attrs.getValue("access"),
0763:                            defaultAccess);
0764:                    meta = repos.addMetaData(_cls, access);
0765:                    meta.setEnvClassLoader(_envLoader);
0766:                    meta.setSourceMode(MODE_NONE);
0767:
0768:                    // parse annotations first so XML overrides them
0769:                    if (_parser != null
0770:                            && !"true".equals(attrs
0771:                                    .getValue("metadata-complete")))
0772:                        _parser.parse(_cls);
0773:                }
0774:
0775:                boolean mappedSuper = "mapped-superclass".equals(elem);
0776:                if (isMetaDataMode()) {
0777:                    meta.setSource(getSourceFile(), meta.SRC_XML);
0778:                    meta.setSourceMode(MODE_META, true);
0779:                    meta.setListingIndex(_clsPos);
0780:                    String name = attrs.getValue("name");
0781:                    if (!StringUtils.isEmpty(name))
0782:                        meta.setTypeAlias(name);
0783:                    meta.setEmbeddedOnly(mappedSuper
0784:                            || "embeddable".equals(elem));
0785:                    if (mappedSuper)
0786:                        meta.setIdentityType(meta.ID_UNKNOWN);
0787:                }
0788:                if (isMappingMode())
0789:                    meta.setSourceMode(MODE_MAPPING, true);
0790:                if (isMappingOverrideMode())
0791:                    startClassMapping(meta, mappedSuper, attrs);
0792:                if (isQueryMode())
0793:                    meta.setSourceMode(MODE_QUERY, true);
0794:
0795:                _clsPos++;
0796:                _fieldPos = 0;
0797:                addComments(meta);
0798:                pushElement(meta);
0799:                return true;
0800:            }
0801:
0802:            @Override
0803:            protected void endClass(String elem) throws SAXException {
0804:                if (_mode != MODE_QUERY) {
0805:                    ClassMetaData meta = (ClassMetaData) popElement();
0806:                    storeCallbacks(meta);
0807:                    if (isMappingOverrideMode())
0808:                        endClassMapping(meta);
0809:                }
0810:                _cls = null;
0811:                super .endClass(elem);
0812:            }
0813:
0814:            /**
0815:             * Implement to add mapping attributes to class.
0816:             */
0817:            protected void startClassMapping(ClassMetaData mapping,
0818:                    boolean mappedSuper, Attributes attrs) throws SAXException {
0819:            }
0820:
0821:            /**
0822:             * Implement to finalize class mapping.
0823:             */
0824:            protected void endClassMapping(ClassMetaData mapping)
0825:                    throws SAXException {
0826:            }
0827:
0828:            /**
0829:             * Default access element.
0830:             */
0831:            private void endAccess() {
0832:                _access = toAccessType(currentText(),
0833:                        ClassMetaData.ACCESS_UNKNOWN);
0834:            }
0835:
0836:            /**
0837:             * Parse the given string as an entity access type, defaulting to given
0838:             * default if string is empty.
0839:             */
0840:            private int toAccessType(String str, int def) {
0841:                if (StringUtils.isEmpty(str))
0842:                    return def;
0843:                if ("PROPERTY".equals(str))
0844:                    return ClassMetaData.ACCESS_PROPERTY;
0845:                return ClassMetaData.ACCESS_FIELD;
0846:            }
0847:
0848:            /**
0849:             * Parse flush-mode element.
0850:             */
0851:            private boolean startFlushMode(Attributes attrs)
0852:                    throws SAXException {
0853:                Log log = getLog();
0854:                if (log.isWarnEnabled())
0855:                    log.warn(_loc.get("unsupported", "flush-mode",
0856:                            getSourceName()));
0857:                return false;
0858:            }
0859:
0860:            /**
0861:             * Parse sequence-generator.
0862:             */
0863:            protected boolean startSequenceGenerator(Attributes attrs) {
0864:                if (!isMappingOverrideMode())
0865:                    return false;
0866:
0867:                String name = attrs.getValue("name");
0868:                Log log = getLog();
0869:                if (log.isTraceEnabled())
0870:                    log.trace(_loc.get("parse-sequence", name));
0871:
0872:                SequenceMetaData meta = getRepository()
0873:                        .getCachedSequenceMetaData(name);
0874:                if (meta != null && log.isWarnEnabled())
0875:                    log.warn(_loc.get("override-sequence", name));
0876:
0877:                meta = getRepository().addSequenceMetaData(name);
0878:                String seq = attrs.getValue("sequence-name");
0879:                String val = attrs.getValue("initial-value");
0880:                int initial = val == null ? 1 : Integer.parseInt(val);
0881:                val = attrs.getValue("allocation-size");
0882:                int allocate = val == null ? 50 : Integer.parseInt(val);
0883:
0884:                String clsName, props;
0885:                if (seq == null || seq.indexOf('(') == -1) {
0886:                    clsName = SequenceMetaData.IMPL_NATIVE;
0887:                    props = null;
0888:                } else { // plugin
0889:                    clsName = Configurations.getClassName(seq);
0890:                    props = Configurations.getProperties(seq);
0891:                    seq = null;
0892:                }
0893:
0894:                meta
0895:                        .setSequencePlugin(Configurations.getPlugin(clsName,
0896:                                props));
0897:                meta.setSequence(seq);
0898:                meta.setInitialValue(initial);
0899:                meta.setAllocate(allocate);
0900:
0901:                Object cur = currentElement();
0902:                Object scope = (cur instanceof  ClassMetaData) ? ((ClassMetaData) cur)
0903:                        .getDescribedType()
0904:                        : null;
0905:                meta.setSource(getSourceFile(), scope, meta.SRC_XML);
0906:                return true;
0907:            }
0908:
0909:            protected void endSequenceGenerator() {
0910:            }
0911:
0912:            /**
0913:             * Parse id.
0914:             */
0915:            protected boolean startId(Attributes attrs) throws SAXException {
0916:                FieldMetaData fmd = parseField(attrs);
0917:                fmd.setExplicit(true);
0918:                fmd.setPrimaryKey(true);
0919:                return true;
0920:            }
0921:
0922:            protected void endId() throws SAXException {
0923:                finishField();
0924:            }
0925:
0926:            /**
0927:             * Parse embedded-id.
0928:             */
0929:            protected boolean startEmbeddedId(Attributes attrs)
0930:                    throws SAXException {
0931:                FieldMetaData fmd = parseField(attrs);
0932:                fmd.setExplicit(true);
0933:                fmd.setPrimaryKey(true);
0934:                fmd.setEmbedded(true);
0935:                if (fmd.getEmbeddedMetaData() == null)
0936:                    fmd.addEmbeddedMetaData();
0937:                return true;
0938:            }
0939:
0940:            protected void endEmbeddedId() throws SAXException {
0941:                finishField();
0942:            }
0943:
0944:            /**
0945:             * Parse id-class.
0946:             */
0947:            protected boolean startIdClass(Attributes attrs)
0948:                    throws SAXException {
0949:                if (!isMetaDataMode())
0950:                    return false;
0951:
0952:                ClassMetaData meta = (ClassMetaData) currentElement();
0953:                String cls = attrs.getValue("class");
0954:                Class idCls = null;
0955:                try {
0956:                    idCls = classForName(cls);
0957:                } catch (Throwable t) {
0958:                    throw getException(_loc.get("invalid-id-class", meta, cls),
0959:                            t);
0960:                }
0961:                meta.setObjectIdType(idCls, true);
0962:                return true;
0963:            }
0964:
0965:            protected void endIdClass() throws SAXException {
0966:            }
0967:
0968:            /**
0969:             * Parse lob.
0970:             */
0971:            protected boolean startLob(Attributes attrs) throws SAXException {
0972:                FieldMetaData fmd = (FieldMetaData) currentElement();
0973:                if (fmd.getDeclaredTypeCode() != JavaTypes.STRING
0974:                        && fmd.getDeclaredType() != char[].class
0975:                        && fmd.getDeclaredType() != Character[].class
0976:                        && fmd.getDeclaredType() != byte[].class
0977:                        && fmd.getDeclaredType() != Byte[].class)
0978:                    fmd.setSerialized(true);
0979:                return true;
0980:            }
0981:
0982:            protected void endLob() throws SAXException {
0983:            }
0984:
0985:            /**
0986:             * Parse generated-value.
0987:             */
0988:            protected boolean startGeneratedValue(Attributes attrs)
0989:                    throws SAXException {
0990:                if (!isMappingOverrideMode())
0991:                    return false;
0992:
0993:                String strategy = attrs.getValue("strategy");
0994:                String generator = attrs.getValue("generator");
0995:                GenerationType type = StringUtils.isEmpty(strategy) ? GenerationType.AUTO
0996:                        : GenerationType.valueOf(strategy);
0997:
0998:                FieldMetaData fmd = (FieldMetaData) currentElement();
0999:                AnnotationPersistenceMetaDataParser.parseGeneratedValue(fmd,
1000:                        type, generator);
1001:                return true;
1002:            }
1003:
1004:            protected void endGeneratedValue() throws SAXException {
1005:            }
1006:
1007:            /**
1008:             * Lazily parse cascades.
1009:             */
1010:            protected boolean startCascade(Object tag, Attributes attrs)
1011:                    throws SAXException {
1012:                if (!isMetaDataMode())
1013:                    return false;
1014:
1015:                Set<CascadeType> cascades = null;
1016:                if (currentElement() instanceof  FieldMetaData) {
1017:                    if (_cascades == null)
1018:                        _cascades = EnumSet.noneOf(CascadeType.class);
1019:                    cascades = _cascades;
1020:                } else {
1021:                    if (_pkgCascades == null)
1022:                        _pkgCascades = EnumSet.noneOf(CascadeType.class);
1023:                    cascades = _pkgCascades;
1024:                }
1025:                boolean all = ELEM_CASCADE_ALL == tag;
1026:                if (all || ELEM_CASCADE_PER == tag)
1027:                    cascades.add(PERSIST);
1028:                if (all || ELEM_CASCADE_REM == tag)
1029:                    cascades.add(REMOVE);
1030:                if (all || ELEM_CASCADE_MER == tag)
1031:                    cascades.add(MERGE);
1032:                if (all || ELEM_CASCADE_REF == tag)
1033:                    cascades.add(REFRESH);
1034:                return true;
1035:            }
1036:
1037:            /**
1038:             * Set the cached cascades into the field.
1039:             */
1040:            protected void setCascades(FieldMetaData fmd) {
1041:                Set<CascadeType> cascades = _cascades;
1042:                if (_cascades == null)
1043:                    cascades = _pkgCascades;
1044:                if (cascades == null)
1045:                    return;
1046:
1047:                ValueMetaData vmd = fmd;
1048:                switch (_strategy) {
1049:                case ONE_MANY:
1050:                case MANY_MANY:
1051:                    vmd = fmd.getElement();
1052:                }
1053:                for (CascadeType cascade : cascades) {
1054:                    switch (cascade) {
1055:                    case PERSIST:
1056:                        vmd.setCascadePersist(ValueMetaData.CASCADE_IMMEDIATE);
1057:                        break;
1058:                    case MERGE:
1059:                        vmd.setCascadeAttach(ValueMetaData.CASCADE_IMMEDIATE);
1060:                        break;
1061:                    case REMOVE:
1062:                        vmd.setCascadeDelete(ValueMetaData.CASCADE_IMMEDIATE);
1063:                        break;
1064:                    case REFRESH:
1065:                        vmd.setCascadeRefresh(ValueMetaData.CASCADE_IMMEDIATE);
1066:                        break;
1067:                    }
1068:                }
1069:                _cascades = null;
1070:            }
1071:
1072:            /**
1073:             * Parse common field attributes.
1074:             */
1075:            private FieldMetaData parseField(Attributes attrs)
1076:                    throws SAXException {
1077:                ClassMetaData meta = (ClassMetaData) currentElement();
1078:                String name = attrs.getValue("name");
1079:                FieldMetaData field = meta.getDeclaredField(name);
1080:                if ((field == null || field.getDeclaredType() == Object.class)
1081:                        && meta.getDescribedType() != Object.class) {
1082:                    Member member = null;
1083:                    Class type = null;
1084:                    int def = _repos.getMetaDataFactory().getDefaults()
1085:                            .getDefaultAccessType();
1086:                    try {
1087:                        if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY
1088:                                || (meta.getAccessType() == ClassMetaData.ACCESS_UNKNOWN && def == ClassMetaData.ACCESS_PROPERTY)) {
1089:                            String cap = StringUtils.capitalize(name);
1090:                            type = meta.getDescribedType();
1091:                            try {
1092:                                member = (Method) AccessController
1093:                                        .doPrivileged(J2DoPrivHelper
1094:                                                .getDeclaredMethodAction(type,
1095:                                                        "get" + cap,
1096:                                                        (Class[]) null));// varargs disambiguate
1097:                            } catch (Exception excep) {
1098:                                try {
1099:                                    member = (Method) AccessController
1100:                                            .doPrivileged(J2DoPrivHelper
1101:                                                    .getDeclaredMethodAction(
1102:                                                            type, "is" + cap,
1103:                                                            (Class[]) null));
1104:                                } catch (Exception excep2) {
1105:                                    throw excep;
1106:                                }
1107:                            }
1108:                            type = ((Method) member).getReturnType();
1109:                        } else {
1110:                            member = (Field) AccessController
1111:                                    .doPrivileged(J2DoPrivHelper
1112:                                            .getDeclaredFieldAction(meta
1113:                                                    .getDescribedType(), name));
1114:                            type = ((Field) member).getType();
1115:                        }
1116:                    } catch (Exception e) {
1117:                        if (e instanceof  PrivilegedActionException)
1118:                            e = ((PrivilegedActionException) e).getException();
1119:                        throw getException(
1120:                                _loc.get("invalid-attr", name, meta), e);
1121:                    }
1122:
1123:                    if (field == null) {
1124:                        field = meta.addDeclaredField(name, type);
1125:                        PersistenceMetaDataDefaults.setCascadeNone(field);
1126:                        PersistenceMetaDataDefaults.setCascadeNone(field
1127:                                .getKey());
1128:                        PersistenceMetaDataDefaults.setCascadeNone(field
1129:                                .getElement());
1130:                    }
1131:                    field.backingMember(member);
1132:                } else if (field == null) {
1133:                    field = meta.addDeclaredField(name, Object.class);
1134:                    PersistenceMetaDataDefaults.setCascadeNone(field);
1135:                    PersistenceMetaDataDefaults.setCascadeNone(field.getKey());
1136:                    PersistenceMetaDataDefaults.setCascadeNone(field
1137:                            .getElement());
1138:                }
1139:
1140:                if (isMetaDataMode())
1141:                    field.setListingIndex(_fieldPos);
1142:
1143:                _fieldPos++;
1144:                pushElement(field);
1145:                addComments(field);
1146:
1147:                if (isMappingOverrideMode())
1148:                    startFieldMapping(field, attrs);
1149:                return field;
1150:            }
1151:
1152:            /**
1153:             * Pops field element.
1154:             */
1155:            private void finishField() throws SAXException {
1156:                FieldMetaData field = (FieldMetaData) popElement();
1157:                setCascades(field);
1158:                if (isMappingOverrideMode())
1159:                    endFieldMapping(field);
1160:                _strategy = null;
1161:            }
1162:
1163:            /**
1164:             * Implement to add field mapping data. Does nothing by default.
1165:             */
1166:            protected void startFieldMapping(FieldMetaData field,
1167:                    Attributes attrs) throws SAXException {
1168:            }
1169:
1170:            /**
1171:             * Implement to finalize field mapping. Does nothing by default.
1172:             */
1173:            protected void endFieldMapping(FieldMetaData field)
1174:                    throws SAXException {
1175:            }
1176:
1177:            /**
1178:             * Parse version.
1179:             */
1180:            protected boolean startVersion(Attributes attrs)
1181:                    throws SAXException {
1182:                FieldMetaData fmd = parseField(attrs);
1183:                fmd.setExplicit(true);
1184:                fmd.setVersion(true);
1185:                return true;
1186:            }
1187:
1188:            protected void endVersion() throws SAXException {
1189:                finishField();
1190:            }
1191:
1192:            /**
1193:             * Parse strategy element.
1194:             */
1195:            private boolean startStrategy(PersistenceStrategy strategy,
1196:                    Attributes attrs) throws SAXException {
1197:                FieldMetaData fmd = parseField(attrs);
1198:                fmd.setExplicit(true);
1199:                fmd.setManagement(FieldMetaData.MANAGE_PERSISTENT);
1200:
1201:                String val = attrs.getValue("fetch");
1202:                if (val != null)
1203:                    fmd.setInDefaultFetchGroup("EAGER".equals(val));
1204:                val = attrs.getValue("optional");
1205:                if ("false".equals(val))
1206:                    fmd.setNullValue(FieldMetaData.NULL_EXCEPTION);
1207:                else if ("true".equals(val)
1208:                        && fmd.getNullValue() == FieldMetaData.NULL_EXCEPTION) {
1209:                    // Reset value if the field was annotated with optional=false. 
1210:                    // Otherwise leave it alone.
1211:                    fmd.setNullValue(FieldMetaData.NULL_UNSET);
1212:                }
1213:                if (isMappingOverrideMode()) {
1214:                    val = attrs.getValue("mapped-by");
1215:                    if (val != null)
1216:                        fmd.setMappedBy(val);
1217:                }
1218:                parseStrategy(fmd, strategy, attrs);
1219:                return true;
1220:            }
1221:
1222:            private void endStrategy(PersistenceStrategy strategy)
1223:                    throws SAXException {
1224:                finishField();
1225:            }
1226:
1227:            /**
1228:             * Parse strategy specific attributes.
1229:             */
1230:            private void parseStrategy(FieldMetaData fmd,
1231:                    PersistenceStrategy strategy, Attributes attrs)
1232:                    throws SAXException {
1233:                switch (strategy) {
1234:                case BASIC:
1235:                    parseBasic(fmd, attrs);
1236:                    break;
1237:                case EMBEDDED:
1238:                    parseEmbedded(fmd, attrs);
1239:                    break;
1240:                case ONE_ONE:
1241:                    parseOneToOne(fmd, attrs);
1242:                    break;
1243:                case MANY_ONE:
1244:                    parseManyToOne(fmd, attrs);
1245:                    break;
1246:                case MANY_MANY:
1247:                    parseManyToMany(fmd, attrs);
1248:                    break;
1249:                case ONE_MANY:
1250:                    parseOneToMany(fmd, attrs);
1251:                    break;
1252:                case TRANSIENT:
1253:                    fmd.setManagement(FieldMetaData.MANAGE_NONE);
1254:                    break;
1255:                }
1256:            }
1257:
1258:            /**
1259:             * Parse basic.
1260:             */
1261:            protected void parseBasic(FieldMetaData fmd, Attributes attrs)
1262:                    throws SAXException {
1263:            }
1264:
1265:            /**
1266:             * Parse embedded.
1267:             */
1268:            protected void parseEmbedded(FieldMetaData fmd, Attributes attrs)
1269:                    throws SAXException {
1270:                assertPC(fmd, "Embedded");
1271:                fmd.setEmbedded(true);
1272:                fmd.setSerialized(false); // override any Lob annotation
1273:                if (fmd.getEmbeddedMetaData() == null)
1274:                    fmd.addEmbeddedMetaData();
1275:            }
1276:
1277:            /**
1278:             * Throw proper exception if given value is not possibly persistence
1279:             * capable.
1280:             */
1281:            private void assertPC(FieldMetaData fmd, String attr)
1282:                    throws SAXException {
1283:                if (!JavaTypes.maybePC(fmd))
1284:                    throw getException(_loc.get("bad-meta-anno", fmd, attr));
1285:            }
1286:
1287:            /**
1288:             * Parse one-to-one.
1289:             */
1290:            protected void parseOneToOne(FieldMetaData fmd, Attributes attrs)
1291:                    throws SAXException {
1292:                String val = attrs.getValue("target-entity");
1293:                if (val != null)
1294:                    fmd.setTypeOverride(classForName(val));
1295:                assertPC(fmd, "OneToOne");
1296:                fmd.setSerialized(false); // override any Lob annotation
1297:                if (!fmd.isDefaultFetchGroupExplicit())
1298:                    fmd.setInDefaultFetchGroup(true);
1299:            }
1300:
1301:            /**
1302:             * Parse many-to-one.
1303:             */
1304:            protected void parseManyToOne(FieldMetaData fmd, Attributes attrs)
1305:                    throws SAXException {
1306:                String val = attrs.getValue("target-entity");
1307:                if (val != null)
1308:                    fmd.setTypeOverride(classForName(val));
1309:                assertPC(fmd, "ManyToOne");
1310:                fmd.setSerialized(false); // override any Lob annotation
1311:                if (!fmd.isDefaultFetchGroupExplicit())
1312:                    fmd.setInDefaultFetchGroup(true);
1313:            }
1314:
1315:            /**
1316:             * Parse many-to-many.
1317:             */
1318:            protected void parseManyToMany(FieldMetaData fmd, Attributes attrs)
1319:                    throws SAXException {
1320:                String val = attrs.getValue("target-entity");
1321:                if (val != null)
1322:                    fmd.getElement().setDeclaredType(classForName(val));
1323:                assertPCCollection(fmd, "ManyToMany");
1324:                fmd.setSerialized(false); // override Lob in annotation
1325:            }
1326:
1327:            /**
1328:             * Throw exception if given field not a collection of possible persistence
1329:             * capables.
1330:             */
1331:            private void assertPCCollection(FieldMetaData fmd, String attr)
1332:                    throws SAXException {
1333:                switch (fmd.getDeclaredTypeCode()) {
1334:                case JavaTypes.ARRAY:
1335:                case JavaTypes.COLLECTION:
1336:                case JavaTypes.MAP:
1337:                    if (JavaTypes.maybePC(fmd.getElement()))
1338:                        break;
1339:                    // no break
1340:                default:
1341:                    throw getException(_loc.get("bad-meta-anno", fmd, attr));
1342:                }
1343:            }
1344:
1345:            /**
1346:             * Parse one-to-many.
1347:             */
1348:            protected void parseOneToMany(FieldMetaData fmd, Attributes attrs)
1349:                    throws SAXException {
1350:                String val = attrs.getValue("target-entity");
1351:                if (val != null)
1352:                    fmd.getElement().setDeclaredType(classForName(val));
1353:                assertPCCollection(fmd, "OneToMany");
1354:                fmd.setSerialized(false); // override any Lob annotation
1355:            }
1356:
1357:            /**
1358:             * Parse map-key.
1359:             */
1360:            private boolean startMapKey(Attributes attrs) throws SAXException {
1361:                if (!isMappingOverrideMode())
1362:                    return false;
1363:
1364:                FieldMetaData fmd = (FieldMetaData) currentElement();
1365:                String mapKey = attrs.getValue("name");
1366:                if (mapKey == null)
1367:                    fmd.getKey().setValueMappedBy(ValueMetaData.MAPPED_BY_PK);
1368:                else
1369:                    fmd.getKey().setValueMappedBy(mapKey);
1370:                return true;
1371:            }
1372:
1373:            /**
1374:             * Parse order-by.
1375:             */
1376:            private void endOrderBy() throws SAXException {
1377:                FieldMetaData fmd = (FieldMetaData) currentElement();
1378:                String dec = currentText();
1379:                if (StringUtils.isEmpty(dec))
1380:                    dec = Order.ELEMENT + " asc";
1381:                fmd.setOrderDeclaration(dec);
1382:            }
1383:
1384:            /**
1385:             * Parse named-query.
1386:             */
1387:            protected boolean startNamedQuery(Attributes attrs)
1388:                    throws SAXException {
1389:                if (!isQueryMode())
1390:                    return false;
1391:
1392:                String name = attrs.getValue("name");
1393:                Log log = getLog();
1394:                if (log.isTraceEnabled())
1395:                    log.trace(_loc.get("parse-query", name));
1396:
1397:                QueryMetaData meta = getRepository().getCachedQueryMetaData(
1398:                        null, name);
1399:                if (meta != null && log.isWarnEnabled())
1400:                    log.warn(_loc
1401:                            .get("override-query", name, currentLocation()));
1402:
1403:                meta = getRepository().addQueryMetaData(null, name);
1404:                meta.setDefiningType(_cls);
1405:                meta.setQueryString(attrs.getValue("query"));
1406:                meta.setLanguage(JPQLParser.LANG_JPQL);
1407:
1408:                Object cur = currentElement();
1409:                Object scope = (cur instanceof  ClassMetaData) ? ((ClassMetaData) cur)
1410:                        .getDescribedType()
1411:                        : null;
1412:                meta.setSource(getSourceFile(), scope, meta.SRC_XML);
1413:                if (isMetaDataMode())
1414:                    meta.setSourceMode(MODE_META);
1415:                else if (isMappingMode())
1416:                    meta.setSourceMode(MODE_MAPPING);
1417:                else
1418:                    meta.setSourceMode(MODE_QUERY);
1419:                pushElement(meta);
1420:                return true;
1421:            }
1422:
1423:            protected void endNamedQuery() throws SAXException {
1424:                popElement();
1425:            }
1426:
1427:            protected boolean startQueryString(Attributes attrs)
1428:                    throws SAXException {
1429:                return true;
1430:            }
1431:
1432:            protected void endQueryString() throws SAXException {
1433:                QueryMetaData meta = (QueryMetaData) currentElement();
1434:                meta.setQueryString(currentText());
1435:            }
1436:
1437:            /**
1438:             * Parse query-hint.
1439:             */
1440:            protected boolean startQueryHint(Attributes attrs)
1441:                    throws SAXException {
1442:                QueryMetaData meta = (QueryMetaData) currentElement();
1443:                meta.addHint(attrs.getValue("name"), attrs.getValue("value"));
1444:                return true;
1445:            }
1446:
1447:            protected void endQueryHint() throws SAXException {
1448:            }
1449:
1450:            /**
1451:             * Parse native-named-query.
1452:             */
1453:            protected boolean startNamedNativeQuery(Attributes attrs)
1454:                    throws SAXException {
1455:                if (!isQueryMode())
1456:                    return false;
1457:
1458:                String name = attrs.getValue("name");
1459:                Log log = getLog();
1460:                if (log.isTraceEnabled())
1461:                    log.trace(_loc.get("parse-native-query", name));
1462:
1463:                QueryMetaData meta = getRepository().getCachedQueryMetaData(
1464:                        null, name);
1465:                if (meta != null && log.isWarnEnabled())
1466:                    log.warn(_loc
1467:                            .get("override-query", name, currentLocation()));
1468:
1469:                meta = getRepository().addQueryMetaData(null, name);
1470:                meta.setDefiningType(_cls);
1471:                meta.setQueryString(attrs.getValue("query"));
1472:                meta.setLanguage(QueryLanguages.LANG_SQL);
1473:                String val = attrs.getValue("result-class");
1474:                if (val != null) {
1475:                    Class type = classForName(val);
1476:                    if (ImplHelper.isManagedType(getConfiguration(), type))
1477:                        meta.setCandidateType(type);
1478:                    else
1479:                        meta.setResultType(type);
1480:                }
1481:
1482:                val = attrs.getValue("result-set-mapping");
1483:                if (val != null)
1484:                    meta.setResultSetMappingName(val);
1485:
1486:                Object cur = currentElement();
1487:                Object scope = (cur instanceof  ClassMetaData) ? ((ClassMetaData) cur)
1488:                        .getDescribedType()
1489:                        : null;
1490:                meta.setSource(getSourceFile(), scope, meta.SRC_XML);
1491:                if (isMetaDataMode())
1492:                    meta.setSourceMode(MODE_META);
1493:                else if (isMappingMode())
1494:                    meta.setSourceMode(MODE_MAPPING);
1495:                else
1496:                    meta.setSourceMode(MODE_QUERY);
1497:                pushElement(meta);
1498:                return true;
1499:            }
1500:
1501:            protected void endNamedNativeQuery() throws SAXException {
1502:                popElement();
1503:            }
1504:
1505:            /**
1506:             * Start entity-listeners
1507:             */
1508:            private boolean startEntityListeners(Attributes attrs)
1509:                    throws SAXException {
1510:                if (!isMetaDataMode())
1511:                    return false;
1512:                if (currentElement() == null)
1513:                    return true;
1514:
1515:                // reset listeners declared in annotations.
1516:                LifecycleMetaData meta = ((ClassMetaData) currentElement())
1517:                        .getLifecycleMetaData();
1518:                for (int i = 0; i < LifecycleEvent.ALL_EVENTS.length; i++)
1519:                    meta.setDeclaredCallbacks(i, null, 0);
1520:                return true;
1521:            }
1522:
1523:            /**
1524:             * Parse exclude-default-listeners.
1525:             */
1526:            private boolean startExcludeDefaultListeners(Attributes attrs)
1527:                    throws SAXException {
1528:                if (!isMetaDataMode())
1529:                    return false;
1530:                ClassMetaData meta = (ClassMetaData) currentElement();
1531:                meta.getLifecycleMetaData().setIgnoreSystemListeners(true);
1532:                return true;
1533:            }
1534:
1535:            /**
1536:             * Parse exclude-superclass-listeners.
1537:             */
1538:            private boolean startExcludeSuperclassListeners(Attributes attrs)
1539:                    throws SAXException {
1540:                if (!isMetaDataMode())
1541:                    return false;
1542:                ClassMetaData meta = (ClassMetaData) currentElement();
1543:                meta.getLifecycleMetaData().setIgnoreSuperclassCallbacks(
1544:                        LifecycleMetaData.IGNORE_HIGH);
1545:                return true;
1546:            }
1547:
1548:            /**
1549:             * Parse entity-listener.
1550:             */
1551:            private boolean startEntityListener(Attributes attrs)
1552:                    throws SAXException {
1553:                _listener = classForName(attrs.getValue("class"));
1554:                boolean system = currentElement() == null;
1555:                Collection<LifecycleCallbacks>[] parsed = AnnotationPersistenceMetaDataParser
1556:                        .parseCallbackMethods(_listener, null, true, true,
1557:                                _repos);
1558:                if (parsed == null)
1559:                    return true;
1560:
1561:                if (_callbacks == null) {
1562:                    _callbacks = (Collection<LifecycleCallbacks>[]) new Collection[LifecycleEvent.ALL_EVENTS.length];
1563:                    if (!system)
1564:                        _highs = new int[LifecycleEvent.ALL_EVENTS.length];
1565:                }
1566:                for (int i = 0; i < parsed.length; i++) {
1567:                    if (parsed[i] == null)
1568:                        continue;
1569:                    if (_callbacks[i] == null)
1570:                        _callbacks[i] = parsed[i];
1571:                    else
1572:                        _callbacks[i].addAll(parsed[i]);
1573:                    if (!system)
1574:                        _highs[i] += parsed[i].size();
1575:                }
1576:                return true;
1577:            }
1578:
1579:            private void endEntityListener() throws SAXException {
1580:                // should be in endEntityListeners I think to merge callbacks
1581:                // into a single listener.  But then the user cannot remove.
1582:                if (currentElement() == null && _callbacks != null) {
1583:                    _repos.addSystemListener(new PersistenceListenerAdapter(
1584:                            _callbacks));
1585:                    _callbacks = null;
1586:                }
1587:                _listener = null;
1588:            }
1589:
1590:            private boolean startCallback(MetaDataTag callback, Attributes attrs)
1591:                    throws SAXException {
1592:                if (!isMetaDataMode())
1593:                    return false;
1594:                int[] events = MetaDataParsers.getEventTypes(callback);
1595:                if (events == null)
1596:                    return false;
1597:
1598:                boolean system = currentElement() == null;
1599:                Class type = currentElement() == null ? null
1600:                        : ((ClassMetaData) currentElement()).getDescribedType();
1601:                if (type == null)
1602:                    type = Object.class;
1603:
1604:                if (_callbacks == null) {
1605:                    _callbacks = (Collection<LifecycleCallbacks>[]) new Collection[LifecycleEvent.ALL_EVENTS.length];
1606:                    if (!system)
1607:                        _highs = new int[LifecycleEvent.ALL_EVENTS.length];
1608:                }
1609:
1610:                MetaDataDefaults def = _repos.getMetaDataFactory()
1611:                        .getDefaults();
1612:                LifecycleCallbacks adapter;
1613:                if (_listener != null)
1614:                    adapter = new BeanLifecycleCallbacks(_listener, attrs
1615:                            .getValue("method-name"), false, type);
1616:                else
1617:                    adapter = new MethodLifecycleCallbacks(_cls, attrs
1618:                            .getValue("method-name"), false);
1619:
1620:                for (int i = 0; i < events.length; i++) {
1621:                    int event = events[i];
1622:                    if (_listener != null) {
1623:                        MetaDataParsers.validateMethodsForSameCallback(
1624:                                _listener, _callbacks[event],
1625:                                ((BeanLifecycleCallbacks) adapter)
1626:                                        .getCallbackMethod(), callback, def,
1627:                                getLog());
1628:                    } else {
1629:                        MetaDataParsers.validateMethodsForSameCallback(_cls,
1630:                                _callbacks[event],
1631:                                ((MethodLifecycleCallbacks) adapter)
1632:                                        .getCallbackMethod(), callback, def,
1633:                                getLog());
1634:
1635:                    }
1636:                    if (_callbacks[event] == null)
1637:                        _callbacks[event] = new ArrayList<LifecycleCallbacks>(3);
1638:                    _callbacks[event].add(adapter);
1639:                    if (!system && _listener != null)
1640:                        _highs[event]++;
1641:                }
1642:                return true;
1643:            }
1644:
1645:            /**
1646:             * Store lifecycle metadata.
1647:             */
1648:            private void storeCallbacks(ClassMetaData cls) {
1649:                LifecycleMetaData meta = cls.getLifecycleMetaData();
1650:                Class supCls = cls.getDescribedType().getSuperclass();
1651:                Collection<LifecycleCallbacks>[] supCalls = null;
1652:                if (!Object.class.equals(supCls)) {
1653:                    supCalls = AnnotationPersistenceMetaDataParser
1654:                            .parseCallbackMethods(supCls, null, true, false,
1655:                                    _repos);
1656:                }
1657:                if (supCalls != null) {
1658:                    for (int event : LifecycleEvent.ALL_EVENTS) {
1659:                        if (supCalls[event] == null)
1660:                            continue;
1661:                        meta.setNonPCSuperclassCallbacks(event, supCalls[event]
1662:                                .toArray(new LifecycleCallbacks[supCalls[event]
1663:                                        .size()]), 0);
1664:                    }
1665:                }
1666:                if (_callbacks == null)
1667:                    return;
1668:
1669:                for (int event : LifecycleEvent.ALL_EVENTS) {
1670:                    if (_callbacks[event] == null)
1671:                        continue;
1672:                    meta
1673:                            .setDeclaredCallbacks(
1674:                                    event,
1675:                                    (LifecycleCallbacks[]) _callbacks[event]
1676:                                            .toArray(new LifecycleCallbacks[_callbacks[event]
1677:                                                    .size()]), _highs[event]);
1678:                }
1679:                _callbacks = null;
1680:                _highs = null;
1681:            }
1682:
1683:            /**
1684:             * Instantiate the given class, taking into account the default package.
1685:             */
1686:            protected Class classForName(String name) throws SAXException {
1687:                if ("Entity".equals(name))
1688:                    return PersistenceCapable.class;
1689:                return super.classForName(name, isRuntime());
1690:            }
1691:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.