Source Code Cross Referenced for XMLPersistenceMetaDataSerializer.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.io.File;
0022:        import java.lang.reflect.Field;
0023:        import java.lang.reflect.Member;
0024:        import java.lang.reflect.Method;
0025:        import java.util.ArrayList;
0026:        import java.util.Arrays;
0027:        import java.util.Collection;
0028:        import java.util.Collections;
0029:        import java.util.Comparator;
0030:        import java.util.HashMap;
0031:        import java.util.Iterator;
0032:        import java.util.List;
0033:        import java.util.Map;
0034:        import java.util.Properties;
0035:
0036:        import org.apache.commons.lang.StringUtils;
0037:        import org.apache.openjpa.conf.OpenJPAConfiguration;
0038:        import org.apache.openjpa.kernel.QueryLanguages;
0039:        import org.apache.openjpa.lib.conf.Configurations;
0040:        import org.apache.openjpa.lib.log.Log;
0041:        import org.apache.openjpa.lib.meta.CFMetaDataSerializer;
0042:        import org.apache.openjpa.lib.meta.SourceTracker;
0043:        import org.apache.openjpa.lib.util.JavaVersions;
0044:        import org.apache.openjpa.lib.util.Localizer;
0045:        import org.apache.openjpa.meta.ClassMetaData;
0046:        import org.apache.openjpa.meta.FieldMetaData;
0047:        import org.apache.openjpa.meta.JavaTypes;
0048:        import org.apache.openjpa.meta.MetaDataInheritanceComparator;
0049:        import static org.apache.openjpa.meta.MetaDataModes.*;
0050:        import org.apache.openjpa.meta.MetaDataRepository;
0051:        import org.apache.openjpa.meta.Order;
0052:        import org.apache.openjpa.meta.QueryMetaData;
0053:        import org.apache.openjpa.meta.SequenceMetaData;
0054:        import org.apache.openjpa.meta.ValueMetaData;
0055:        import org.apache.openjpa.util.InternalException;
0056:        import org.xml.sax.SAXException;
0057:        import serp.util.Strings;
0058:
0059:        /**
0060:         * Serializes persistence metadata back to XML.
0061:         * This class processes all object level tags that are store-agnostic.
0062:         * However, it provides hooks for the subclasses to include store-specific
0063:         * tags to be serialized both at <entity-mappings> and
0064:         * <entity> level.
0065:         *
0066:         * @since 0.4.0
0067:         * @author Steve Kim
0068:         * @nojavadoc
0069:         */
0070:        public class XMLPersistenceMetaDataSerializer extends
0071:                CFMetaDataSerializer implements 
0072:                PersistenceMetaDataFactory.Serializer {
0073:
0074:            // NOTE: order is important! these constants must be maintained in
0075:            // serialization order. constants are spaced so that subclasses can
0076:            // slip tags in-between
0077:            protected static final int TYPE_SEQ = 10;
0078:            protected static final int TYPE_QUERY = 20;
0079:            protected static final int TYPE_META = 30;
0080:            protected static final int TYPE_CLASS_SEQS = 40;
0081:            protected static final int TYPE_CLASS_QUERIES = 50;
0082:
0083:            private static final Localizer _loc = Localizer
0084:                    .forPackage(XMLPersistenceMetaDataSerializer.class);
0085:
0086:            private final OpenJPAConfiguration _conf;
0087:            private Map<String, ClassMetaData> _metas = null;
0088:            private Map<String, List> _queries = null;
0089:            private Map<String, List> _seqs = null;
0090:            private int _mode = MODE_NONE;
0091:            private boolean _annos = true;
0092:            private SerializationComparator _comp = null;
0093:
0094:            /**
0095:             * Constructor. Supply configuration.
0096:             */
0097:            public XMLPersistenceMetaDataSerializer(OpenJPAConfiguration conf) {
0098:                _conf = conf;
0099:                setLog(conf.getLog(OpenJPAConfiguration.LOG_METADATA));
0100:                setMode(MODE_META | MODE_MAPPING | MODE_QUERY);
0101:            }
0102:
0103:            /**
0104:             * Configuration.
0105:             */
0106:            public OpenJPAConfiguration getConfiguration() {
0107:                return _conf;
0108:            }
0109:
0110:            /**
0111:             * Whether to serialize content originally specified in annotations.
0112:             * Defaults to true.
0113:             */
0114:            public boolean getSerializeAnnotations() {
0115:                return _annos;
0116:            }
0117:
0118:            /**
0119:             * Whether to serialize content originally specified in annotations.
0120:             * Defaults to true.
0121:             */
0122:            public void setSerializeAnnotations(boolean annos) {
0123:                _annos = annos;
0124:            }
0125:
0126:            /**
0127:             * The serialization mode according to the expected document type. The
0128:             * mode constants act as bit flags, and therefore can be combined.
0129:             */
0130:            public int getMode() {
0131:                return _mode;
0132:            }
0133:
0134:            /**
0135:             * The serialization mode according to the expected document type. The
0136:             * mode constants act as bit flags, and therefore can be combined.
0137:             */
0138:            public void setMode(int mode) {
0139:                _mode = mode;
0140:            }
0141:
0142:            /**
0143:             * The serialization mode according to the expected document type.
0144:             */
0145:            public void setMode(int mode, boolean on) {
0146:                if (mode == MODE_NONE)
0147:                    setMode(MODE_NONE);
0148:                else if (on)
0149:                    setMode(_mode | mode);
0150:                else
0151:                    setMode(_mode & ~mode);
0152:            }
0153:
0154:            /**
0155:             * Override to not overwrite annotations.
0156:             */
0157:            @Override
0158:            protected File getSourceFile(Object obj) {
0159:                File file = super .getSourceFile(obj);
0160:                if (file == null || file.getName().endsWith(".java")
0161:                        || file.getName().endsWith(".class"))
0162:                    return null;
0163:                return file;
0164:            }
0165:
0166:            /**
0167:             * Convenience method for interpreting {@link #getMode}.
0168:             */
0169:            protected boolean isMetaDataMode() {
0170:                return (_mode & MODE_META) != 0;
0171:            }
0172:
0173:            /**
0174:             * Convenience method for interpreting {@link #getMode}.
0175:             */
0176:            protected boolean isQueryMode() {
0177:                return (_mode & MODE_QUERY) != 0;
0178:            }
0179:
0180:            /**
0181:             * Convenience method for interpreting {@link #getMode}.
0182:             */
0183:            protected boolean isMappingMode() {
0184:                return (_mode & MODE_MAPPING) != 0;
0185:            }
0186:
0187:            /**
0188:             * Convenience method for interpreting {@link #getMode}. Takes into
0189:             * account whether mapping information is loaded for the given instance.
0190:             */
0191:            protected boolean isMappingMode(ClassMetaData meta) {
0192:                return isMappingMode()
0193:                        && (meta.getSourceMode() & MODE_MAPPING) != 0
0194:                        && (meta.getEmbeddingMetaData() != null || !meta
0195:                                .isEmbeddedOnly())
0196:                        && (meta.getEmbeddingMetaData() == null || isMappingMode(meta
0197:                                .getEmbeddingMetaData()));
0198:            }
0199:
0200:            /**
0201:             * Convenience method for interpreting {@link #getMode}. Takes into
0202:             * account whether mapping information is loaded for the given instance.
0203:             */
0204:            protected boolean isMappingMode(ValueMetaData vmd) {
0205:                return isMappingMode(vmd.getFieldMetaData()
0206:                        .getDefiningMetaData());
0207:            }
0208:
0209:            /**
0210:             * Add a class meta data to the set to be serialized.
0211:             */
0212:            public void addMetaData(ClassMetaData meta) {
0213:                if (meta == null)
0214:                    return;
0215:
0216:                if (_metas == null)
0217:                    _metas = new HashMap<String, ClassMetaData>();
0218:                _metas.put(meta.getDescribedType().getName(), meta);
0219:            }
0220:
0221:            /**
0222:             * Add a sequence meta data to the set to be serialized.
0223:             */
0224:            public void addSequenceMetaData(SequenceMetaData meta) {
0225:                if (meta == null)
0226:                    return;
0227:
0228:                List seqs = null;
0229:                String defName = null;
0230:                if (meta.getSourceScope() instanceof  Class)
0231:                    defName = ((Class) meta.getSourceScope()).getName();
0232:                if (_seqs == null)
0233:                    _seqs = new HashMap<String, List>();
0234:                else
0235:                    seqs = _seqs.get(defName);
0236:
0237:                if (seqs == null) {
0238:                    seqs = new ArrayList(3); // don't expect many seqs / class
0239:                    seqs.add(meta);
0240:                    _seqs.put(defName, seqs);
0241:                } else if (!seqs.contains(meta))
0242:                    seqs.add(meta);
0243:            }
0244:
0245:            /**
0246:             * Add a query meta data to the set to be serialized.
0247:             */
0248:            public void addQueryMetaData(QueryMetaData meta) {
0249:                if (meta == null)
0250:                    return;
0251:
0252:                List queries = null;
0253:                String defName = null;
0254:                if (meta.getSourceScope() instanceof  Class)
0255:                    defName = ((Class) meta.getSourceScope()).getName();
0256:                if (_queries == null)
0257:                    _queries = new HashMap<String, List>();
0258:                else
0259:                    queries = _queries.get(defName);
0260:
0261:                if (queries == null) {
0262:                    queries = new ArrayList(3); // don't expect many queries / class
0263:                    queries.add(meta);
0264:                    _queries.put(defName, queries);
0265:                } else if (!queries.contains(meta))
0266:                    queries.add(meta);
0267:            }
0268:
0269:            /**
0270:             * Add all components in the given repository to the set to be serialized.
0271:             */
0272:            public void addAll(MetaDataRepository repos) {
0273:                if (repos == null)
0274:                    return;
0275:
0276:                for (ClassMetaData meta : repos.getMetaDatas())
0277:                    addMetaData(meta);
0278:                for (SequenceMetaData seq : repos.getSequenceMetaDatas())
0279:                    addSequenceMetaData(seq);
0280:                for (QueryMetaData query : repos.getQueryMetaDatas())
0281:                    addQueryMetaData(query);
0282:            }
0283:
0284:            /**
0285:             * Remove a metadata from the set to be serialized.
0286:             *
0287:             * @return true if removed, false if not in set
0288:             */
0289:            public boolean removeMetaData(ClassMetaData meta) {
0290:                return _metas != null
0291:                        && meta != null
0292:                        && _metas.remove(meta.getDescribedType().getName()) != null;
0293:            }
0294:
0295:            /**
0296:             * Remove a sequence metadata from the set to be serialized.
0297:             *
0298:             * @return true if removed, false if not in set
0299:             */
0300:            public boolean removeSequenceMetaData(SequenceMetaData meta) {
0301:                if (_seqs == null || meta == null)
0302:                    return false;
0303:                String defName = null;
0304:                if (meta.getSourceScope() instanceof  Class)
0305:                    defName = ((Class) meta.getSourceScope()).getName();
0306:                List seqs = _seqs.get(defName);
0307:                if (seqs == null)
0308:                    return false;
0309:                if (!seqs.remove(meta))
0310:                    return false;
0311:                if (seqs.isEmpty())
0312:                    _seqs.remove(defName);
0313:                return true;
0314:            }
0315:
0316:            /**
0317:             * Remove a query metadata from the set to be serialized.
0318:             *
0319:             * @return true if removed, false if not in set
0320:             */
0321:            public boolean removeQueryMetaData(QueryMetaData meta) {
0322:                if (_queries == null || meta == null)
0323:                    return false;
0324:                String defName = null;
0325:                if (meta.getSourceScope() instanceof  Class)
0326:                    defName = ((Class) meta.getSourceScope()).getName();
0327:                List queries = _queries.get(defName);
0328:                if (queries == null)
0329:                    return false;
0330:                if (!queries.remove(meta))
0331:                    return false;
0332:                if (queries.isEmpty())
0333:                    _queries.remove(defName);
0334:                return true;
0335:            }
0336:
0337:            /**
0338:             * Remove all the components in the given repository from the set to be
0339:             * serialized.
0340:             *
0341:             * @return true if any components removed, false if none in set
0342:             */
0343:            public boolean removeAll(MetaDataRepository repos) {
0344:                if (repos == null)
0345:                    return false;
0346:
0347:                boolean removed = false;
0348:                ClassMetaData[] metas = repos.getMetaDatas();
0349:                for (int i = 0; i < metas.length; i++)
0350:                    removed |= removeMetaData(metas[i]);
0351:                SequenceMetaData[] seqs = repos.getSequenceMetaDatas();
0352:                for (int i = 0; i < seqs.length; i++)
0353:                    removed |= removeSequenceMetaData(seqs[i]);
0354:                QueryMetaData[] queries = repos.getQueryMetaDatas();
0355:                for (int i = 0; i < queries.length; i++)
0356:                    removed |= removeQueryMetaData(queries[i]);
0357:                return removed;
0358:            }
0359:
0360:            /**
0361:             * Clear the set of metadatas to be serialized.
0362:             */
0363:            public void clear() {
0364:                if (_metas != null)
0365:                    _metas.clear();
0366:                if (_seqs != null)
0367:                    _seqs.clear();
0368:                if (_queries != null)
0369:                    _queries.clear();
0370:            }
0371:
0372:            @Override
0373:            protected Collection getObjects() {
0374:                List all = new ArrayList();
0375:                if (isQueryMode())
0376:                    addQueryMetaDatas(all);
0377:                if (isMappingMode())
0378:                    addSequenceMetaDatas(all);
0379:                if ((isMetaDataMode() || isMappingMode()) && _metas != null)
0380:                    all.addAll(_metas.values());
0381:                if (isMappingMode())
0382:                    addSystemMappingElements(all);
0383:                serializationSort(all);
0384:                return all;
0385:            }
0386:
0387:            /**
0388:             * Add system-level mapping elements to be serialized. Does nothing
0389:             * by default.
0390:             */
0391:            protected void addSystemMappingElements(Collection toSerialize) {
0392:            }
0393:
0394:            /**
0395:             * Sort the given collection of objects to be serialized.
0396:             */
0397:            private void serializationSort(List objs) {
0398:                if (objs == null || objs.isEmpty())
0399:                    return;
0400:                if (_comp == null)
0401:                    _comp = newSerializationComparator();
0402:                Collections.sort(objs, _comp);
0403:            }
0404:
0405:            /**
0406:             * Create a new comparator for ordering objects that are to be serialized.
0407:             */
0408:            protected SerializationComparator newSerializationComparator() {
0409:                return _comp;
0410:            }
0411:
0412:            /**
0413:             * Add sequence metadata to the given metadatas collection.
0414:             */
0415:            private void addSequenceMetaDatas(Collection all) {
0416:                if (_seqs == null)
0417:                    return;
0418:
0419:                for (Map.Entry entry : _seqs.entrySet()) {
0420:                    if (entry.getKey() == null)
0421:                        all.addAll((List) entry.getValue());
0422:                    else if (_metas == null
0423:                            || !_metas.containsKey(entry.getKey()))
0424:                        all.add(new ClassSeqs((List<SequenceMetaData>) entry
0425:                                .getValue()));
0426:                }
0427:            }
0428:
0429:            /**
0430:             * Add query metadata to the given metadatas collection.
0431:             */
0432:            private void addQueryMetaDatas(Collection all) {
0433:                if (_queries == null)
0434:                    return;
0435:
0436:                for (Map.Entry entry : _queries.entrySet()) {
0437:                    if (entry.getKey() == null)
0438:                        all.addAll((List) entry.getValue());
0439:                    else if (_mode == MODE_QUERY || _metas == null
0440:                            || !_metas.containsKey(entry.getKey()))
0441:                        all.add(new ClassQueries((List<QueryMetaData>) entry
0442:                                .getValue()));
0443:                }
0444:            }
0445:
0446:            @Override
0447:            protected void serialize(Collection objects) throws SAXException {
0448:                // copy collection to avoid mutation
0449:                Object meta;
0450:                boolean unique = true;
0451:                boolean fieldAccess = false;
0452:                boolean propertyAccess = false;
0453:                for (Iterator it = objects.iterator(); it.hasNext();) {
0454:                    meta = it.next();
0455:                    switch (type(meta)) {
0456:                    case TYPE_META:
0457:                        ClassMetaData cls = (ClassMetaData) meta;
0458:                        if (cls.getAccessType() == ClassMetaData.ACCESS_FIELD)
0459:                            fieldAccess = true;
0460:                        else
0461:                            propertyAccess = true;
0462:                        // no break
0463:                    default:
0464:                        if (unique && getPackage() == null)
0465:                            setPackage(getPackage(meta));
0466:                        else if (unique) {
0467:                            unique = getPackage().equals(getPackage(meta));
0468:                            if (!unique)
0469:                                setPackage(null);
0470:                        }
0471:                    }
0472:                }
0473:
0474:                serializeNamespaceAttributes();
0475:                startElement("entity-mappings");
0476:                if (getPackage() != null) {
0477:                    startElement("package");
0478:                    addText(getPackage());
0479:                    endElement("package");
0480:                }
0481:                if (fieldAccess != propertyAccess) // i.e. only one
0482:                {
0483:                    int def = getConfiguration()
0484:                            .getMetaDataRepositoryInstance()
0485:                            .getMetaDataFactory().getDefaults()
0486:                            .getDefaultAccessType();
0487:                    String access = null;
0488:                    if (fieldAccess && def == ClassMetaData.ACCESS_PROPERTY)
0489:                        access = "FIELD";
0490:                    else if (propertyAccess
0491:                            && def == ClassMetaData.ACCESS_FIELD)
0492:                        access = "PROPERTY";
0493:                    if (access != null) {
0494:                        startElement("access");
0495:                        addText(access);
0496:                        endElement("access");
0497:                    }
0498:                }
0499:                for (Object obj : objects) {
0500:                    int type = type(obj);
0501:                    switch (type) {
0502:                    case TYPE_META:
0503:                        serializeClass((ClassMetaData) obj, fieldAccess
0504:                                && propertyAccess);
0505:                        break;
0506:                    case TYPE_SEQ:
0507:                        if (isMappingMode())
0508:                            serializeSequence((SequenceMetaData) obj);
0509:                    case TYPE_QUERY:
0510:                        serializeQuery((QueryMetaData) obj);
0511:                        break;
0512:                    case TYPE_CLASS_QUERIES:
0513:                        for (QueryMetaData query : ((ClassQueries) obj)
0514:                                .getQueries())
0515:                            serializeQuery(query);
0516:                        break;
0517:                    case TYPE_CLASS_SEQS:
0518:                        if (isMappingMode())
0519:                            for (SequenceMetaData seq : ((ClassSeqs) obj)
0520:                                    .getSequences())
0521:                                serializeSequence(seq);
0522:                        break;
0523:                    default:
0524:                        if (isMappingMode())
0525:                            serializeSystemMappingElement(obj);
0526:                        break;
0527:                    }
0528:                }
0529:                endElement("entity-mappings");
0530:            }
0531:
0532:            @Override
0533:            protected String getPackage(Object obj) {
0534:                int type = type(obj);
0535:                switch (type) {
0536:                case TYPE_META:
0537:                    return Strings.getPackageName(((ClassMetaData) obj)
0538:                            .getDescribedType());
0539:                case TYPE_QUERY:
0540:                case TYPE_SEQ:
0541:                case TYPE_CLASS_QUERIES:
0542:                case TYPE_CLASS_SEQS:
0543:                    SourceTracker st = (SourceTracker) obj;
0544:                    if (st.getSourceScope() instanceof  Class)
0545:                        return Strings.getPackageName((Class) st
0546:                                .getSourceScope());
0547:                    return null;
0548:                default:
0549:                    return null;
0550:                }
0551:            }
0552:
0553:            /**
0554:             * Return the type constant for the given object based on its runtime
0555:             * class. If the runtime class does not correspond to any of the known
0556:             * types then returns -1. This can happen for tags
0557:             * that are not handled at this store-agnostic level.
0558:             */
0559:            protected int type(Object o) {
0560:                if (o instanceof  ClassMetaData)
0561:                    return TYPE_META;
0562:                if (o instanceof  QueryMetaData)
0563:                    return TYPE_QUERY;
0564:                if (o instanceof  SequenceMetaData)
0565:                    return TYPE_SEQ;
0566:                if (o instanceof  ClassQueries)
0567:                    return TYPE_CLASS_QUERIES;
0568:                if (o instanceof  ClassSeqs)
0569:                    return TYPE_CLASS_SEQS;
0570:                return -1;
0571:            }
0572:
0573:            /**
0574:             * Serialize namespace attributes
0575:             */
0576:            private void serializeNamespaceAttributes() throws SAXException {
0577:                addAttribute("xmlns",
0578:                        "http://java.sun.com/xml/ns/persistence/orm");
0579:                addAttribute("xmlns:xsi",
0580:                        "http://www.w3.org/2001/XMLSchema-instance");
0581:                addAttribute("xsi:schemaLocation",
0582:                        "http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd");
0583:                addAttribute("version", "1.0");
0584:            }
0585:
0586:            /**
0587:             * Serialize unknown mapping element at system level.
0588:             */
0589:            protected void serializeSystemMappingElement(Object obj)
0590:                    throws SAXException {
0591:            }
0592:
0593:            /**
0594:             * Serialize query metadata.
0595:             */
0596:            private void serializeQuery(QueryMetaData meta) throws SAXException {
0597:                if (!_annos && meta.getSourceType() == meta.SRC_ANNOTATIONS)
0598:                    return;
0599:
0600:                Log log = getLog();
0601:                if (log.isInfoEnabled()) {
0602:                    if (meta.getSourceScope() instanceof  Class)
0603:                        log.info(_loc.get("ser-cls-query", meta
0604:                                .getSourceScope(), meta.getName()));
0605:                    else
0606:                        log.info(_loc.get("ser-query", meta.getName()));
0607:                }
0608:
0609:                addComments(meta);
0610:                addAttribute("name", meta.getName());
0611:                addAttribute("query", meta.getQueryString());
0612:                if (QueryLanguages.LANG_SQL.equals(meta.getLanguage())) {
0613:                    if (meta.getResultType() != null)
0614:                        addAttribute("result-class", meta.getResultType()
0615:                                .getName());
0616:                    startElement("named-native-query");
0617:                    serializeQueryHints(meta);
0618:                    endElement("named-native-query");
0619:                } else {
0620:                    startElement("named-query");
0621:                    serializeQueryHints(meta);
0622:                    endElement("named-query");
0623:                }
0624:            }
0625:
0626:            /**
0627:             * Serialize query hints.
0628:             */
0629:            private void serializeQueryHints(QueryMetaData meta)
0630:                    throws SAXException {
0631:                String[] hints = meta.getHintKeys();
0632:                Object[] values = meta.getHintValues();
0633:                for (int i = 0; i < hints.length; i++) {
0634:                    addAttribute("name", hints[i]);
0635:                    addAttribute("value", String.valueOf(values[i]));
0636:                    startElement("query-hint");
0637:                    endElement("query-hint");
0638:                }
0639:            }
0640:
0641:            /**
0642:             * Serialize sequence metadata.
0643:             */
0644:            protected void serializeSequence(SequenceMetaData meta)
0645:                    throws SAXException {
0646:                if (!_annos && meta.getSourceType() == meta.SRC_ANNOTATIONS)
0647:                    return;
0648:
0649:                Log log = getLog();
0650:                if (log.isInfoEnabled())
0651:                    log.info(_loc.get("ser-sequence", meta.getName()));
0652:
0653:                addComments(meta);
0654:                addAttribute("name", meta.getName());
0655:
0656:                // parse out the datastore sequence name, if any
0657:                String plugin = meta.getSequencePlugin();
0658:                String clsName = Configurations.getClassName(plugin);
0659:                String props = Configurations.getProperties(plugin);
0660:                String ds = null;
0661:                if (props != null) {
0662:                    Properties map = Configurations.parseProperties(props);
0663:                    ds = (String) map.remove("Sequence");
0664:                    if (ds != null) {
0665:                        props = Configurations.serializeProperties(map);
0666:                        plugin = Configurations.getPlugin(clsName, props);
0667:                    }
0668:                }
0669:
0670:                if (ds != null)
0671:                    addAttribute("sequence-name", ds);
0672:                else if (plugin != null
0673:                        && !SequenceMetaData.IMPL_NATIVE.equals(plugin))
0674:                    addAttribute("sequence-name", plugin);
0675:                if (meta.getInitialValue() != 0 && meta.getInitialValue() != -1)
0676:                    addAttribute("initial-value", String.valueOf(meta
0677:                            .getInitialValue()));
0678:                if (meta.getAllocate() != 50 && meta.getAllocate() != -1)
0679:                    addAttribute("allocation-size", String.valueOf(meta
0680:                            .getAllocate()));
0681:
0682:                startElement("sequence-generator");
0683:                endElement("sequence-generator");
0684:            }
0685:
0686:            /**
0687:             * Serialize class metadata.
0688:             */
0689:            protected void serializeClass(ClassMetaData meta, boolean access)
0690:                    throws SAXException {
0691:                if (!_annos && meta.getSourceType() == meta.SRC_ANNOTATIONS)
0692:                    return;
0693:
0694:                Log log = getLog();
0695:                if (log.isInfoEnabled())
0696:                    log.info(_loc.get("ser-class", meta));
0697:
0698:                addComments(meta);
0699:                addAttribute("class", getClassName(meta.getDescribedType()
0700:                        .getName()));
0701:
0702:                if (isMetaDataMode()
0703:                        && !meta.getTypeAlias().equals(
0704:                                Strings.getClassName(meta.getDescribedType())))
0705:                    addAttribute("name", meta.getTypeAlias());
0706:
0707:                String name = getEntityElementName(meta);
0708:                if (isMetaDataMode())
0709:                    addClassAttributes(meta, access);
0710:                if (isMappingMode())
0711:                    addClassMappingAttributes(meta);
0712:
0713:                startElement(name);
0714:                if (isMappingMode())
0715:                    serializeClassMappingContent(meta);
0716:                if (isMetaDataMode())
0717:                    serializeIdClass(meta);
0718:                if (isMappingMode())
0719:                    serializeInheritanceContent(meta);
0720:
0721:                if (isMappingMode()) {
0722:                    List seqs = (_seqs == null) ? null : _seqs.get(meta
0723:                            .getDescribedType().getName());
0724:                    if (seqs != null) {
0725:                        serializationSort(seqs);
0726:                        for (int i = 0; i < seqs.size(); i++)
0727:                            serializeSequence((SequenceMetaData) seqs.get(i));
0728:                    }
0729:                }
0730:
0731:                if (isQueryMode()) {
0732:                    List queries = (_queries == null) ? null : _queries
0733:                            .get(meta.getDescribedType().getName());
0734:                    if (queries != null) {
0735:                        serializationSort(queries);
0736:                        for (int i = 0; i < queries.size(); i++)
0737:                            serializeQuery((QueryMetaData) queries.get(i));
0738:                    }
0739:                    if (isMappingMode())
0740:                        serializeQueryMappings(meta);
0741:                }
0742:
0743:                List<FieldMetaData> fields = new ArrayList(Arrays.asList(meta
0744:                        .getDefinedFieldsInListingOrder()));
0745:                Collections.sort(fields, new FieldComparator());
0746:
0747:                // serialize attr-override
0748:                if (isMappingMode()) {
0749:                    FieldMetaData fmd;
0750:                    FieldMetaData orig;
0751:                    for (Iterator<FieldMetaData> it = fields.iterator(); it
0752:                            .hasNext();) {
0753:                        fmd = it.next();
0754:                        if (meta.getDefinedSuperclassField(fmd.getName()) == null)
0755:                            continue;
0756:                        orig = meta.getPCSuperclassMetaData().getField(
0757:                                fmd.getName());
0758:                        if (serializeAttributeOverride(fmd, orig))
0759:                            serializeAttributeOverrideContent(fmd, orig);
0760:                        it.remove();
0761:                    }
0762:                }
0763:
0764:                if (fields.size() > 0 && (isMetaDataMode() || isMappingMode())) {
0765:                    startElement("attributes");
0766:                    FieldMetaData orig;
0767:                    for (FieldMetaData fmd : fields) {
0768:                        if (fmd.getDeclaringType() != fmd.getDefiningMetaData()
0769:                                .getDescribedType()) {
0770:                            orig = fmd.getDeclaringMetaData().getDeclaredField(
0771:                                    fmd.getName());
0772:                        } else
0773:                            orig = null;
0774:                        serializeField(fmd, orig);
0775:                    }
0776:                    endElement("attributes");
0777:                }
0778:                endElement(name);
0779:            }
0780:
0781:            /**
0782:             * Return the entity element name.
0783:             */
0784:            private static String getEntityElementName(ClassMetaData meta) {
0785:                switch (getEntityTag(meta)) {
0786:                case ENTITY:
0787:                    return "entity";
0788:                case EMBEDDABLE:
0789:                    return "embeddable";
0790:                case MAPPED_SUPERCLASS:
0791:                    return "mapped-superclass";
0792:                default:
0793:                    throw new IllegalStateException();
0794:                }
0795:            }
0796:
0797:            /**
0798:             * Return the MetaDataTag for the given class meta data.
0799:             */
0800:            private static MetaDataTag getEntityTag(ClassMetaData meta) {
0801:                // @Embeddable classes can't declare Id fields
0802:                if (meta.isEmbeddedOnly()
0803:                        && meta.getPrimaryKeyFields().length == 0)
0804:                    return MetaDataTag.EMBEDDABLE;
0805:                if (meta.isMapped())
0806:                    return MetaDataTag.ENTITY;
0807:                return MetaDataTag.MAPPED_SUPERCLASS;
0808:            }
0809:
0810:            /**
0811:             * Set class attributes.
0812:             *
0813:             * @param access whether to write access
0814:             */
0815:            private void addClassAttributes(ClassMetaData meta, boolean access) {
0816:                if (!access)
0817:                    return;
0818:                int def = getConfiguration().getMetaDataRepositoryInstance()
0819:                        .getMetaDataFactory().getDefaults()
0820:                        .getDefaultAccessType();
0821:                if (meta.getAccessType() == ClassMetaData.ACCESS_FIELD
0822:                        && def == ClassMetaData.ACCESS_PROPERTY)
0823:                    addAttribute("access", "FIELD");
0824:                else if (meta.getAccessType() == ClassMetaData.ACCESS_PROPERTY
0825:                        && def == ClassMetaData.ACCESS_FIELD)
0826:                    addAttribute("access", "PROPERTY");
0827:            }
0828:
0829:            /**
0830:             * Add mapping attributes for the given class. Does nothing by default
0831:             */
0832:            protected void addClassMappingAttributes(ClassMetaData mapping)
0833:                    throws SAXException {
0834:            }
0835:
0836:            /**
0837:             * Serialize id-class.
0838:             */
0839:            private void serializeIdClass(ClassMetaData meta)
0840:                    throws SAXException {
0841:                if (meta.getIdentityType() != ClassMetaData.ID_APPLICATION
0842:                        || meta.isOpenJPAIdentity())
0843:                    return;
0844:
0845:                ClassMetaData sup = meta.getPCSuperclassMetaData();
0846:                Class oid = meta.getObjectIdType();
0847:                if (oid != null
0848:                        && (sup == null || oid != sup.getObjectIdType())) {
0849:                    addAttribute("class", getClassName(oid.getName()));
0850:                    startElement("id-class");
0851:                    endElement("id-class");
0852:                }
0853:            }
0854:
0855:            /**
0856:             * Serialize class mapping content. Does nothing by default.
0857:             */
0858:            protected void serializeClassMappingContent(ClassMetaData mapping)
0859:                    throws SAXException {
0860:            }
0861:
0862:            /**
0863:             * Serialize inheritance content. Does nothing by default.
0864:             */
0865:            protected void serializeInheritanceContent(ClassMetaData mapping)
0866:                    throws SAXException {
0867:            }
0868:
0869:            /**
0870:             * Serialize query mappings. Does nothing by default.
0871:             */
0872:            protected void serializeQueryMappings(ClassMetaData meta)
0873:                    throws SAXException {
0874:            }
0875:
0876:            /**
0877:             * Serialize the given field.
0878:             */
0879:            private void serializeField(FieldMetaData fmd, FieldMetaData orig)
0880:                    throws SAXException {
0881:                if (fmd.getManagement() != FieldMetaData.MANAGE_PERSISTENT
0882:                        && !fmd.isExplicit())
0883:                    return;
0884:
0885:                addComments(fmd);
0886:                addAttribute("name", fmd.getName());
0887:
0888:                String strategy = null;
0889:                PersistenceStrategy strat = getStrategy(fmd);
0890:                ValueMetaData cascades = null;
0891:                if (fmd.isPrimaryKey() && strat == PersistenceStrategy.EMBEDDED)
0892:                    strategy = "embedded-id";
0893:                else if (fmd.isPrimaryKey())
0894:                    strategy = "id";
0895:                else if (fmd.isVersion())
0896:                    strategy = "version";
0897:                else {
0898:                    switch (strat) {
0899:                    case TRANSIENT:
0900:                        strategy = "transient";
0901:                        break;
0902:                    case BASIC:
0903:                        if (isMetaDataMode())
0904:                            addBasicAttributes(fmd);
0905:                        strategy = "basic";
0906:                        break;
0907:                    case EMBEDDED:
0908:                        strategy = "embedded";
0909:                        break;
0910:                    case MANY_ONE:
0911:                        if (isMetaDataMode())
0912:                            addManyToOneAttributes(fmd);
0913:                        strategy = "many-to-one";
0914:                        cascades = fmd;
0915:                        break;
0916:                    case ONE_ONE:
0917:                        if (isMetaDataMode())
0918:                            addOneToOneAttributes(fmd);
0919:                        strategy = "one-to-one";
0920:                        cascades = fmd;
0921:                        break;
0922:                    case ONE_MANY:
0923:                        if (isMetaDataMode())
0924:                            addOneToManyAttributes(fmd);
0925:                        strategy = "one-to-many";
0926:                        cascades = fmd.getElement();
0927:                        break;
0928:                    case MANY_MANY:
0929:                        if (isMetaDataMode())
0930:                            addManyToManyAttributes(fmd);
0931:                        strategy = "many-to-many";
0932:                        cascades = fmd.getElement();
0933:                        break;
0934:                    }
0935:                    if (isMappingMode())
0936:                        addStrategyMappingAttributes(fmd);
0937:                }
0938:                if (isMappingMode(fmd))
0939:                    addFieldMappingAttributes(fmd, orig);
0940:
0941:                startElement(strategy);
0942:                if (fmd.getOrderDeclaration() != null) {
0943:                    startElement("order-by");
0944:                    if (!(Order.ELEMENT + " asc").equals(fmd
0945:                            .getOrderDeclaration()))
0946:                        addText(fmd.getOrderDeclaration());
0947:                    endElement("order-by");
0948:                }
0949:                if (isMappingMode() && fmd.getKey().getValueMappedBy() != null) {
0950:                    FieldMetaData mapBy = fmd.getKey()
0951:                            .getValueMappedByMetaData();
0952:                    if (!mapBy.isPrimaryKey()
0953:                            || mapBy.getDefiningMetaData()
0954:                                    .getPrimaryKeyFields().length != 1) {
0955:                        addAttribute("name", fmd.getKey().getValueMappedBy());
0956:                    }
0957:                    startElement("map-key");
0958:                    endElement("map-key");
0959:                }
0960:                if (isMappingMode(fmd))
0961:                    serializeFieldMappingContent(fmd, strat);
0962:                if (cascades != null && isMetaDataMode())
0963:                    serializeCascades(cascades);
0964:                if (isMappingMode() && strat == PersistenceStrategy.EMBEDDED) {
0965:                    ClassMetaData meta = fmd.getEmbeddedMetaData();
0966:                    ClassMetaData owner = getConfiguration()
0967:                            .getMetaDataRepositoryInstance().getMetaData(
0968:                                    meta.getDescribedType(),
0969:                                    meta.getEnvClassLoader(), true);
0970:                    FieldMetaData eorig;
0971:                    for (FieldMetaData efmd : meta.getFields()) {
0972:                        eorig = owner.getField(efmd.getName());
0973:                        if (serializeAttributeOverride(efmd, eorig))
0974:                            serializeAttributeOverrideContent(efmd, eorig);
0975:                    }
0976:                }
0977:                endElement(strategy);
0978:            }
0979:
0980:            /**
0981:             * Add mapping attributes for the given field. Does nothing by default.
0982:             */
0983:            protected void addFieldMappingAttributes(FieldMetaData fmd,
0984:                    FieldMetaData orig) throws SAXException {
0985:            }
0986:
0987:            /**
0988:             * Always returns false by default.
0989:             */
0990:            protected boolean serializeAttributeOverride(FieldMetaData fmd,
0991:                    FieldMetaData orig) {
0992:                return false;
0993:            }
0994:
0995:            /**
0996:             * Serialize attribute override content.
0997:             */
0998:            private void serializeAttributeOverrideContent(FieldMetaData fmd,
0999:                    FieldMetaData orig) throws SAXException {
1000:                addAttribute("name", fmd.getName());
1001:                startElement("attribute-override");
1002:                serializeAttributeOverrideMappingContent(fmd, orig);
1003:                endElement("attribute-override");
1004:            }
1005:
1006:            /**
1007:             * Serialize attribute override mapping content. Does nothing by default,
1008:             */
1009:            protected void serializeAttributeOverrideMappingContent(
1010:                    FieldMetaData fmd, FieldMetaData orig) throws SAXException {
1011:            }
1012:
1013:            /**
1014:             * Serialize cascades.
1015:             */
1016:            private void serializeCascades(ValueMetaData vmd)
1017:                    throws SAXException {
1018:                Collection<String> cascades = null;
1019:                if (vmd.getCascadePersist() == ValueMetaData.CASCADE_IMMEDIATE) {
1020:                    if (cascades == null)
1021:                        cascades = new ArrayList<String>();
1022:                    cascades.add("cascade-persist");
1023:                }
1024:                if (vmd.getCascadeAttach() == ValueMetaData.CASCADE_IMMEDIATE) {
1025:                    if (cascades == null)
1026:                        cascades = new ArrayList<String>();
1027:                    cascades.add("cascade-merge");
1028:                }
1029:                if (vmd.getCascadeDelete() == ValueMetaData.CASCADE_IMMEDIATE) {
1030:                    if (cascades == null)
1031:                        cascades = new ArrayList<String>();
1032:                    cascades.add("cascade-remove");
1033:                }
1034:                if (vmd.getCascadeRefresh() == ValueMetaData.CASCADE_IMMEDIATE) {
1035:                    if (cascades == null)
1036:                        cascades = new ArrayList<String>();
1037:                    cascades.add("cascade-refresh");
1038:                }
1039:                if (cascades != null && cascades.size() == 4) // ALL
1040:                {
1041:                    cascades.clear();
1042:                    cascades.add("cascade-all");
1043:                }
1044:                if (cascades != null) {
1045:                    startElement("cascade");
1046:                    for (String cascade : cascades) {
1047:                        startElement(cascade);
1048:                        endElement(cascade);
1049:                    }
1050:                    endElement("cascade");
1051:                }
1052:            }
1053:
1054:            /**
1055:             * Return the serialized strategy name.
1056:             */
1057:            protected PersistenceStrategy getStrategy(FieldMetaData fmd) {
1058:                if (fmd.getManagement() == fmd.MANAGE_NONE)
1059:                    return PersistenceStrategy.TRANSIENT;
1060:
1061:                if (fmd.isSerialized() || fmd.getDeclaredType() == byte[].class
1062:                        || fmd.getDeclaredType() == Byte[].class
1063:                        || fmd.getDeclaredType() == char[].class
1064:                        || fmd.getDeclaredType() == Character[].class)
1065:                    return PersistenceStrategy.BASIC;
1066:
1067:                FieldMetaData mappedBy;
1068:                switch (fmd.getDeclaredTypeCode()) {
1069:                case JavaTypes.PC:
1070:                    if (fmd.isEmbedded())
1071:                        return PersistenceStrategy.EMBEDDED;
1072:                    if (fmd.getMappedBy() != null)
1073:                        return PersistenceStrategy.ONE_ONE;
1074:                    FieldMetaData[] inverses = fmd.getInverseMetaDatas();
1075:                    if (inverses.length == 1
1076:                            && inverses[0].getTypeCode() == JavaTypes.PC
1077:                            && inverses[0].getMappedByMetaData() == fmd) {
1078:                        return PersistenceStrategy.ONE_ONE;
1079:                    }
1080:                    return PersistenceStrategy.MANY_ONE;
1081:                case JavaTypes.ARRAY:
1082:                case JavaTypes.COLLECTION:
1083:                case JavaTypes.MAP:
1084:                    mappedBy = fmd.getMappedByMetaData();
1085:                    if (mappedBy == null
1086:                            || mappedBy.getTypeCode() != JavaTypes.PC)
1087:                        return PersistenceStrategy.MANY_MANY;
1088:                    return PersistenceStrategy.ONE_MANY;
1089:                case JavaTypes.OID:
1090:                    return PersistenceStrategy.EMBEDDED;
1091:                default:
1092:                    return PersistenceStrategy.BASIC;
1093:                }
1094:            }
1095:
1096:            /**
1097:             * Add basic attributes.
1098:             */
1099:            private void addBasicAttributes(FieldMetaData fmd)
1100:                    throws SAXException {
1101:                if (!fmd.isInDefaultFetchGroup())
1102:                    addAttribute("fetch", "LAZY");
1103:                if (fmd.getNullValue() == FieldMetaData.NULL_EXCEPTION)
1104:                    addAttribute("optional", "false");
1105:            }
1106:
1107:            /**
1108:             * Add many-to-one attributes.
1109:             */
1110:            private void addManyToOneAttributes(FieldMetaData fmd)
1111:                    throws SAXException {
1112:                if (!fmd.isInDefaultFetchGroup())
1113:                    addAttribute("fetch", "LAZY");
1114:                if (fmd.getNullValue() == FieldMetaData.NULL_EXCEPTION)
1115:                    addAttribute("optional", "false");
1116:            }
1117:
1118:            /**
1119:             * Add one-to-one attributes.
1120:             */
1121:            private void addOneToOneAttributes(FieldMetaData fmd)
1122:                    throws SAXException {
1123:                if (!fmd.isInDefaultFetchGroup())
1124:                    addAttribute("fetch", "LAZY");
1125:                if (fmd.getNullValue() == FieldMetaData.NULL_EXCEPTION)
1126:                    addAttribute("optional", "false");
1127:            }
1128:
1129:            /**
1130:             * Add one-to-many attributes.
1131:             */
1132:            private void addOneToManyAttributes(FieldMetaData fmd)
1133:                    throws SAXException {
1134:                if (fmd.isInDefaultFetchGroup())
1135:                    addAttribute("fetch", "EAGER");
1136:                addTargetEntityAttribute(fmd);
1137:            }
1138:
1139:            /**
1140:             * Add many-to-many attributes.
1141:             */
1142:            private void addManyToManyAttributes(FieldMetaData fmd)
1143:                    throws SAXException {
1144:                if (fmd.isInDefaultFetchGroup())
1145:                    addAttribute("fetch", "EAGER");
1146:                addTargetEntityAttribute(fmd);
1147:            }
1148:
1149:            /**
1150:             * Add a target-entity attribute to collection and map fields that do
1151:             * not use generics.
1152:             */
1153:            private void addTargetEntityAttribute(FieldMetaData fmd)
1154:                    throws SAXException {
1155:                Member member = fmd.getBackingMember();
1156:                Class[] types;
1157:                if (member instanceof  Field)
1158:                    types = JavaVersions.getParameterizedTypes((Field) member);
1159:                else if (member instanceof  Method)
1160:                    types = JavaVersions.getParameterizedTypes((Method) member);
1161:                else
1162:                    types = new Class[0];
1163:
1164:                switch (fmd.getDeclaredTypeCode()) {
1165:                case JavaTypes.COLLECTION:
1166:                    if (types.length != 1)
1167:                        addAttribute("target-entity", fmd.getElement()
1168:                                .getDeclaredType().getName());
1169:                    break;
1170:                case JavaTypes.MAP:
1171:                    if (types.length != 2)
1172:                        addAttribute("target-entity", fmd.getElement()
1173:                                .getDeclaredType().getName());
1174:                    break;
1175:                }
1176:            }
1177:
1178:            /**
1179:             * Serialize field mapping content; this will be called before
1180:             * {@link #serializeValueMappingContent}. Does nothing by default.
1181:             */
1182:            protected void serializeFieldMappingContent(FieldMetaData fmd,
1183:                    PersistenceStrategy strategy) throws SAXException {
1184:            }
1185:
1186:            /**
1187:             * Set mapping attributes for strategy. Sets mapped-by by default.
1188:             */
1189:            protected void addStrategyMappingAttributes(FieldMetaData fmd)
1190:                    throws SAXException {
1191:                if (fmd.getMappedBy() != null)
1192:                    addAttribute("mapped-by", fmd.getMappedBy());
1193:            }
1194:
1195:            /**
1196:             * Represents ordered set of {@link SequenceMetaData}s with a
1197:             * common class scope.
1198:             *
1199:             * @author Stephen Kim
1200:             * @author Pinaki Poddar
1201:             */
1202:            private static class ClassSeqs implements  SourceTracker,
1203:                    Comparable<ClassSeqs>, Comparator<SequenceMetaData> {
1204:
1205:                private final SequenceMetaData[] _seqs;
1206:
1207:                public ClassSeqs(List<SequenceMetaData> seqs) {
1208:                    if (seqs == null || seqs.isEmpty())
1209:                        throw new InternalException();
1210:
1211:                    _seqs = (SequenceMetaData[]) seqs
1212:                            .toArray(new SequenceMetaData[seqs.size()]);
1213:                    Arrays.sort(_seqs, this );
1214:                }
1215:
1216:                public SequenceMetaData[] getSequences() {
1217:                    return _seqs;
1218:                }
1219:
1220:                /**
1221:                 * Compare sequence metadata on name.
1222:                 */
1223:                public int compare(SequenceMetaData o1, SequenceMetaData o2) {
1224:                    return o1.getName().compareTo(o2.getName());
1225:                }
1226:
1227:                public File getSourceFile() {
1228:                    return _seqs[0].getSourceFile();
1229:                }
1230:
1231:                public Object getSourceScope() {
1232:                    return _seqs[0].getSourceScope();
1233:                }
1234:
1235:                public int getSourceType() {
1236:                    return _seqs[0].getSourceType();
1237:                }
1238:
1239:                public String getResourceName() {
1240:                    return _seqs[0].getResourceName();
1241:                }
1242:
1243:                public int compareTo(ClassSeqs other) {
1244:                    if (other == this )
1245:                        return 0;
1246:                    if (other == null)
1247:                        return -1;
1248:                    Class scope = (Class) getSourceScope();
1249:                    Class oscope = (Class) other.getSourceScope();
1250:                    return scope.getName().compareTo(oscope.getName());
1251:                }
1252:            }
1253:
1254:            /**
1255:             * Represents ordered set of {@link QueryMetaData}s with a
1256:             * common class scope.
1257:             *
1258:             * @author Stephen Kim
1259:             * @author Pinaki Poddar
1260:             */
1261:            private static class ClassQueries implements  SourceTracker,
1262:                    Comparable<ClassQueries>, Comparator<QueryMetaData> {
1263:
1264:                private final QueryMetaData[] _queries;
1265:
1266:                public ClassQueries(List<QueryMetaData> queries) {
1267:                    if (queries == null || queries.isEmpty())
1268:                        throw new InternalException();
1269:
1270:                    _queries = (QueryMetaData[]) queries
1271:                            .toArray(new QueryMetaData[queries.size()]);
1272:                    Arrays.sort(_queries, this );
1273:                }
1274:
1275:                public QueryMetaData[] getQueries() {
1276:                    return _queries;
1277:                }
1278:
1279:                /**
1280:                 * Compare query metadata. Normal queries appear before native queries.
1281:                 * If the given queries use same language, then their names are
1282:                 * compared.
1283:                 */
1284:                public int compare(QueryMetaData o1, QueryMetaData o2) {
1285:                    // normal queries before native
1286:                    if (!StringUtils.equals(o1.getLanguage(), o2.getLanguage())) {
1287:                        if (QueryLanguages.LANG_SQL.equals(o1.getLanguage()))
1288:                            return 1;
1289:                        else
1290:                            return -1;
1291:                    }
1292:                    return o1.getName().compareTo(o2.getName());
1293:                }
1294:
1295:                public File getSourceFile() {
1296:                    return _queries[0].getSourceFile();
1297:                }
1298:
1299:                public Object getSourceScope() {
1300:                    return _queries[0].getSourceScope();
1301:                }
1302:
1303:                public int getSourceType() {
1304:                    return _queries[0].getSourceType();
1305:                }
1306:
1307:                public String getResourceName() {
1308:                    return _queries[0].getResourceName();
1309:                }
1310:
1311:                public int compareTo(ClassQueries other) {
1312:                    if (other == this )
1313:                        return 0;
1314:                    if (other == null)
1315:                        return -1;
1316:                    Class scope = (Class) getSourceScope();
1317:                    Class oscope = (Class) other.getSourceScope();
1318:                    return scope.getName().compareTo(oscope.getName());
1319:                }
1320:            }
1321:
1322:            /**
1323:             * Compares clases, sequences, and queries to order them for serialization.
1324:             * Places sequences first, then classes, then queries. Sequences and
1325:             * queries are ordered alphabetically by name. Classes are placed in
1326:             * listing order, in inheritance order within that, and in alphabetical
1327:             * order within that.
1328:             *
1329:             * @author Stephen Kim
1330:             */
1331:            protected class SerializationComparator extends
1332:                    MetaDataInheritanceComparator {
1333:
1334:                public int compare(Object o1, Object o2) {
1335:                    if (o1 == o2)
1336:                        return 0;
1337:                    if (o1 == null)
1338:                        return 1;
1339:                    if (o2 == null)
1340:                        return -1;
1341:
1342:                    int t1 = type(o1);
1343:                    int t2 = type(o2);
1344:                    if (t1 != t2)
1345:                        return t1 - t2;
1346:
1347:                    switch (t1) {
1348:                    case TYPE_META:
1349:                        return compare((ClassMetaData) o1, (ClassMetaData) o2);
1350:                    case TYPE_QUERY:
1351:                        return compare((QueryMetaData) o1, (QueryMetaData) o2);
1352:                    case TYPE_SEQ:
1353:                        return compare((SequenceMetaData) o1,
1354:                                (SequenceMetaData) o2);
1355:                    case TYPE_CLASS_QUERIES:
1356:                        return ((Comparable) o1).compareTo(o2);
1357:                    case TYPE_CLASS_SEQS:
1358:                        return ((Comparable) o1).compareTo(o2);
1359:                    default:
1360:                        return compareUnknown(o1, o2);
1361:                    }
1362:                }
1363:
1364:                /**
1365:                 * Compare two unrecognized elements of the same type. Throws
1366:                 * exception by default.
1367:                 */
1368:                protected int compareUnknown(Object o1, Object o2) {
1369:                    throw new InternalException();
1370:                }
1371:
1372:                /**
1373:                 * Compare between two class metadata.
1374:                 */
1375:                private int compare(ClassMetaData o1, ClassMetaData o2) {
1376:                    int li1 = o1.getListingIndex();
1377:                    int li2 = o2.getListingIndex();
1378:                    if (li1 == -1 && li2 == -1) {
1379:                        MetaDataTag t1 = getEntityTag(o1);
1380:                        MetaDataTag t2 = getEntityTag(o2);
1381:                        if (t1.compareTo(t2) != 0)
1382:                            return t1.compareTo(t2);
1383:                        int inher = super .compare(o1, o2);
1384:                        if (inher != 0)
1385:                            return inher;
1386:                        return o1.getDescribedType().getName().compareTo(
1387:                                o2.getDescribedType().getName());
1388:                    }
1389:
1390:                    if (li1 == -1)
1391:                        return 1;
1392:                    if (li2 == -1)
1393:                        return -1;
1394:                    return li1 - li2;
1395:                }
1396:
1397:                /**
1398:                 * Compare query metadata.
1399:                 */
1400:                private int compare(QueryMetaData o1, QueryMetaData o2) {
1401:                    // normal queries before native
1402:                    if (!StringUtils.equals(o1.getLanguage(), o2.getLanguage())) {
1403:                        if (QueryLanguages.LANG_SQL.equals(o1.getLanguage()))
1404:                            return 1;
1405:                        else
1406:                            return -1;
1407:                    }
1408:                    return o1.getName().compareTo(o2.getName());
1409:                }
1410:
1411:                /**
1412:                 * Compare sequence metadata.
1413:                 */
1414:                private int compare(SequenceMetaData o1, SequenceMetaData o2) {
1415:                    return o1.getName().compareTo(o2.getName());
1416:                }
1417:            }
1418:
1419:            /**
1420:             * Sorts fields according to listing order, then XSD strategy order,
1421:             * then name order.
1422:             */
1423:            private class FieldComparator implements  Comparator {
1424:
1425:                public int compare(Object o1, Object o2) {
1426:                    FieldMetaData fmd1 = (FieldMetaData) o1;
1427:                    FieldMetaData fmd2 = (FieldMetaData) o2;
1428:                    if (fmd1.isPrimaryKey()) {
1429:                        if (fmd2.isPrimaryKey())
1430:                            return fmd1.compareTo(fmd2);
1431:                        return -1;
1432:                    }
1433:                    if (fmd2.isPrimaryKey())
1434:                        return 1;
1435:
1436:                    if (fmd1.isVersion()) {
1437:                        if (fmd2.isVersion())
1438:                            return compareListingOrder(fmd1, fmd2);
1439:                        return getStrategy(fmd2) == PersistenceStrategy.BASIC ? 1
1440:                                : -1;
1441:                    }
1442:                    if (fmd2.isVersion())
1443:                        return getStrategy(fmd1) == PersistenceStrategy.BASIC ? -1
1444:                                : 1;
1445:
1446:                    int stcmp = getStrategy(fmd1).compareTo(getStrategy(fmd2));
1447:                    if (stcmp != 0)
1448:                        return stcmp;
1449:                    return compareListingOrder(fmd1, fmd2);
1450:                }
1451:
1452:                private int compareListingOrder(FieldMetaData fmd1,
1453:                        FieldMetaData fmd2) {
1454:                    int lcmp = fmd1.getListingIndex() - fmd2.getListingIndex();
1455:                    if (lcmp != 0)
1456:                        return lcmp;
1457:                    return fmd1.compareTo(fmd2);
1458:                }
1459:            }
1460:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.