You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by di...@apache.org on 2011/11/28 16:45:00 UTC

svn commit: r1207320 [2/3] - in /openjpa/trunk: openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/ openjpa-persistence-jdbc/src/main/java/org/apache/openjpa/persistence/jdbc/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/fet...

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