Modified: openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=1207320&r1=1207319&r2=1207320&view=diff ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java (original) +++ openjpa/trunk/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Mon Nov 28 15:44:58 2011 @@ -20,6 +20,7 @@ package org.apache.openjpa.persistence; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; @@ -28,15 +29,14 @@ import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.Stack; import javax.persistence.CascadeType; -import javax.persistence.Entity; import javax.persistence.GenerationType; import javax.persistence.LockModeType; -import javax.persistence.NamedQuery; import static javax.persistence.CascadeType.*; @@ -63,16 +63,21 @@ import org.apache.openjpa.meta.JavaTypes import org.apache.openjpa.meta.LifecycleMetaData; import org.apache.openjpa.meta.MetaDataContext; import org.apache.openjpa.meta.MetaDataFactory; +import org.apache.openjpa.meta.UpdateStrategies; + import static org.apache.openjpa.meta.MetaDataModes.*; import org.apache.openjpa.meta.MetaDataRepository; import org.apache.openjpa.meta.Order; import org.apache.openjpa.meta.QueryMetaData; import org.apache.openjpa.meta.SequenceMetaData; import org.apache.openjpa.meta.ValueMetaData; +import org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.FetchAttributeImpl; +import org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.FetchGroupImpl; import static org.apache.openjpa.persistence.MetaDataTag.*; import static org.apache.openjpa.persistence.PersistenceStrategy.*; import org.apache.openjpa.util.ImplHelper; +import org.apache.openjpa.util.InternalException; import org.apache.openjpa.util.MetaDataException; import org.xml.sax.Attributes; import org.xml.sax.Locator; @@ -125,6 +130,13 @@ public class XMLPersistenceMetaDataParse _embeddables = new HashMap<Class<?>, ArrayList<MetaDataContext>>(); private static final Map<Class<?>, Integer> _embeddableAccess = new HashMap<Class<?>, Integer>(); + + // Hold fetch group info + private FetchGroupImpl[] _fgs = null; + private List<FetchGroupImpl> _fgList = null; + private List<String> _referencedFgList = null; + private FetchGroupImpl _currentFg = null; + private List<FetchAttributeImpl> _fetchAttrList = null; static { _elems.put(ELEM_PKG, ELEM_PKG); @@ -173,6 +185,8 @@ public class XMLPersistenceMetaDataParse _elems.put("order-by", ORDER_BY); _elems.put("order-column", ORDER_COLUMN); _elems.put("lob", LOB); + _elems.put("data-store-id", DATASTORE_ID); + _elems.put("data-cache", DATA_CACHE); _elems.put("basic", BASIC); _elems.put("many-to-one", MANY_ONE); @@ -182,8 +196,24 @@ public class XMLPersistenceMetaDataParse _elems.put("many-to-many", MANY_MANY); _elems.put("transient", TRANSIENT); _elems.put("element-collection", ELEM_COLL); + _elems.put("persistent", PERS); + _elems.put("persistent-collection", PERS_COLL); + _elems.put("persistent-map", PERS_MAP); _elems.put("map-key-class", MAP_KEY_CLASS); - } + + _elems.put("read-only", READ_ONLY); + _elems.put("external-values", EXTERNAL_VALS); + _elems.put("external-value", EXTERNAL_VAL); + _elems.put("externalizer", EXTERNALIZER); + _elems.put("factory", FACTORY); + + _elems.put("fetch-groups", FETCH_GROUPS); + _elems.put("fetch-group", FETCH_GROUP); + _elems.put("fetch-attribute", FETCH_ATTRIBUTE); + _elems.put("referenced-fetch-group", REFERENCED_FETCH_GROUP); + + _elems.put("openjpa-version", OPENJPA_VERSION); +} private static final Localizer _loc = Localizer.forPackage (XMLPersistenceMetaDataParser.class); @@ -197,8 +227,10 @@ public class XMLPersistenceMetaDataParse private final Stack<Object> _elements = new Stack<Object>(); private final Stack<Object> _parents = new Stack<Object>(); + + private StringBuffer _externalValues = null; - private Class<?> _cls = null; + protected Class<?> _cls = null; // List of classes currently being parsed private ArrayList<Class<?>> _parseList = new ArrayList<Class<?>>(); private int _fieldPos = 0; @@ -481,6 +513,7 @@ public class XMLPersistenceMetaDataParse // use the latest schema by default. 'unknown' docs should parse // with the latest schema. String ormxsd = "orm_2_0-xsd.rsrc"; + boolean useExtendedSchema = true; // if the version and/or schema location is for 1.0, use the 1.0 // schema if (_ormVersion != null && @@ -488,8 +521,36 @@ public class XMLPersistenceMetaDataParse (_schemaLocation != null && _schemaLocation.indexOf(ORM_XSD_1_0) != -1)) { ormxsd = "orm-xsd.rsrc"; + useExtendedSchema = false; + } + InputStream ormxsdIS = XMLPersistenceMetaDataParser.class.getResourceAsStream(ormxsd); + + ArrayList<InputStream> schema = new ArrayList<InputStream>(); + schema.add(ormxsdIS); + + if (useExtendedSchema) { + // Get the extendable schema + InputStream extendableXSDIS = + XMLPersistenceMetaDataParser.class.getResourceAsStream("extendable-orm.xsd"); + if (extendableXSDIS != null) { + schema.add(extendableXSDIS); + } + else { + // TODO: log/trace + } + + // Get the openjpa extended schema + InputStream openjpaXSDIS = + XMLPersistenceMetaDataParser.class.getResourceAsStream("openjpa-orm.xsd"); + if (openjpaXSDIS != null) { + schema.add(openjpaXSDIS); + } + else { + // TODO: log/trace + } } - return XMLPersistenceMetaDataParser.class.getResourceAsStream(ormxsd); + + return schema.toArray(); } @Override @@ -728,12 +789,59 @@ public class XMLPersistenceMetaDataParse case POST_LOAD: ret = startCallback((MetaDataTag) tag, attrs); break; + case DATASTORE_ID: + ret = startDatastoreId(attrs); + break; + case DATA_CACHE: + ret = startDataCache(attrs); + break; + case READ_ONLY: + ret = startReadOnly(attrs); + break; + case EXTERNAL_VALS: + ret = startExternalValues(attrs); + break; + case EXTERNAL_VAL: + ret = startExternalValue(attrs); + break; + case EXTERNALIZER: + ret = startExternalizer(attrs); + break; + case FACTORY: + ret = startFactory(attrs); + break; + case FETCH_GROUPS: + ret = startFetchGroups(attrs); + break; + case FETCH_GROUP: + ret = startFetchGroup(attrs); + break; + case FETCH_ATTRIBUTE: + ret = startFetchAttribute(attrs); + break; + case REFERENCED_FETCH_GROUP: + ret = startReferencedFetchGroup(attrs); + break; + case OPENJPA_VERSION: + ret = true; + // TODO: right now the schema enforces this value, but may need to change in the future + break; default: warnUnsupportedTag(name); } } else if (tag instanceof PersistenceStrategy) { PersistenceStrategy ps = (PersistenceStrategy) tag; - ret = startStrategy(ps, attrs); + if (_openjpaNamespace > 0) { + if (ps == PERS + || ps == PERS_COLL + || ps == PERS_MAP) + ret = startStrategy(ps, attrs); + else + ret = startExtendedStrategy(ps, attrs); + } + else { + ret = startStrategy(ps, attrs); + } if (ret) _strategy = ps; } else if (tag == ELEM_LISTENER) @@ -796,9 +904,31 @@ public class XMLPersistenceMetaDataParse case ORDER_BY: endOrderBy(); break; + case EXTERNAL_VALS: + endExternalValues(); + break; + case EXTERNALIZER: + endExternalizer(); + break; + case FACTORY: + endFactory(); + break; + case FETCH_GROUP: + endFetchGroup(); + break; + case REFERENCED_FETCH_GROUP: + endReferencedFetchGroup(); + break; + } + } else if (tag instanceof PersistenceStrategy) { + PersistenceStrategy ps = (PersistenceStrategy) tag; + if (_openjpaNamespace > 0) { + endExtendedStrategy(ps); + } + else { + endStrategy(ps); } - } else if (tag instanceof PersistenceStrategy) - endStrategy((PersistenceStrategy) tag); + } else if (tag == ELEM_ACCESS) endAccess(); else if (tag == ELEM_LISTENER) @@ -970,13 +1100,14 @@ public class XMLPersistenceMetaDataParse if (_mode != MODE_QUERY) { ClassMetaData meta = (ClassMetaData) popElement(); storeCallbacks(meta); + if (isMappingOverrideMode()) endClassMapping(meta); } _cls = null; super.endClass(elem); } - + /** * Implement to add mapping attributes to class. */ @@ -1440,6 +1571,16 @@ public class XMLPersistenceMetaDataParse break; case ELEM_COLL: parseElementCollection(fmd, attrs); + break; + case PERS: + parsePersistent(fmd, attrs); + break; + case PERS_COLL: + parsePersistentCollection(fmd, attrs); + break; + case PERS_MAP: + parsePersistentMap(fmd, attrs); + break; } } @@ -2247,4 +2388,529 @@ public class XMLPersistenceMetaDataParse } return lineNum; } + + private boolean startDatastoreId(Attributes attrs) + throws SAXException { + MetaDataRepository repos = getRepository(); + ClassMetaData meta = repos.getCachedMetaData(_cls); + + //Set default value if not specified + String strategy = attrs.getValue("strategy"); + if (StringUtils.isEmpty(strategy)) { + strategy ="AUTO" ; + } + GenerationType stratType = GenerationType.valueOf(strategy); + + AnnotationPersistenceMetaDataParser.parseDataStoreId(meta, stratType, + attrs.getValue("generator")); + + return true; + } + + private boolean startDataCache(Attributes attrs) + throws SAXException { + String enabledStr = attrs.getValue("enabled"); + boolean enabled = (Boolean) (StringUtils.isEmpty(enabledStr) ? true : + Boolean.parseBoolean(enabledStr)); + + String timeoutStr = attrs.getValue("timeout"); + int timeout = (Integer) (StringUtils.isEmpty(timeoutStr) ? Integer.MIN_VALUE : + Integer.parseInt(timeoutStr)); + + String name = attrs.getValue("name"); + name = StringUtils.isEmpty(name) ? "" : name; + + AnnotationPersistenceMetaDataParser.parseDataCache(getRepository().getCachedMetaData(_cls), + enabled, name, timeout); + + return true; + } + + private boolean startExtendedStrategy(PersistenceStrategy ps, Attributes attrs) + throws SAXException { + + FieldMetaData fmd = (FieldMetaData) currentElement(); + parseExtendedStrategy(fmd, ps, attrs); + + return true; + } + + private void endExtendedStrategy(PersistenceStrategy ps) + throws SAXException { + if (ps == PERS + || ps == PERS_COLL + || ps == PERS_MAP) { + finishField(); + } + + } + + /** + * Parse strategy specific attributes. + */ + private void parseExtendedStrategy(FieldMetaData fmd, + PersistenceStrategy strategy, Attributes attrs) + throws SAXException { + + // The following attributes will be temporarily parsed for all strategy types. This + // is because it is not clear which attributes should be supported for which strategies. + // And more testing needs to be done to determine what actually works. + // Right now they are limited by the schema. But, putting these here allows a temporary schema + // update by a developer without requiring a corresponding code update. + parseTypeAttr(fmd, attrs); + parseElementTypeAttr(fmd, attrs); + parseKeyTypeAttr(fmd, attrs); + parseDependentAttr(fmd, attrs); + parseElementDependentAttr(fmd, attrs); + parseKeyDependentAttr(fmd, attrs); + parseElementClassCriteriaAttr(fmd, attrs); + parseLRSAttr(fmd, attrs); + parseInverseLogicalAttr(fmd, attrs); + parseEagerFetchModeAttr(fmd, attrs); + + switch (strategy) { + case BASIC: + parseExtendedBasic(fmd, attrs); + break; + case EMBEDDED: + parseExtendedEmbedded(fmd, attrs); + break; + case ONE_ONE: + parseExtendedOneToOne(fmd, attrs); + break; + case MANY_ONE: + parseExtendedManyToOne(fmd, attrs); + break; + case MANY_MANY: + parseExtendedManyToMany(fmd, attrs); + break; + case ONE_MANY: + parseExtendedOneToMany(fmd, attrs); + break; + case ELEM_COLL: + parseExtendedElementCollection(fmd, attrs); + } + } + + private void parseExtendedBasic(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + // TODO: Handle specific attributes + + } + + private void parseExtendedEmbedded(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + // TODO: Handle specific attributes + } + + private void parseExtendedOneToOne(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + // TODO: Handle specific attributes + } + + private void parseExtendedManyToOne(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + // TODO: Handle specific attributes + } + + private void parseExtendedManyToMany(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + // TODO: Handle specific attributes + } + + private void parseExtendedOneToMany(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + // TODO: Handle specific attributes + + } + + private void parseExtendedElementCollection(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + // TODO: Handle specific attributes + + } + + private void parsePersistent(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + parseTypeAttr(fmd, attrs); + // TODO - handle attributes + switch (fmd.getDeclaredTypeCode()) { + case JavaTypes.ARRAY: + if (fmd.getDeclaredType() == byte[].class + || fmd.getDeclaredType() == Byte[].class + || fmd.getDeclaredType() == char[].class + || fmd.getDeclaredType() == Character[].class) + break; + // no break + case JavaTypes.COLLECTION: + case JavaTypes.MAP: + throw new MetaDataException(_loc.get("bad-meta-anno", fmd, + "Persistent")); + } + } + + private void parsePersistentCollection(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + parseElementTypeAttr(fmd, attrs); + // TODO - handle attributes and field type + } + + private void parsePersistentMap(FieldMetaData fmd, Attributes attrs) + throws SAXException { + parseCommonExtendedAttributes(fmd, attrs); + parseElementTypeAttr(fmd, attrs); + parseKeyTypeAttr(fmd, attrs); + // TODO - handle attributes and field type + } + + private void parseCommonExtendedAttributes(FieldMetaData fmd, Attributes attrs) { + String loadFetchGroup = attrs.getValue("load-fetch-group"); + if (!StringUtils.isEmpty(loadFetchGroup)) { + fmd.setLoadFetchGroup(loadFetchGroup); + } + + String externalizer = attrs.getValue("externalizer"); + if (!StringUtils.isEmpty(externalizer)) { + fmd.setExternalizer(externalizer); + } + + String factory = attrs.getValue("factory"); + if (!StringUtils.isEmpty(factory)) { + fmd.setFactory(factory); + } + + parseStrategy(fmd, attrs); + } + + protected void parseStrategy(FieldMetaData fmd, Attributes attrs) { + + } + + private boolean startReadOnly(Attributes attrs) + throws SAXException { + + FieldMetaData fmd = (FieldMetaData) currentElement(); + String updateAction = attrs.getValue("update-action"); + + if (updateAction.equalsIgnoreCase("RESTRICT")) { + fmd.setUpdateStrategy(UpdateStrategies.RESTRICT); + } + else if (updateAction.equalsIgnoreCase("IGNORE")) { + fmd.setUpdateStrategy(UpdateStrategies.IGNORE); + } + else + throw new InternalException(); + + return true; + } + + private void parseDependentAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + String dependentStr = attrs.getValue("dependent"); + if (!StringUtils.isEmpty(dependentStr)) { + boolean dependent = Boolean.parseBoolean(dependentStr); + if (dependent) { + fmd.setCascadeDelete(ValueMetaData.CASCADE_AUTO); + } + else { + fmd.setCascadeDelete(ValueMetaData.CASCADE_NONE); + } + } + } + + private void parseElementDependentAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + + String elementDependentStr = attrs.getValue("element-dependent"); + if (!StringUtils.isEmpty(elementDependentStr)) { + boolean elementDependent = Boolean.parseBoolean(elementDependentStr); + if (elementDependent) { + fmd.getElement().setCascadeDelete(ValueMetaData.CASCADE_AUTO); + } + else { + fmd.getElement().setCascadeDelete(ValueMetaData.CASCADE_NONE); + } + } + } + + private void parseKeyDependentAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + + String keyDependentStr = attrs.getValue("key-dependent"); + if (!StringUtils.isEmpty(keyDependentStr)) { + boolean keyDependent = Boolean.parseBoolean(keyDependentStr); + if (keyDependent) { + fmd.getKey().setCascadeDelete(ValueMetaData.CASCADE_AUTO); + } + else { + fmd.getKey().setCascadeDelete(ValueMetaData.CASCADE_NONE); + } + } + } + + protected void parseElementClassCriteriaAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + +// String elementClassCriteriaString = attrs.getValue("element-class-criteria"); +// if (!StringUtils.isEmpty(elementClassCriteriaString)) { +// FieldMapping fm = (FieldMapping) fmd; +// boolean elementClassCriteria = Boolean.parseBoolean(elementClassCriteriaString); +// fm.getElementMapping().getValueInfo().setUseClassCriteria(elementClassCriteria); +// } + } + + private void parseTypeAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + + String typeStr = attrs.getValue("type"); + if (!StringUtils.isEmpty(typeStr)) { + if (StringUtils.endsWithIgnoreCase(typeStr, ".class")) { + typeStr = + typeStr.substring(0, StringUtils.lastIndexOf(typeStr, '.')); + } + Class<?> typeCls = parseTypeStr(typeStr); + + fmd.setTypeOverride(typeCls); + } + } + + private void parseLRSAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + String lrsStr = attrs.getValue("lrs"); + if (!StringUtils.isEmpty(lrsStr)) { + boolean lrs = Boolean.parseBoolean(lrsStr); + fmd.setLRS(lrs); + } + } + + private void parseElementTypeAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + + String typeStr = attrs.getValue("element-type"); + if (!StringUtils.isEmpty(typeStr)) { + if (StringUtils.endsWithIgnoreCase(typeStr, ".class")) { + typeStr = + typeStr.substring(0, StringUtils.lastIndexOf(typeStr, '.')); + } + Class<?> typeCls = parseTypeStr(typeStr); + + fmd.setTypeOverride(typeCls); + } + } + + private void parseKeyTypeAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + + String typeStr = attrs.getValue("key-type"); + if (!StringUtils.isEmpty(typeStr)) { + if (StringUtils.endsWithIgnoreCase(typeStr, ".class")) { + typeStr = + typeStr.substring(0, StringUtils.lastIndexOf(typeStr, '.')); + } + Class<?> typeCls = parseTypeStr(typeStr); + + fmd.setTypeOverride(typeCls); + } + } + + private Class<?> parseTypeStr(String typeStr) + throws SAXException { + Class<?> typeCls = null; + try { + if (typeStr.equalsIgnoreCase("int")) { + typeCls = int.class; + } + else if (typeStr.equalsIgnoreCase("byte")) { + typeCls = byte.class; + } + else if (typeStr.equalsIgnoreCase("short")) { + typeCls = short.class; + } + else if (typeStr.equalsIgnoreCase("long")) { + typeCls = long.class; + } + else if (typeStr.equalsIgnoreCase("float")) { + typeCls = float.class; + } + else if (typeStr.equalsIgnoreCase("double")) { + typeCls = double.class; + } + else if (typeStr.equalsIgnoreCase("boolean")) { + typeCls = boolean.class; + } + else if (typeStr.equalsIgnoreCase("char")) { + typeCls = char.class; + } + else { + typeCls = Class.forName(typeStr); + } + } catch (ClassNotFoundException e) { + throw new SAXException(e); + } + + return typeCls; + } + + private void parseInverseLogicalAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + + String inverseLogical = attrs.getValue("inverse-logical"); + if (!StringUtils.isEmpty(inverseLogical)) { + fmd.setInverse(inverseLogical); + } + } + + protected void parseEagerFetchModeAttr(FieldMetaData fmd, Attributes attrs) + throws SAXException { + } + + private boolean startExternalValues(Attributes attrs) + throws SAXException { + + _externalValues = new StringBuffer(10); + + return true; + } + + private void endExternalValues() + throws SAXException { + FieldMetaData fmd = (FieldMetaData) currentElement(); + fmd.setExternalValues(_externalValues.toString()); + _externalValues = null; + } + + private boolean startExternalValue(Attributes attrs) + throws SAXException { + + if (_externalValues.length() > 0) { + _externalValues.append(','); + } + _externalValues.append(attrs.getValue("java-value")); + _externalValues.append('='); + _externalValues.append(attrs.getValue("datastore-value")); + + return true; + } + + private boolean startExternalizer(Attributes attrs) + throws SAXException { + + return true; + } + + private void endExternalizer() + throws SAXException { + + FieldMetaData fmd = (FieldMetaData) currentElement(); + String externalizer = currentText(); + fmd.setExternalizer(externalizer); + } + + private boolean startFactory(Attributes attrs) + throws SAXException { + + return true; + } + + private void endFactory() + throws SAXException { + + FieldMetaData fmd = (FieldMetaData) currentElement(); + String factory = currentText(); + fmd.setFactory(factory); + } + + private boolean startFetchGroups(Attributes attrs) + throws SAXException { + if (_fgList == null) { + _fgList = new ArrayList<FetchGroupImpl>(); + } + return true; + } + + private boolean startFetchGroup(Attributes attrs) + throws SAXException { + + if (_fgList == null) { + _fgList = new ArrayList<FetchGroupImpl>(); + } + _currentFg = new AnnotationPersistenceMetaDataParser.FetchGroupImpl(attrs.getValue("name"), + Boolean.parseBoolean(attrs.getValue("post-load"))); + + return true; + } + + private void endFetchGroup() + throws SAXException { + + String[] referencedFetchGroups = {}; + if (_referencedFgList != null &&_referencedFgList.size() > 0) { + referencedFetchGroups = _referencedFgList.toArray(referencedFetchGroups); + } + _currentFg.setFetchGroups(referencedFetchGroups); + + FetchAttributeImpl[] fetchAttrs = {}; + if (_fetchAttrList != null && _fetchAttrList.size() > 0) { + fetchAttrs = _fetchAttrList.toArray(fetchAttrs); + } + _currentFg.setAttributes(fetchAttrs); + + _fgList.add(_currentFg); + _currentFg = null; + _referencedFgList = null; + _fetchAttrList = null; + } + + private boolean startFetchAttribute(Attributes attrs) + throws SAXException { + if (_fetchAttrList == null) { + _fetchAttrList = new ArrayList<FetchAttributeImpl>(); + } + + FetchAttributeImpl fetchAttribute = new FetchAttributeImpl(attrs.getValue("name"), + Integer.parseInt(attrs.getValue("recursion-depth"))); + + _fetchAttrList.add(fetchAttribute); + + return true; + } + + private boolean startReferencedFetchGroup(Attributes attrs) + throws SAXException { + + if (_referencedFgList == null) { + _referencedFgList = new ArrayList<String>(); + } + + return true; + } + + private void endReferencedFetchGroup() + throws SAXException { + + _referencedFgList.add(currentText()); + } + + @Override + protected void endExtendedClass(String elem) throws SAXException { + ClassMetaData meta = (ClassMetaData) peekElement(); + + if (_fgList != null) { + // Handle fetch groups + _fgs = new FetchGroupImpl[]{}; + _fgs = _fgList.toArray(_fgs); + AnnotationPersistenceMetaDataParser.parseFetchGroups(meta, _fgs); + _fgList = null; + _fgs = null; + } + } }
Added: openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/extendable-orm.xsd URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/extendable-orm.xsd?rev=1207320&view=auto ============================================================================== --- openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/extendable-orm.xsd (added) +++ openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/extendable-orm.xsd Mon Nov 28 15:44:58 2011 @@ -0,0 +1,393 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" + targetNamespace="http://www.apache.org/openjpa/ns/orm/extendable" + xmlns:extendable-orm="http://www.apache.org/openjpa/ns/orm/extendable" + xmlns:orm="http://java.sun.com/xml/ns/persistence/orm" + elementFormDefault="qualified" + attributeFormDefault="unqualified" + version="1.0"> + + <xsd:import namespace="http://java.sun.com/xml/ns/persistence/orm"/> + + <!-- **************************************************** --> + <xsd:element name="entity-mappings"> + <xsd:complexType> + <xsd:annotation> + <xsd:documentation> + See the entity-mappings type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:element name="description" type="xsd:string" + minOccurs="0" /> + <xsd:element ref="extendable-orm:ext-version" + minOccurs="1" maxOccurs="unbounded"/> + <xsd:element name="persistence-unit-metadata" + type="orm:persistence-unit-metadata" minOccurs="0" /> + <xsd:element name="package" type="xsd:string" + minOccurs="0" /> + <xsd:element name="schema" type="xsd:string" + minOccurs="0" /> + <xsd:element name="catalog" type="xsd:string" + minOccurs="0" /> + <xsd:element name="access" type="orm:access-type" + minOccurs="0" /> + <xsd:element name="sequence-generator" type="orm:sequence-generator" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="table-generator" type="orm:table-generator" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="named-query" type="orm:named-query" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="named-native-query" type="orm:named-native-query" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sql-result-set-mapping" + type="orm:sql-result-set-mapping" minOccurs="0" + maxOccurs="unbounded" /> + <xsd:element name="mapped-superclass" type="extendable-orm:mapped-superclass" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="entity" type="extendable-orm:entity" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="embeddable" type="extendable-orm:embeddable" + minOccurs="0" maxOccurs="unbounded" /> + </xsd:sequence> + <xsd:attribute name="version" type="orm:versionType" + fixed="2.0" use="required" /> + </xsd:complexType> + </xsd:element> + <!-- **************************************************** --> + <xsd:element name="ext-version" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="entity"> + <xsd:annotation> + <xsd:documentation> + See the entity type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:element name="description" type="xsd:string" + minOccurs="0" /> + <xsd:element name="table" type="orm:table" + minOccurs="0" /> + <xsd:element name="secondary-table" type="orm:secondary-table" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="primary-key-join-column" + type="orm:primary-key-join-column" minOccurs="0" + maxOccurs="unbounded" /> + <xsd:element name="id-class" type="orm:id-class" + minOccurs="0" /> + <xsd:element name="inheritance" type="orm:inheritance" + minOccurs="0" /> + <xsd:element name="discriminator-value" type="orm:discriminator-value" + minOccurs="0" /> + <xsd:element name="discriminator-column" type="orm:discriminator-column" + minOccurs="0" /> + <xsd:element name="sequence-generator" type="orm:sequence-generator" + minOccurs="0" /> + <xsd:element name="table-generator" type="orm:table-generator" + minOccurs="0" /> + <xsd:element name="named-query" type="orm:named-query" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="named-native-query" type="orm:named-native-query" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="sql-result-set-mapping" type="orm:sql-result-set-mapping" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="exclude-default-listeners" + type="orm:emptyType" minOccurs="0" /> + <xsd:element name="exclude-superclass-listeners" + type="orm:emptyType" minOccurs="0" /> + <xsd:element name="entity-listeners" type="orm:entity-listeners" + minOccurs="0" /> + <xsd:element name="pre-persist" type="orm:pre-persist" + minOccurs="0" /> + <xsd:element name="post-persist" type="orm:post-persist" + minOccurs="0" /> + <xsd:element name="pre-remove" type="orm:pre-remove" + minOccurs="0" /> + <xsd:element name="post-remove" type="orm:post-remove" + minOccurs="0" /> + <xsd:element name="pre-update" type="orm:pre-update" + minOccurs="0" /> + <xsd:element name="post-update" type="orm:post-update" + minOccurs="0" /> + <xsd:element name="post-load" type="orm:post-load" + minOccurs="0" /> + <xsd:element name="attribute-override" type="orm:attribute-override" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="association-override" type="orm:association-override" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="attributes" type="extendable-orm:attributes" + minOccurs="0" /> + <xsd:element ref="extendable-orm:ext-entity" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" /> + <xsd:attribute name="class" type="xsd:string" use="required" /> + <xsd:attribute name="access" type="orm:access-type" /> + <xsd:attribute name="cacheable" type="xsd:boolean" /> + <xsd:attribute name="metadata-complete" type="xsd:boolean" /> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-entity" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="mapped-superclass"> + <xsd:annotation> + <xsd:documentation> + See the mapped-superclass type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:element name="description" type="xsd:string" + minOccurs="0" /> + <xsd:element name="id-class" type="orm:id-class" + minOccurs="0" /> + <xsd:element name="exclude-default-listeners" + type="orm:emptyType" minOccurs="0" /> + <xsd:element name="exclude-superclass-listeners" + type="orm:emptyType" minOccurs="0" /> + <xsd:element name="entity-listeners" type="orm:entity-listeners" + minOccurs="0" /> + <xsd:element name="pre-persist" type="orm:pre-persist" + minOccurs="0" /> + <xsd:element name="post-persist" type="orm:post-persist" + minOccurs="0" /> + <xsd:element name="pre-remove" type="orm:pre-remove" + minOccurs="0" /> + <xsd:element name="post-remove" type="orm:post-remove" + minOccurs="0" /> + <xsd:element name="pre-update" type="orm:pre-update" + minOccurs="0" /> + <xsd:element name="post-update" type="orm:post-update" + minOccurs="0" /> + <xsd:element name="post-load" type="orm:post-load" + minOccurs="0" /> + <xsd:element name="attributes" type="extendable-orm:attributes" + minOccurs="0" /> + <xsd:element ref="extendable-orm:ext-mapped-superclass" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attribute name="class" type="xsd:string" use="required" /> + <xsd:attribute name="access" type="orm:access-type" /> + <xsd:attribute name="metadata-complete" type="xsd:boolean" /> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-mapped-superclass" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="embeddable"> + <xsd:annotation> + <xsd:documentation> + See the embeddable type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:element name="description" type="xsd:string" + minOccurs="0" /> + <xsd:element name="attributes" type="orm:embeddable-attributes" + minOccurs="0" /> + <xsd:element ref="extendable-orm:ext-embeddable" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + <xsd:attribute name="class" type="xsd:string" use="required" /> + <xsd:attribute name="access" type="orm:access-type" /> + <xsd:attribute name="metadata-complete" type="xsd:boolean" /> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-embeddable" abstract="true"/> + <!-- **************************************************** --> + + <xsd:complexType name="attributes"> + <xsd:annotation> + <xsd:documentation> + See the attributes type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:sequence> + <xsd:element name="description" type="xsd:string" + minOccurs="0" /> + <xsd:choice> + <xsd:element name="id" type="orm:id" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="embedded-id" type="orm:embedded-id" + minOccurs="0" /> + </xsd:choice> + <xsd:element name="basic" type="extendable-orm:basic" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="version" type="orm:version" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="many-to-one" type="extendable-orm:many-to-one" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="one-to-many" type="extendable-orm:one-to-many" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="one-to-one" type="extendable-orm:one-to-one" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="many-to-many" type="extendable-orm:many-to-many" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="element-collection" type="extendable-orm:element-collection" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="embedded" type="extendable-orm:embedded" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element name="transient" type="orm:transient" + minOccurs="0" maxOccurs="unbounded" /> + <xsd:element ref="extendable-orm:ext-attributes" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-attributes" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="basic"> + <xsd:annotation> + <xsd:documentation> + See the basic type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:complexContent> + <xsd:extension base="orm:basic"> + <xsd:sequence> + <xsd:element ref="extendable-orm:ext-basic" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-basic" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="many-to-one"> + <xsd:annotation> + <xsd:documentation> + See the many-to-one type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:complexContent> + <xsd:extension base="orm:many-to-one"> + <xsd:sequence> + <xsd:element ref="extendable-orm:ext-many-to-one" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-many-to-one" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="many-to-many"> + <xsd:annotation> + <xsd:documentation> + See the many-to-many type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:complexContent> + <xsd:extension base="orm:many-to-many"> + <xsd:sequence> + <xsd:element ref="extendable-orm:ext-many-to-many" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-many-to-many" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="one-to-many"> + <xsd:annotation> + <xsd:documentation> + See the one-to-many type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:complexContent> + <xsd:extension base="orm:one-to-many"> + <xsd:sequence> + <xsd:element ref="extendable-orm:ext-one-to-many" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-one-to-many" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="one-to-one"> + <xsd:annotation> + <xsd:documentation> + See the one-to-one type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:complexContent> + <xsd:extension base="orm:one-to-one"> + <xsd:sequence> + <xsd:element ref="extendable-orm:ext-one-to-one" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-one-to-one" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="element-collection"> + <xsd:annotation> + <xsd:documentation> + See the element-collection type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:complexContent> + <xsd:extension base="orm:element-collection"> + <xsd:sequence> + <xsd:element ref="extendable-orm:ext-element-collection" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-element-collection" abstract="true"/> + <!-- **************************************************** --> + <xsd:complexType name="embedded"> + <xsd:annotation> + <xsd:documentation> + See the embedded type in the schema for namespace + http://java.sun.com/xml/ns/persistence/orm. + </xsd:documentation> + </xsd:annotation> + <xsd:complexContent> + <xsd:extension base="orm:embedded"> + <xsd:sequence> + <xsd:element ref="extendable-orm:ext-embedded" + minOccurs="0" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:extension> + </xsd:complexContent> + </xsd:complexType> + <!-- **************************************************** --> + <xsd:element name="ext-embedded" abstract="true"/> + <!-- **************************************************** --> +</xsd:schema> \ No newline at end of file Propchange: openjpa/trunk/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/extendable-orm.xsd ------------------------------------------------------------------------------ svn:eol-style = native
