/*
 * 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.
 */
package org.apache.openjpa.persistence;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.net.URL;
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.Objects;
import java.util.Set;
import java.util.Stack;

import javax.persistence.CascadeType;
import javax.persistence.GenerationType;
import javax.persistence.LockModeType;

import static javax.persistence.CascadeType.*;

import org.apache.openjpa.lib.util.StringUtil;
import org.apache.openjpa.conf.OpenJPAConfiguration;
import org.apache.openjpa.enhance.PersistenceCapable;
import org.apache.openjpa.event.BeanLifecycleCallbacks;
import org.apache.openjpa.event.LifecycleCallbacks;
import org.apache.openjpa.event.LifecycleEvent;
import org.apache.openjpa.event.MethodLifecycleCallbacks;
import org.apache.openjpa.kernel.QueryLanguages;
import org.apache.openjpa.kernel.jpql.JPQLParser;
import org.apache.openjpa.lib.conf.Configurations;
import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.lib.meta.CFMetaDataParser;
import org.apache.openjpa.lib.meta.SourceTracker;
import org.apache.openjpa.lib.meta.XMLVersionParser;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.meta.AccessCode;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.DelegatingMetaDataFactory;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.JavaTypes;
import org.apache.openjpa.meta.LifecycleMetaData;
import org.apache.openjpa.meta.MetaDataContext;
import org.apache.openjpa.meta.MetaDataDefaults;
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;
import org.xml.sax.SAXException;


/**
 * Custom SAX parser used by the system to quickly parse persistence
 * metadata files. This parser may invoke
 * {@linkplain AnnotationPersistenceMetaDataParser another parser} to scan
 * source code annotation.
 *
 * @author Steve Kim
 * @author Pinaki Poddar
 */
public class XMLPersistenceMetaDataParser
    extends CFMetaDataParser
    implements PersistenceMetaDataFactory.Parser {

    // parse constants
    protected static final String ELEM_PKG = "package";
    protected static final String ELEM_ACCESS = "access";
    protected static final String ELEM_ATTRS = "attributes";
    protected static final String ELEM_LISTENER = "entity-listener";
    protected static final String ELEM_CASCADE = "cascade";
    protected static final String ELEM_CASCADE_ALL = "cascade-all";
    protected static final String ELEM_CASCADE_PER = "cascade-persist";
    protected static final String ELEM_CASCADE_MER = "cascade-merge";
    protected static final String ELEM_CASCADE_REM = "cascade-remove";
    protected static final String ELEM_CASCADE_REF = "cascade-refresh";
    protected static final String ELEM_CASCADE_DET = "cascade-detach";
    protected static final String ELEM_PU_META = "persistence-unit-metadata";
    protected static final String ELEM_PU_DEF = "persistence-unit-defaults";
    protected static final String ELEM_XML_MAP_META_COMPLETE = "xml-mapping-metadata-complete";
    protected static final String ELEM_DELIM_IDS = "delimited-identifiers";
    
    // The following is needed for input into the delimitString() method
    protected static enum localDBIdentifiers {
        SEQUENCE_GEN_SEQ_NAME,
        SEQUENCE_GEN_SCHEMA
    }    

    private static final Map<String, Object> _elems =
        new HashMap<String, Object>();

    // Map for storing deferred metadata which needs to be populated
    // after embeddables are loaded.
    private static final Map<Class<?>, ArrayList<MetaDataContext>>
        _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);
        _elems.put(ELEM_ACCESS, ELEM_ACCESS);
        _elems.put(ELEM_ATTRS, ELEM_ATTRS);
        _elems.put(ELEM_LISTENER, ELEM_LISTENER);
        _elems.put(ELEM_CASCADE, ELEM_CASCADE);
        _elems.put(ELEM_CASCADE_ALL, ELEM_CASCADE_ALL);
        _elems.put(ELEM_CASCADE_PER, ELEM_CASCADE_PER);
        _elems.put(ELEM_CASCADE_REM, ELEM_CASCADE_REM);
        _elems.put(ELEM_CASCADE_MER, ELEM_CASCADE_MER);
        _elems.put(ELEM_CASCADE_REF, ELEM_CASCADE_REF);
        _elems.put(ELEM_CASCADE_DET, ELEM_CASCADE_DET);
        _elems.put(ELEM_PU_META, ELEM_PU_META);
        _elems.put(ELEM_PU_DEF, ELEM_PU_DEF);
        _elems.put(ELEM_XML_MAP_META_COMPLETE, ELEM_XML_MAP_META_COMPLETE);
        _elems.put(ELEM_DELIM_IDS, ELEM_DELIM_IDS);

        _elems.put("entity-listeners", ENTITY_LISTENERS);
        _elems.put("pre-persist", PRE_PERSIST);
        _elems.put("post-persist", POST_PERSIST);
        _elems.put("pre-remove", PRE_REMOVE);
        _elems.put("post-remove", POST_REMOVE);
        _elems.put("pre-update", PRE_UPDATE);
        _elems.put("post-update", POST_UPDATE);
        _elems.put("post-load", POST_LOAD);
        _elems.put("exclude-default-listeners", EXCLUDE_DEFAULT_LISTENERS);
        _elems.put("exclude-superclass-listeners",
            EXCLUDE_SUPERCLASS_LISTENERS);

        _elems.put("named-query", QUERY);
        _elems.put("named-native-query", NATIVE_QUERY);
        _elems.put("hint", QUERY_HINT);
        _elems.put("query", QUERY_STRING);

        _elems.put("flush-mode", FLUSH_MODE);
        _elems.put("sequence-generator", SEQ_GENERATOR);

        _elems.put("id", ID);
        _elems.put("id-class", ID_CLASS);
        _elems.put("embedded-id", EMBEDDED_ID);
        _elems.put("maps-id", MAPPED_BY_ID);
        _elems.put("version", VERSION);
        _elems.put("generated-value", GENERATED_VALUE);
        _elems.put("map-key", MAP_KEY);
        _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);
        _elems.put("one-to-one", ONE_ONE);
        _elems.put("embedded", EMBEDDED);
        _elems.put("one-to-many", ONE_MANY);
        _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);

    private final OpenJPAConfiguration _conf;
    private MetaDataRepository _repos = null;
    private AnnotationPersistenceMetaDataParser _parser = null;
    private ClassLoader _envLoader = null;
    private int _mode = MODE_NONE;
    private boolean _override = false;

    private final Stack<Object> _elements = new Stack<Object>();
    private final Stack<Object> _parents = new Stack<Object>();
    
    private StringBuffer _externalValues = null;

    protected Class<?> _cls = null;
    // List of classes currently being parsed
    private ArrayList<Class<?>> _parseList = new ArrayList<Class<?>>();
    private int _fieldPos = 0;
    private int _clsPos = 0;
    private int _access = AccessCode.UNKNOWN;
    private PersistenceStrategy _strategy = null;
    private Set<CascadeType> _cascades = null;
    private Set<CascadeType> _pkgCascades = null;

    private Class<?> _listener = null;
    private Collection<LifecycleCallbacks>[] _callbacks = null;
    private Collection<Class<?>> _listeners = null;
    private int[] _highs = null;
    private boolean _isXMLMappingMetaDataComplete = false;

    private String _ormVersion;
    private String _schemaLocation;

    private static final String ORM_XSD_1_0 = "orm_1_0.xsd";
    private static final String ORM_XSD_2_0 = "orm_2_0.xsd";

    /**
     * Constructor; supply configuration.
     */
    public XMLPersistenceMetaDataParser(OpenJPAConfiguration conf) {
        _conf = conf;
        setValidating(true);
        setLog(conf.getLog(OpenJPAConfiguration.LOG_METADATA));
        setParseComments(true);
        setMode(MODE_META | MODE_MAPPING | MODE_QUERY);
        setParseText(true);
    }

    /**
     * Configuration supplied on construction.
     */
    public OpenJPAConfiguration getConfiguration() {
        return _conf;
    }

    /**
     * The annotation parser. When class is discovered in an XML file,
     * we first parse any annotations present, then override with the XML.
     */
    public AnnotationPersistenceMetaDataParser getAnnotationParser() {
        return _parser;
    }

    /**
     * The annotation parser. When class is discovered in an XML file,
     * we first parse any annotations present, then override with the XML.
     */
    public void setAnnotationParser(AnnotationPersistenceMetaDataParser parser){
        _parser = parser;
    }

    /**
     * Returns the repository for this parser. If none has been set, creates
     * a new repository and sets it.
     */
    public MetaDataRepository getRepository() {
        if (_repos == null) {
            MetaDataRepository repos = _conf.newMetaDataRepositoryInstance();
            MetaDataFactory mdf = repos.getMetaDataFactory();
            if (mdf instanceof DelegatingMetaDataFactory)
                mdf = ((DelegatingMetaDataFactory) mdf).getInnermostDelegate();
            if (mdf instanceof PersistenceMetaDataFactory)
                ((PersistenceMetaDataFactory) mdf).setXMLParser(this);
            _repos = repos;
        }
        return _repos;
    }

    /**
     * Set the metadata repository for this parser.
     */
    public void setRepository(MetaDataRepository repos) {
        _repos = repos;
        if (repos != null
            && (repos.getValidate() & MetaDataRepository.VALIDATE_RUNTIME) != 0)
            setParseComments(false);
        
        if (repos != null) {
            // Determine if the Thread Context Classloader needs to be temporally overridden to the Classloader
            // that loaded the OpenJPA classes, to avoid a potential deadlock issue with the way Xerces
            // handles parsers and classloaders.
            this.setOverrideContextClassloader(repos.getConfiguration().getCompatibilityInstance().
                getOverrideContextClassloader());
        }
    }

    /**
     * Return the environmental class loader to pass on to parsed
     * metadata instances.
     */
    public ClassLoader getEnvClassLoader() {
        return _envLoader;
    }

    /**
     * Set the environmental class loader to pass on to parsed
     * metadata instances.
     */
    public void setEnvClassLoader(ClassLoader loader) {
        _envLoader = loader;
    }

    /**
     * Whether to allow later parses of mapping information to override
     * earlier information for the same class. Defaults to false. Useful
     * when a tool is mapping a class, so that .jdo file partial mapping
     * information can be used even when mappings are stored in .orm files
     * or other locations.
     */
    public boolean getMappingOverride() {
        return _override;
    }

    /**
     * Whether to allow later parses of mapping information to override
     * earlier information for the same class. Defaults to false. Useful
     * when a tool is mapping a class, so that .jdo file partial mapping
     * information can be used even when mappings are stored in .orm files
     * or other locations.
     */
    public void setMappingOverride(boolean override) {
        _override = override;
    }

    /**
     * The parse mode according to the expected document type. The
     * mode constants act as bit flags, and therefore can be combined.
     */
    public int getMode() {
        return _mode;
    }

    /**
     * The parse mode according to the expected document type.
     */
    public void setMode(int mode, boolean on) {
        if (mode == MODE_NONE)
            setMode(MODE_NONE);
        else if (on)
            setMode(_mode | mode);
        else
            setMode(_mode & ~mode);
    }

    /**
     * The parse mode according to the expected document type.
     */
    public void setMode(int mode) {
        _mode = mode;
        if (_parser != null)
            _parser.setMode(mode);
    }

    public void parse(URL url) throws IOException {
        // peek at the doc to determine the version
        XMLVersionParser vp = new XMLVersionParser("entity-mappings");
        try {
            vp.parse(url);
            _ormVersion = vp.getVersion();
            _schemaLocation = vp.getSchemaLocation();
        } catch (Throwable t) {
                Log log = getLog();
                if (log.isInfoEnabled())
                    log.trace(_loc.get("version-check-error",
                        url.toString()));
        }
        super.parse(url);
    }

    public void parse(File file) throws IOException {
        // peek at the doc to determine the version
        XMLVersionParser vp = new XMLVersionParser("entity-mappings");
        try {
            vp.parse(file);
            _ormVersion = vp.getVersion();
            _schemaLocation = vp.getSchemaLocation();
        } catch (Throwable t) {
                Log log = getLog();
                if (log.isInfoEnabled())
                    log.trace(_loc.get("version-check-error",
                        file.toString()));
        }
        super.parse(file);
    }
    /**
     * Convenience method for interpreting {@link #getMode}.
     */
    protected boolean isMetaDataMode() {
        return (_mode & MODE_META) != 0;
    }

    /**
     * Convenience method for interpreting {@link #getMode}.
     */
    protected boolean isQueryMode() {
        return (_mode & MODE_QUERY) != 0;
    }

    /**
     * Convenience method for interpreting {@link #getMode}.
     */
    protected boolean isMappingMode() {
        return (_mode & MODE_MAPPING) != 0;
    }

    /**
     * Returns true if we're in mapping mode or in metadata mode with
     * mapping override enabled.
     */
    protected boolean isMappingOverrideMode() {
        return isMappingMode() || (_override && isMetaDataMode());
    }

    ///////////////
    // XML parsing
    ///////////////

    /**
     * Push a parse element onto the stack.
     */
    protected void pushElement(Object elem) {
        _elements.push(elem);
    }

    /**
     * Pop a parse element from the stack.
     */
    protected Object popElement() {
        return _elements.pop();
    }

    /**
     * Peek a parse element from the stack.
     */
    protected Object peekElement() {
        return _elements.peek();
    }

    /**
     * Return the current element being parsed. May be a class metadata,
     * field metadata, query metadata, etc.
     */
    protected Object currentElement() {
        if (_elements.isEmpty())
            return null;
        return _elements.peek();
    }

    /**
     * Return the current {@link PersistenceStrategy} if any.
     */
    protected PersistenceStrategy currentStrategy() {
        return _strategy;
    }

    /**
     * Return the tag of the current parent element.
     */
    protected Object currentParent() {
        if (_parents.isEmpty())
            return null;
        return _parents.peek();
    }

    /**
     * Return whether we're running the parser at runtime.
     */
    protected boolean isRuntime() {
        return (getRepository().getValidate()
            & MetaDataRepository.VALIDATE_RUNTIME) != 0;
    }

    @Override
    protected Object getSchemaSource() {
        // 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 &&
            _ormVersion.equals(XMLVersionParser.VERSION_1_0) ||
            (_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 schema.toArray();
    }

    @Override
    protected String getPackageAttributeName() {
        return null;
    }

    @Override
    protected String getClassAttributeName() {
        return "class";
    }

    @Override
    protected int getClassElementDepth() {
        return 1;
    }

    @Override
    protected boolean isClassElementName(String name) {
        return "entity".equals(name)
            || "embeddable".equals(name)
            || "mapped-superclass".equals(name);
    }

    @Override
    protected void reset() {
    	// Add all remaining deferred embeddable metadata
        addDeferredEmbeddableMetaData();

        super.reset();
        _elements.clear();
        _parents.clear();
        _cls = null;
        _parseList.clear();
        _fieldPos = 0;
        _clsPos = 0;

        _access = AccessCode.UNKNOWN;
        _strategy = null;
        _listener = null;
        _callbacks = null;
        _highs = null;
        _cascades = null;
        _pkgCascades = null;
    }

    @Override
    protected boolean startSystemElement(String name, Attributes attrs)
        throws SAXException {
        Object tag = _elems.get(name);
        boolean ret = false;
        if (tag == null) {
            if (isMappingOverrideMode())
                tag = startSystemMappingElement(name, attrs);
            ret = tag != null;
        } else if (tag instanceof MetaDataTag) {
            switch ((MetaDataTag) tag) {
                case QUERY:
                    ret = startNamedQuery(attrs);
                    break;
                case QUERY_HINT:
                    ret = startQueryHint(attrs);
                    break;
                case NATIVE_QUERY:
                    ret = startNamedNativeQuery(attrs);
                    break;
                case QUERY_STRING:
                    ret = startQueryString(attrs);
                    break;
                case SEQ_GENERATOR:
                    ret = startSequenceGenerator(attrs);
                    break;
                case FLUSH_MODE:
                    ret = startFlushMode(attrs);
                    break;
                case ENTITY_LISTENERS:
                    ret = startEntityListeners(attrs);
                    break;
                case PRE_PERSIST:
                case POST_PERSIST:
                case PRE_REMOVE:
                case POST_REMOVE:
                case PRE_UPDATE:
                case POST_UPDATE:
                case POST_LOAD:
                    ret = startCallback((MetaDataTag) tag, attrs);
                    break;
                default:
                    warnUnsupportedTag(name);
            }
        } else if (tag == ELEM_PU_META || tag == ELEM_PU_DEF)
            ret = isMetaDataMode();
        else if (tag == ELEM_XML_MAP_META_COMPLETE) {
            setAnnotationParser(null);
            _isXMLMappingMetaDataComplete = true;
        }
        else if (tag == ELEM_ACCESS)
            ret = _mode != MODE_QUERY;
        else if (tag == ELEM_LISTENER)
            ret = startEntityListener(attrs);
        else if (tag == ELEM_DELIM_IDS)
            ret = startDelimitedIdentifiers();
        else if (tag == ELEM_CASCADE)
            ret = isMetaDataMode();
        else if (tag == ELEM_CASCADE_ALL || tag == ELEM_CASCADE_PER
            || tag == ELEM_CASCADE_MER || tag == ELEM_CASCADE_REM
            || tag == ELEM_CASCADE_REF || tag == ELEM_CASCADE_DET)
            ret = startCascade(tag, attrs);

        if (ret)
            _parents.push(tag);
        return ret;
    }

    @Override
    protected void endSystemElement(String name)
        throws SAXException {
        Object tag = _elems.get(name);
        if (tag == null && isMappingOverrideMode())
            endSystemMappingElement(name);
        else if (tag instanceof MetaDataTag) {
            switch ((MetaDataTag) tag) {
                case QUERY:
                    endNamedQuery();
                    break;
                case QUERY_HINT:
                    endQueryHint();
                    break;
                case NATIVE_QUERY:
                    endNamedNativeQuery();
                    break;
                case QUERY_STRING:
                    endQueryString();
                    break;
                case SEQ_GENERATOR:
                    endSequenceGenerator();
                    break;
            }
        } else if (tag == ELEM_ACCESS)
            endAccess();
        else if (tag == ELEM_LISTENER)
            endEntityListener();

        _parents.pop();
    }

    /**
     * Implement to parse a mapping element outside of any class.
     *
     * @return the tag for the given element, or null to skip the element
     */
    protected Object startSystemMappingElement(String name, Attributes attrs)
        throws SAXException {
        return null;
    }

    /**
     * Implement to parse a mapping element outside of any class.
     */
    protected void endSystemMappingElement(String name)
        throws SAXException {
    }

    @Override
    protected boolean startClassElement(String name, Attributes attrs)
        throws SAXException {
        Object tag = (Object) _elems.get(name);
        boolean ret = false;
        if (tag == null) {
            if (isMappingOverrideMode())
                tag = startClassMappingElement(name, attrs);
            ret = tag != null;
        } else if (tag instanceof MetaDataTag) {
            switch ((MetaDataTag) tag) {
                case GENERATED_VALUE:
                    ret = startGeneratedValue(attrs);
                    break;
                case ID:
                    ret = startId(attrs);
                    break;
                case EMBEDDED_ID:
                    ret = startEmbeddedId(attrs);
                    break;
                case ID_CLASS:
                    ret = startIdClass(attrs);
                    break;
                case LOB:
                    ret = startLob(attrs);
                    break;
                case QUERY:
                    ret = startNamedQuery(attrs);
                    break;
                case QUERY_HINT:
                    ret = startQueryHint(attrs);
                    break;
                case NATIVE_QUERY:
                    ret = startNamedNativeQuery(attrs);
                    break;
                case QUERY_STRING:
                    ret = startQueryString(attrs);
                    break;
                case SEQ_GENERATOR:
                    ret = startSequenceGenerator(attrs);
                    break;
                case VERSION:
                    ret = startVersion(attrs);
                    break;
                case MAP_KEY:
                    ret = startMapKey(attrs);
                    break;
                case MAP_KEY_CLASS:
                    ret = startMapKeyClass(attrs);
                    break;
                case FLUSH_MODE:
                    ret = startFlushMode(attrs);
                    break;
                case ORDER_COLUMN:
                    ret = startOrderColumn(attrs);
                    break;
                case ORDER_BY:
                case ENTITY_LISTENERS:
                    ret = isMetaDataMode();
                    break;
                case EXCLUDE_DEFAULT_LISTENERS:
                    ret = startExcludeDefaultListeners(attrs);
                    break;
                case EXCLUDE_SUPERCLASS_LISTENERS:
                    ret = startExcludeSuperclassListeners(attrs);
                    break;
                case PRE_PERSIST:
                case POST_PERSIST:
                case PRE_REMOVE:
                case POST_REMOVE:
                case PRE_UPDATE:
                case POST_UPDATE:
                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;
            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)
            ret = startEntityListener(attrs);
        else if (tag == ELEM_ATTRS)
            ret = _mode != MODE_QUERY;
        else if (tag == ELEM_CASCADE)
            ret = isMetaDataMode();
        else if (tag == ELEM_CASCADE_ALL || tag == ELEM_CASCADE_PER
            || tag == ELEM_CASCADE_MER || tag == ELEM_CASCADE_REM
            || tag == ELEM_CASCADE_REF || tag == ELEM_CASCADE_DET)
            ret = startCascade(tag, attrs);

        if (ret)
            _parents.push(tag);
        return ret;
    }

    @Override
    protected void endClassElement(String name)
        throws SAXException {
        Object tag = _elems.get(name);
        if (tag == null && isMappingOverrideMode())
            endClassMappingElement(name);
        else if (tag instanceof MetaDataTag) {
            switch ((MetaDataTag) tag) {
                case GENERATED_VALUE:
                    endGeneratedValue();
                    break;
                case ID:
                    endId();
                    break;
                case EMBEDDED_ID:
                    endEmbeddedId();
                    break;
                case ID_CLASS:
                    endIdClass();
                    break;
                case LOB:
                    endLob();
                    break;
                case QUERY:
                    endNamedQuery();
                    break;
                case QUERY_HINT:
                    endQueryHint();
                    break;
                case NATIVE_QUERY:
                    endNamedNativeQuery();
                    break;
                case QUERY_STRING:
                    endQueryString();
                    break;
                case SEQ_GENERATOR:
                    endSequenceGenerator();
                    break;
                case VERSION:
                    endVersion();
                    break;
                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 == ELEM_ACCESS)
            endAccess();
        else if (tag == ELEM_LISTENER)
            endEntityListener();

        _parents.pop();
    }

    /**
     * Log warning about an unsupported tag.
     */
    private void warnUnsupportedTag(String name) {
        Log log = getLog();
        if (log.isInfoEnabled())
            log.trace(_loc.get("unsupported-tag", name));
    }

    /**
     * Implement to parse a mapping element within a class.
     *
     * @return the tag for the given element, or null to skip element
     */
    protected Object startClassMappingElement(String name, Attributes attrs)
        throws SAXException {
        return null;
    }

    /**
     * Implement to parse a mapping element within a class.
     */
    protected void endClassMappingElement(String name)
        throws SAXException {
    }

    boolean isMetaDataComplete(Attributes attrs) {
    	return attrs != null
    	    && "true".equals(attrs.getValue("metadata-complete"));
    }

    void resetAnnotationParser() {
    	setAnnotationParser(((PersistenceMetaDataFactory)getRepository()
    			.getMetaDataFactory()).getAnnotationParser());
    }

    @Override
    protected boolean startClass(String elem, Attributes attrs)
        throws SAXException {
        boolean metaDataComplete = false;
        super.startClass(elem, attrs);
        if (isMetaDataComplete(attrs)) {
            metaDataComplete = true;
        	setAnnotationParser(null);
        } else if (!_isXMLMappingMetaDataComplete){
        	resetAnnotationParser();
        }

        // query mode only?
        _cls = classForName(currentClassName());

        // Prevent a reentrant parse for the same class
        if (parseListContains(_cls)) {
            return false;
        }

        if (_mode == MODE_QUERY) {
            if(_conf.getCompatibilityInstance().getParseAnnotationsForQueryMode()){ 
                if (_parser != null) {
                    _parser.parse(_cls);
                }
            }
            return true;
        }

        Log log = getLog();
        if (log.isTraceEnabled())
            log.trace(_loc.get("parse-class", _cls.getName()));

        MetaDataRepository repos = getRepository();
        ClassMetaData meta = repos.getCachedMetaData(_cls);
        if (meta != null
            && ((isMetaDataMode() && (meta.getSourceMode() & MODE_META) != 0)
            || (isMappingMode() && (meta.getSourceMode() & MODE_MAPPING) != 0)))
        {
            if(isDuplicateClass(meta)) { 
                if (log.isWarnEnabled()) {
                    log.warn(_loc.get("dup-metadata", _cls, getSourceName()));
                }
                if(log.isTraceEnabled()) { 
                    log.trace(String.format(
                        "MetaData originally obtained from source: %s under mode: %d with scope: %s, and type: %d",
                        meta.getSourceName(), meta.getSourceMode(), meta.getSourceScope(), meta.getSourceType()));
                }
            }
            _cls = null;
            return false;
        }
        
        int access = AccessCode.UNKNOWN;
        if (meta == null) {
            int accessCode = toAccessType(attrs.getValue("access"));
            // if access not specified and access was specified at
            // the system level, use the system default (which may
            // be UNKNOWN)
            if (accessCode == AccessCode.UNKNOWN)
                accessCode = _access;
            meta = repos.addMetaData(_cls, accessCode, metaDataComplete);
            FieldMetaData[] fmds = meta.getFields();
            if (metaDataComplete) {
                for (int i = 0; i < fmds.length; i++) {
                    fmds[i].setExplicit(true);
                }
            }
            meta.setEnvClassLoader(_envLoader);
            meta.setSourceMode(MODE_NONE);

            // parse annotations first so XML overrides them
            if (_parser != null) {
                _parser.parse(_cls);
            }
        }
        access = meta.getAccessType();

        boolean mappedSuper = "mapped-superclass".equals(elem);
        boolean embeddable = "embeddable".equals(elem);

        if (isMetaDataMode()) {
            Locator locator = getLocation().getLocator();
            meta.setSource(getSourceFile(), SourceTracker.SRC_XML, locator != null ? locator.getSystemId() : "" );
            meta.setSourceMode(MODE_META, true);
        
            if (locator != null) {
                meta.setLineNumber(locator.getLineNumber());
                meta.setColNumber(locator.getColumnNumber());
            }
            meta.setListingIndex(_clsPos);
            String name = attrs.getValue("name");
            if (!StringUtil.isEmpty(name))
                meta.setTypeAlias(name);
            meta.setAbstract(mappedSuper);
            meta.setEmbeddedOnly(mappedSuper || embeddable);

            if (embeddable) {
                meta.setEmbeddable();
                setDeferredEmbeddableAccessType(_cls, access);
            }
        }

        if (attrs.getValue("cacheable") != null) {
            meta.setCacheEnabled(Boolean.valueOf(attrs.getValue("cacheable")));
        }

        if (isMappingMode())
            meta.setSourceMode(MODE_MAPPING, true);
        if (isMappingOverrideMode())
            startClassMapping(meta, mappedSuper, attrs);
        if (isQueryMode())
            meta.setSourceMode(MODE_QUERY, true);

        _clsPos++;
        _fieldPos = 0;
        addComments(meta);
        pushElement(meta);
        return true;
    }

    @Override
    protected void endClass(String elem)
        throws SAXException {
        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.
     */
    protected void startClassMapping(ClassMetaData mapping,
        boolean mappedSuper, Attributes attrs)
        throws SAXException {
    }

    /**
     * Implement to finalize class mapping.
     */
    protected void endClassMapping(ClassMetaData mapping)
        throws SAXException {
    }

    /**
     * Default access element.
     */
    private void endAccess() {
        _access = toAccessType(currentText());
    }

    /**
     * Parse the given string as an entity access type, defaulting to given
     * default if string is empty.
     */
    private int toAccessType(String str) {
        if (StringUtil.isEmpty(str))
            return AccessCode.UNKNOWN;
        if ("PROPERTY".equals(str))
            return AccessCode.EXPLICIT | AccessCode.PROPERTY;
        return AccessCode.EXPLICIT | AccessCode.FIELD;
    }
    /**
     * Parse flush-mode element.
     */
    private boolean startFlushMode(Attributes attrs)
        throws SAXException {
        Log log = getLog();
        if (log.isWarnEnabled())
            log.warn(_loc.get("unsupported", "flush-mode", getSourceName()));
        return false;
    }

    /**
     * Parse sequence-generator.
     */
    protected boolean startSequenceGenerator(Attributes attrs) {
        if (!isMappingOverrideMode())
            return false;

        String name = attrs.getValue("name");
        Log log = getLog();
        if (log.isTraceEnabled())
            log.trace(_loc.get("parse-sequence", name));

        SequenceMetaData meta = getRepository().getCachedSequenceMetaData(name);
        if (meta != null && log.isWarnEnabled())
            log.warn(_loc.get("override-sequence", name));

        meta = getRepository().addSequenceMetaData(name);
        String seq = attrs.getValue("sequence-name");
        // Do not normalize the sequence name if it appears to be a plugin 
        if (seq.indexOf('(') == -1){
            seq = normalizeSequenceName(seq);
        }
        String val = attrs.getValue("initial-value");
        int initial = val == null ? 1 : Integer.parseInt(val);
        val = attrs.getValue("allocation-size");
        int allocate = val == null ? 50 : Integer.parseInt(val);
        String schema = normalizeSchemaName(attrs.getValue("schema"));
        String catalog = normalizeCatalogName(attrs.getValue("catalog"));

        String clsName, props;
        if (seq == null || seq.indexOf('(') == -1) {
            clsName = SequenceMetaData.IMPL_NATIVE;
            props = null;
        } else { // plugin
            clsName = Configurations.getClassName(seq);
            props = Configurations.getProperties(seq);
            seq = null;
        }

        meta.setSequencePlugin(Configurations.getPlugin(clsName, props));
        meta.setSequence(seq);
        meta.setInitialValue(initial);
        meta.setAllocate(allocate);
        meta.setSchema(schema);
        meta.setCatalog(catalog);

        Object cur = currentElement();
        Object scope = (cur instanceof ClassMetaData)
            ? ((ClassMetaData) cur).getDescribedType() : null;
        meta.setSource(getSourceFile(), scope, SourceTracker.SRC_XML);
        Locator locator = getLocation().getLocator();
        if (locator != null) {
            meta.setLineNumber(locator.getLineNumber());
            meta.setColNumber(locator.getColumnNumber());
        }
        return true;
    }

    protected void endSequenceGenerator() {
    }

    /**
     * Parse id.
     */
    protected boolean startId(Attributes attrs)
        throws SAXException {
        FieldMetaData fmd = parseField(attrs);
        fmd.setExplicit(true);
        fmd.setPrimaryKey(true);
        return true;
    }

    protected void endId()
        throws SAXException {
        finishField();
    }

    /**
     * Parse embedded-id.
     */
    protected boolean startEmbeddedId(Attributes attrs)
        throws SAXException {
        FieldMetaData fmd = parseField(attrs);
        fmd.setExplicit(true);
        fmd.setPrimaryKey(true);
        fmd.setEmbedded(true);
        fmd.setSerialized(false);
        if (fmd.getEmbeddedMetaData() == null)
//            fmd.addEmbeddedMetaData();
            deferEmbeddable(fmd.getDeclaredType(), fmd);
        return true;
    }

    protected void endEmbeddedId()
        throws SAXException {
        finishField();
    }

    /**
     * Parse id-class.
     */
    protected boolean startIdClass(Attributes attrs)
        throws SAXException {
        if (!isMetaDataMode())
            return false;

        ClassMetaData meta = (ClassMetaData) currentElement();
        String cls = attrs.getValue("class");
        Class<?> idCls = null;
        try {
            idCls = classForName(cls);
        } catch (Throwable t) {
            throw getException(_loc.get("invalid-id-class", meta, cls), t);
        }
        if (!Serializable.class.isAssignableFrom(idCls)) {
        	_conf.getConfigurationLog().warn(_loc.get("id-class-not-serializable", idCls, _cls));
        }
        meta.setObjectIdType(idCls, true);
        return true;
    }

    protected void endIdClass()
        throws SAXException {
    }

    /**
     * Parse lob.
     */
    protected boolean startLob(Attributes attrs)
        throws SAXException {
        FieldMetaData fmd = (FieldMetaData) currentElement();
        int typeCode = fmd.isElementCollection() ? fmd.getElement().getDeclaredTypeCode() : fmd.getDeclaredTypeCode();
        Class<?> type = fmd.isElementCollection() ? fmd.getElement().getDeclaredType() : fmd.getDeclaredType();
        if (typeCode != JavaTypes.STRING
            && type != char[].class
            && type != Character[].class
            && type != byte[].class
            && type != Byte[].class)
            fmd.setSerialized(true);
        return true;
    }

    protected void endLob()
        throws SAXException {
    }

    /**
     * Parse generated-value.
     */
    protected boolean startGeneratedValue(Attributes attrs)
        throws SAXException {
        if (!isMappingOverrideMode())
            return false;

        String strategy = attrs.getValue("strategy");
        String generator = attrs.getValue("generator");
        GenerationType type = StringUtil.isEmpty(strategy)
            ? GenerationType.AUTO : GenerationType.valueOf(strategy);

        FieldMetaData fmd = (FieldMetaData) currentElement();
        AnnotationPersistenceMetaDataParser.parseGeneratedValue(fmd, type,
            generator);
        return true;
    }

    protected void endGeneratedValue()
        throws SAXException {
    }

    /**
     * Lazily parse cascades.
     */
    protected boolean startCascade(Object tag, Attributes attrs)
        throws SAXException {
        if (!isMetaDataMode())
            return false;
        
        boolean puDefault = false;

        Set<CascadeType> cascades = null;
        if (currentElement() instanceof FieldMetaData) {
            if (_cascades == null)
                _cascades = EnumSet.noneOf(CascadeType.class);
            cascades = _cascades;
        } else {
            if (_pkgCascades == null)
                _pkgCascades = EnumSet.noneOf(CascadeType.class);
            cascades = _pkgCascades;
            puDefault = true;
        }
        boolean all = ELEM_CASCADE_ALL == tag;
        if (all || ELEM_CASCADE_PER == tag) {
            cascades.add(PERSIST);
            if (puDefault) {
                MetaDataDefaults mdd = _repos.getMetaDataFactory().getDefaults();
                mdd.setDefaultCascadePersistEnabled(true);
            }
        }
            
        if (all || ELEM_CASCADE_REM == tag)
            cascades.add(REMOVE);
        if (all || ELEM_CASCADE_MER == tag)
            cascades.add(MERGE);
        if (all || ELEM_CASCADE_REF == tag)
            cascades.add(REFRESH);
        if (all || ELEM_CASCADE_DET == tag)
            cascades.add(DETACH);
        return true;
    }

    /**
     * Set the cached cascades into the field.
     */
    protected void setCascades(FieldMetaData fmd) {
        Set<CascadeType> cascades = _cascades;
        if (_cascades == null)
            cascades = _pkgCascades;
        if (cascades == null)
            return;

        ValueMetaData vmd = fmd;
        if (_strategy == ONE_MANY || _strategy == MANY_MANY) {
            vmd = fmd.getElement();
        }
        for (CascadeType cascade : cascades) {
            switch (cascade) {
                case PERSIST:
                    vmd.setCascadePersist(ValueMetaData.CASCADE_IMMEDIATE, false);
                    break;
                case MERGE:
                    vmd.setCascadeAttach(ValueMetaData.CASCADE_IMMEDIATE);
                    break;
                case DETACH:
                    vmd.setCascadeDetach(ValueMetaData.CASCADE_IMMEDIATE);
                    break;
                case REMOVE:
                    vmd.setCascadeDelete(ValueMetaData.CASCADE_IMMEDIATE);
                    break;
                case REFRESH:
                    vmd.setCascadeRefresh(ValueMetaData.CASCADE_IMMEDIATE);
                    break;
            }
        }
        _cascades = null;
    }

    /**
     * Parse common field attributes.
     */
    private FieldMetaData parseField(Attributes attrs)
        throws SAXException {
        ClassMetaData meta = (ClassMetaData) currentElement();
        String name = attrs.getValue("name");
        FieldMetaData field = meta.getDeclaredField(name);
        int fldAccess = getFieldAccess(field, attrs);
        // If the access defined in XML is not the same as what was defined
        // by default or annotation, find the appropriate backing member and
        // replace what is currently defined in metadata.
        if ((field == null || field.getDeclaredType() == Object.class ||
             field.getAccessType() != fldAccess)
            && meta.getDescribedType() != Object.class) {
            Member member = _repos.getMetaDataFactory().getDefaults()
     	        .getMemberByProperty(meta, name, fldAccess, false);
            Class<?> type = Field.class.isInstance(member) ?
                ((Field)member).getType() : ((Method)member).getReturnType();

            if (field == null) {
                field = meta.addDeclaredField(name, type);
                PersistenceMetaDataDefaults.setCascadeNone(field);
                PersistenceMetaDataDefaults.setCascadeNone(field.getKey());
                PersistenceMetaDataDefaults.setCascadeNone(field.getElement());
            }
            field.backingMember(member);
        } else if (field == null) {
            field = meta.addDeclaredField(name, Object.class);
            PersistenceMetaDataDefaults.setCascadeNone(field);
            PersistenceMetaDataDefaults.setCascadeNone(field.getKey());
            PersistenceMetaDataDefaults.setCascadeNone(field.getElement());
        }

        if (isMetaDataMode())
            field.setListingIndex(_fieldPos);

        _fieldPos++;
        pushElement(field);
        addComments(field);

        if (isMappingOverrideMode())
            startFieldMapping(field, attrs);
        return field;
    }

    /**
     * Pops field element.
     */
    private void finishField()
        throws SAXException {
        FieldMetaData field = (FieldMetaData) popElement();
        setCascades(field);
        if (isMappingOverrideMode())
            endFieldMapping(field);
        _strategy = null;
    }

    /**
     * Determines access for field based upon existing metadata and XML
     * attributes.
     *
     * @param field FieldMetaData current metadata for field
     * @param attrs XML Attributes defined on this field
     */
    private int getFieldAccess(FieldMetaData field, Attributes attrs) {
        if (attrs != null) {
            String access = attrs.getValue("access");
            if ("PROPERTY".equals(access))
                return AccessCode.EXPLICIT | AccessCode.PROPERTY;
            if ("FIELD".equals(access))
                return AccessCode.EXPLICIT | AccessCode.FIELD;
        }
        // Check access defined on field, if provided
        if (field != null) {
            return field.getAccessType();
        }
        // Otherwise, get the default access type of the declaring class
        ClassMetaData meta = (ClassMetaData) currentElement();
        if (meta != null) {
            return AccessCode.toFieldCode(meta.getAccessType());
        }
        return AccessCode.UNKNOWN;
    }

    /**
     * Implement to add field mapping data. Does nothing by default.
     */
    protected void startFieldMapping(FieldMetaData field, Attributes attrs)
        throws SAXException {
    }

    /**
     * Implement to finalize field mapping. Does nothing by default.
     */
    protected void endFieldMapping(FieldMetaData field)
        throws SAXException {
    }

    /**
     * Parse version.
     */
    protected boolean startVersion(Attributes attrs)
        throws SAXException {
        FieldMetaData fmd = parseField(attrs);
        fmd.setExplicit(true);
        fmd.setVersion(true);
        return true;
    }

    protected void endVersion()
        throws SAXException {
        finishField();
    }

    /**
     * Parse strategy element.
     */
    private boolean startStrategy(PersistenceStrategy strategy,
        Attributes attrs)
        throws SAXException {
        FieldMetaData fmd = parseField(attrs);
        fmd.setExplicit(true);
        fmd.setManagement(FieldMetaData.MANAGE_PERSISTENT);

        String val = attrs.getValue("optional");
        if ("false".equals(val))
            fmd.setNullValue(FieldMetaData.NULL_EXCEPTION);
        else if ("true".equals(val)
                && fmd.getNullValue() == FieldMetaData.NULL_EXCEPTION) {
            // Reset value if the field was annotated with optional=false.
            // Otherwise leave it alone.
            fmd.setNullValue(FieldMetaData.NULL_UNSET);
        }
        if (isMappingOverrideMode()) {
            val = attrs.getValue("mapped-by");
            if (val != null)
                fmd.setMappedBy(val);
        }
        parseStrategy(fmd, strategy, attrs);
        return true;
    }

    private void endStrategy(PersistenceStrategy strategy)
        throws SAXException {
        finishField();
    }

    /**
     * Parse strategy specific attributes.
     */
    private void parseStrategy(FieldMetaData fmd,
        PersistenceStrategy strategy, Attributes attrs)
        throws SAXException {
        switch (strategy) {
            case BASIC:
                parseBasic(fmd, attrs);
                break;
            case EMBEDDED:
                parseEmbedded(fmd, attrs);
                break;
            case ONE_ONE:
                parseOneToOne(fmd, attrs);
                break;
            case MANY_ONE:
                parseManyToOne(fmd, attrs);
                break;
            case MANY_MANY:
                parseManyToMany(fmd, attrs);
                break;
            case ONE_MANY:
                parseOneToMany(fmd, attrs);
                break;
            case TRANSIENT:
                String val = attrs.getValue("fetch");
                if (val != null) {
                    fmd.setInDefaultFetchGroup("EAGER".equals(val));
                }
                fmd.setManagement(FieldMetaData.MANAGE_NONE);
                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;
        }
    }

    /**
     * Parse basic.
     */
    protected void parseBasic(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        String val = attrs.getValue("fetch");
        if (val != null) {
            fmd.setInDefaultFetchGroup("EAGER".equals(val));
        }
    }

    /**
     * Parse embedded.
     */
    protected void parseEmbedded(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        assertPC(fmd, "Embedded");
        fmd.setInDefaultFetchGroup(true);
        fmd.setEmbedded(true);
        fmd.setSerialized(false); // override any Lob annotation

        if (fmd.getEmbeddedMetaData() == null)
//            fmd.addEmbeddedMetaData();
            deferEmbeddable(fmd.getDeclaredType(), fmd);
    }

    /**
     * Throw proper exception if given value is not possibly persistence
     * capable.
     */
    private void assertPC(FieldMetaData fmd, String attr)
        throws SAXException {
        if (!JavaTypes.maybePC(fmd))
            throw getException(_loc.get("bad-meta-anno", fmd, attr));
    }

    /**
     * Parse one-to-one.
     */
    protected void parseOneToOne(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        String val = attrs.getValue("fetch");
        boolean dfg = (val != null && val.equals("LAZY")) ? false : true;
        
        // We need to toggle the DFG explicit flag here because this is used for an optimization when selecting an
        // Entity with lazy fields. 
        fmd.setDefaultFetchGroupExplicit(true);
        fmd.setInDefaultFetchGroup(dfg);
        fmd.setDefaultFetchGroupExplicit(false);
        
        val = attrs.getValue("target-entity");
        if (val != null)
            fmd.setTypeOverride(AnnotationPersistenceMetaDataParser.toOverrideType(classForName(val)));
        assertPC(fmd, "OneToOne");
        fmd.setSerialized(false); // override any Lob annotation
        boolean orphanRemoval = Boolean.valueOf(attrs.getValue(
            "orphan-removal"));
        setOrphanRemoval(fmd, orphanRemoval);
        String mapsId = attrs.getValue("maps-id");
        if (mapsId != null)
            fmd.setMappedByIdValue(mapsId);
    }

    /**
     * Parse many-to-one.
     */
    protected void parseManyToOne(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        String val = attrs.getValue("fetch");
        boolean dfg = (val != null && val.equals("LAZY")) ? false : true;
        
        // We need to toggle the DFG explicit flag here because this is used for an optimization when selecting an
        // Entity with lazy fields. 
        fmd.setDefaultFetchGroupExplicit(true);
        fmd.setInDefaultFetchGroup(dfg);
        fmd.setDefaultFetchGroupExplicit(false);
        
        val = attrs.getValue("target-entity");
        if (val != null)
            fmd.setTypeOverride(AnnotationPersistenceMetaDataParser.toOverrideType(classForName(val)));
        assertPC(fmd, "ManyToOne");
        fmd.setSerialized(false); // override any Lob annotation
        String mapsId = attrs.getValue("maps-id");
        if (mapsId != null)
            fmd.setMappedByIdValue(mapsId);
    }

    /**
     * Parse many-to-many.
     */
    protected void parseManyToMany(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        String val = attrs.getValue("fetch");
        if (val != null) {
            fmd.setInDefaultFetchGroup("EAGER".equals(val));
        }
        val = attrs.getValue("target-entity");
        if (val != null)
            fmd.getElement().setDeclaredType(classForName(val));
        assertPCCollection(fmd, "ManyToMany");
        fmd.setSerialized(false); // override Lob in annotation
    }

    /**
     * Throw exception if given field not a collection of possible persistence
     * capables.
     */
    private void assertPCCollection(FieldMetaData fmd, String attr)
        throws SAXException {
        switch (fmd.getDeclaredTypeCode()) {
            case JavaTypes.ARRAY:
            case JavaTypes.COLLECTION:
            case JavaTypes.MAP:
                if (JavaTypes.maybePC(fmd.getElement()))
                    break;
                // no break
            default:
                throw getException(_loc.get("bad-meta-anno", fmd, attr));
        }
    }

    /**
     * Parse one-to-many.
     */
    protected void parseOneToMany(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        String val = attrs.getValue("fetch");
        if (val != null) {
            fmd.setInDefaultFetchGroup("EAGER".equals(val));
        }
        val = attrs.getValue("target-entity");
        if (val != null)
            fmd.getElement().setDeclaredType(classForName(val));
        assertPCCollection(fmd, "OneToMany");
        fmd.setSerialized(false); // override any Lob annotation
        boolean orphanRemoval = Boolean.valueOf(attrs.getValue(
            "orphan-removal"));
        setOrphanRemoval(fmd.getElement(), orphanRemoval);
    }

    protected void setOrphanRemoval(ValueMetaData vmd, boolean orphanRemoval) {
        if (orphanRemoval)
            vmd.setCascadeDelete(ValueMetaData.CASCADE_AUTO);
    }

    protected void parseElementCollection(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        String val = attrs.getValue("target-class");
        if (val != null)
            fmd.getElement().setDeclaredType(classForName(val));

        if (fmd.getDeclaredTypeCode() != JavaTypes.COLLECTION &&
            fmd.getDeclaredTypeCode() != JavaTypes.MAP)
            throw getException(_loc.get("bad-meta-anno", fmd,
                    "ElementCollection"));

        val = attrs.getValue("fetch");
        if (val != null)
            fmd.setInDefaultFetchGroup("EAGER".equals(val));
        fmd.setElementCollection(true);
        fmd.setSerialized(false);
        if (JavaTypes.maybePC(fmd.getElement()) && !fmd.getElement().getDeclaredType().isEnum()) {
            fmd.getElement().setEmbedded(true);
            if (fmd.getElement().getEmbeddedMetaData() == null)
//                fmd.getElement().addEmbeddedMetaData();
                deferEmbeddable(fmd.getElement().getDeclaredType(),
                    fmd.getElement());
        }
    }

    /**
     * Parse map-key.
     */
    private boolean startMapKey(Attributes attrs)
        throws SAXException {
        if (!isMappingOverrideMode())
            return false;

        FieldMetaData fmd = (FieldMetaData) currentElement();
        String mapKey = attrs.getValue("name");
        if (mapKey == null)
            fmd.getKey().setValueMappedBy(ValueMetaData.MAPPED_BY_PK);
        else
            fmd.getKey().setValueMappedBy(mapKey);
        return true;
    }


    /**
     * Parse map-key-class.
     */
    private boolean startMapKeyClass(Attributes attrs)
    throws SAXException {
        if (!isMappingOverrideMode())
            return false;

        FieldMetaData fmd = (FieldMetaData) currentElement();
        String mapKeyClass = attrs.getValue("class");

        if (mapKeyClass != null) {
            try {
                fmd.getKey().setDeclaredType(Class.forName(mapKeyClass));
            } catch (ClassNotFoundException e) {
                throw new IllegalArgumentException("Class not found");
            }
        } else
            throw new IllegalArgumentException(
            "The value of the MapKeyClass cannot be null");
        return true;
    }

    /**
     * Parse order-by.
     */
    private void endOrderBy()
        throws SAXException {
        FieldMetaData fmd = (FieldMetaData) currentElement();
        String dec = currentText();
        if (fmd.isElementCollection() &&
            fmd.getElement().getEmbeddedMetaData() != null ||
            isDeferredEmbeddable(fmd.getElement().getDeclaredType(),
                fmd.getElement())) {
            if (dec.length() == 0 || dec.equals("ASC") ||
                dec.equals("DESC"))
                throw new MetaDataException(_loc.get(
                    "invalid-orderBy", fmd));
        }
        if (StringUtil.isEmpty(dec) || dec.equals("ASC"))
            dec = Order.ELEMENT + " asc";
        else if (dec.equals("DESC"))
            dec = Order.ELEMENT + " desc";

        fmd.setOrderDeclaration(dec);
    }

    /**
     * Parse named-query.
     */
    protected boolean startNamedQuery(Attributes attrs)
        throws SAXException {
        if (!isQueryMode())
            return false;

        String name = attrs.getValue("name");
        Log log = getLog();
        if (log.isTraceEnabled())
            log.trace(_loc.get("parse-query", name));

        QueryMetaData meta = getRepository().searchQueryMetaDataByName(name);
        if (meta != null) {
        	Class<?> defType = meta.getDefiningType();
            if ((defType != _cls) && log.isWarnEnabled()) {
                log.warn(_loc.get("dup-query", name, currentLocation(),
            	        defType));
            }
            pushElement(meta);
            return true;
        }

        meta = getRepository().addQueryMetaData(null, name);
        meta.setDefiningType(_cls);
        meta.setLanguage(JPQLParser.LANG_JPQL);
        meta.setQueryString(attrs.getValue("query"));
        String lockModeStr = attrs.getValue("lock-mode");
        LockModeType lmt = processNamedQueryLockModeType(log, lockModeStr, name);
        if (lmt != null && lmt != LockModeType.NONE) {
            meta.addHint("openjpa.FetchPlan.ReadLockMode", lmt);
        }
        Locator locator = getLocation().getLocator();
        if (locator != null) {
            meta.setLineNumber(locator.getLineNumber());
            meta.setColNumber(locator.getColumnNumber());
        }
        Object cur = currentElement();
        Object scope = (cur instanceof ClassMetaData)
            ? ((ClassMetaData) cur).getDescribedType() : null;
        meta.setSource(getSourceFile(), scope, SourceTracker.SRC_XML, locator == null ? "" : locator.getSystemId());
        if (isMetaDataMode())
            meta.setSourceMode(MODE_META);
        else if (isMappingMode())
            meta.setSourceMode(MODE_MAPPING);
        else
            meta.setSourceMode(MODE_QUERY);
        pushElement(meta);
        return true;
    }
    
    /**
     * A private worker method that calculates the lock mode for an individual NamedQuery. If the NamedQuery is 
     * configured to use the NONE lock mode(explicit or implicit), this method will promote the lock to a READ
     * level lock. This was done to allow for JPA1 apps to function properly under a 2.0 runtime. 
     */
    private LockModeType processNamedQueryLockModeType(Log log, String lockModeString, String queryName) {
        if (lockModeString == null) {
            return null;
        }
        LockModeType lmt = LockModeType.valueOf(lockModeString);
        String lm = _conf.getLockManager();
        boolean optimistic = _conf.getOptimistic();
        if (lm != null) {
            lm = lm.toLowerCase();
            if (lm.contains("pessimistic")) {
                if (lmt == LockModeType.NONE && !optimistic) {
                    if (log != null && log.isWarnEnabled() == true) {
                        log.warn(_loc.get("override-named-query-lock-mode", new String[] { "xml", queryName,
                            _cls.getName() }));
                    }
                    lmt = LockModeType.READ;
                }
            }
        }

        return lmt;
    }

    protected void endNamedQuery()
        throws SAXException {
        popElement();
    }

    protected boolean startQueryString(Attributes attrs)
        throws SAXException {
        return true;
    }

    protected void endQueryString()
        throws SAXException {
        QueryMetaData meta = (QueryMetaData) currentElement();
        meta.setQueryString(currentText());
    }

    /**
     * Parse query-hint.
     */
    protected boolean startQueryHint(Attributes attrs)
        throws SAXException {
        QueryMetaData meta = (QueryMetaData) currentElement();
        meta.addHint(attrs.getValue("name"), attrs.getValue("value"));
        return true;
    }

    protected void endQueryHint()
        throws SAXException {
    }

    /**
     * Parse native-named-query.
     */
    protected boolean startNamedNativeQuery(Attributes attrs)
        throws SAXException {
        if (!isQueryMode())
            return false;

        String name = attrs.getValue("name");
        Log log = getLog();
        if (log.isTraceEnabled())
            log.trace(_loc.get("parse-native-query", name));

        QueryMetaData meta = getRepository().getCachedQueryMetaData(name);
        if (meta != null && isDuplicateQuery(meta) ) {
            log.warn(_loc.get("override-query", name, currentLocation()));
        }

        meta = getRepository().addQueryMetaData(null, name);
        meta.setDefiningType(_cls);
        meta.setLanguage(QueryLanguages.LANG_SQL);
        meta.setQueryString(attrs.getValue("query"));
        String val = attrs.getValue("result-class");
        if (val != null) {
            Class<?> type = classForName(val);
            if (ImplHelper.isManagedType(getConfiguration(), type))
                meta.setCandidateType(type);
            else
                meta.setResultType(type);
        }

        val = attrs.getValue("result-set-mapping");
        if (val != null)
            meta.setResultSetMappingName(val);

        Object cur = currentElement();
        Object scope = (cur instanceof ClassMetaData) ? ((ClassMetaData) cur).getDescribedType() : null;
        Locator locator = getLocation().getLocator();
        meta.setSource(getSourceFile(), scope, SourceTracker.SRC_XML, locator == null ? "" : locator.getSystemId());
        if (locator != null) {
            meta.setLineNumber(locator.getLineNumber());
            meta.setColNumber(locator.getColumnNumber());
        }
        if (isMetaDataMode())
            meta.setSourceMode(MODE_META);
        else if (isMappingMode())
            meta.setSourceMode(MODE_MAPPING);
        else
            meta.setSourceMode(MODE_QUERY);
        pushElement(meta);
        return true;
    }

    protected void endNamedNativeQuery()
        throws SAXException {
        popElement();
    }

    /**
     * Start entity-listeners
     */
    private boolean startEntityListeners(Attributes attrs)
        throws SAXException {
        if (!isMetaDataMode())
            return false;
        if (currentElement() == null)
            return true;

        // reset listeners declared in annotations.
        LifecycleMetaData meta = ((ClassMetaData) currentElement()).
            getLifecycleMetaData();
        for (int i = 0; i < LifecycleEvent.ALL_EVENTS.length; i++)
            meta.setDeclaredCallbacks(i, null, 0);
        return true;
    }

    /**
     * Parse exclude-default-listeners.
     */
    private boolean startExcludeDefaultListeners(Attributes attrs)
        throws SAXException {
        if (!isMetaDataMode())
            return false;
        ClassMetaData meta = (ClassMetaData) currentElement();
        meta.getLifecycleMetaData().setIgnoreSystemListeners(true);
        return true;
    }

    /**
     * Parse exclude-superclass-listeners.
     */
    private boolean startExcludeSuperclassListeners(Attributes attrs)
        throws SAXException {
        if (!isMetaDataMode())
            return false;
        ClassMetaData meta = (ClassMetaData) currentElement();
        meta.getLifecycleMetaData().setIgnoreSuperclassCallbacks
            (LifecycleMetaData.IGNORE_HIGH);
        return true;
    }

    /**
     * Parse entity-listener.
     */
    private boolean startEntityListener(Attributes attrs)
        throws SAXException {
        _listener = classForName(attrs.getValue("class"));
        if (!_conf.getCallbackOptionsInstance().getAllowsDuplicateListener()) {
            if (_listeners == null)
                _listeners = new ArrayList<Class<?>>();
            if (_listeners.contains(_listener)) 
                return true;
            _listeners.add(_listener);    
        }
            
        boolean system = currentElement() == null;
        Collection<LifecycleCallbacks>[] parsed =
            AnnotationPersistenceMetaDataParser.parseCallbackMethods(_listener,
                null, true, true, _repos);
        if (parsed == null)
            return true;

        if (_callbacks == null) {
            _callbacks = (Collection<LifecycleCallbacks>[])
                new Collection[LifecycleEvent.ALL_EVENTS.length];
            if (!system)
                _highs = new int[LifecycleEvent.ALL_EVENTS.length];
        }
        for (int i = 0; i < parsed.length; i++) {
            if (parsed[i] == null)
                continue;
            if (_callbacks[i] == null)
                _callbacks[i] = parsed[i];
            else
                _callbacks[i].addAll(parsed[i]);
            if (!system)
                _highs[i] += parsed[i].size();
        }
        return true;
    }

    private void endEntityListener()
        throws SAXException {
        // should be in endEntityListeners I think to merge callbacks
        // into a single listener.  But then the user cannot remove.
        if (currentElement() == null && _callbacks != null) {
            _repos.addSystemListener(new PersistenceListenerAdapter
                (_callbacks));
            _callbacks = null;
        }
        _listener = null;
    }

    private boolean startCallback(MetaDataTag callback, Attributes attrs)
        throws SAXException {
        if (!isMetaDataMode())
            return false;
        int[] events = MetaDataParsers.getEventTypes(callback, _conf);
        if (events == null)
            return false;

        boolean system = currentElement() == null;

        // If in a multi-level parse, do not add system level listeners.
        // Otherwise, they will get added multiple times.
        if (system && _parseList != null && _parseList.size() > 0) {
            return false;
        }

        Class<?> type = currentElement() == null ? null :
            ((ClassMetaData) currentElement()).getDescribedType();
        if (type == null)
            type = Object.class;

        if (_callbacks == null) {
            _callbacks = (Collection<LifecycleCallbacks>[])
                new Collection[LifecycleEvent.ALL_EVENTS.length];
            if (!system)
                _highs = new int[LifecycleEvent.ALL_EVENTS.length];
        }

        LifecycleCallbacks adapter;
        if (_listener != null)
            adapter = new BeanLifecycleCallbacks(_listener,
                attrs.getValue("method-name"), false, type);
        else
            adapter = new MethodLifecycleCallbacks(_cls,
                attrs.getValue("method-name"), false);

        for (int i = 0; i < events.length; i++) {
            int event = events[i];
            if (_listener != null) {
                MetaDataParsers.validateMethodsForSameCallback(_listener,
                    _callbacks[event], ((BeanLifecycleCallbacks) adapter).
                    getCallbackMethod(), callback, _conf, getLog());
            } else {
                MetaDataParsers.validateMethodsForSameCallback(_cls,
                    _callbacks[event], ((MethodLifecycleCallbacks) adapter).
                    getCallbackMethod(), callback, _conf, getLog());

            }
            if (_callbacks[event] == null)
                _callbacks[event] = new ArrayList<LifecycleCallbacks>(3);
            _callbacks[event].add(adapter);
            if (!system && _listener != null)
                _highs[event]++;
        }
        return true;
    }

    /**
     * Store lifecycle metadata.
     */
    private void storeCallbacks(ClassMetaData cls) {
        LifecycleMetaData meta = cls.getLifecycleMetaData();
        Class<?> supCls = cls.getDescribedType().getSuperclass();
        Collection<LifecycleCallbacks>[] supCalls = null;
        if (!Object.class.equals(supCls)) {
            supCalls = AnnotationPersistenceMetaDataParser.parseCallbackMethods
                (supCls, null, true, false, _repos);
        }
        if (supCalls != null) {
            for (int event : LifecycleEvent.ALL_EVENTS) {
                if (supCalls[event] == null)
                    continue;
                meta.setNonPCSuperclassCallbacks(event, supCalls[event].toArray
                    (new LifecycleCallbacks[supCalls[event].size()]), 0);
            }
        }
        if (_callbacks == null)
            return;

        for (int event : LifecycleEvent.ALL_EVENTS) {
            if (_callbacks[event] == null)
                continue;
            meta.setDeclaredCallbacks(event, (LifecycleCallbacks[])
                _callbacks[event].toArray
                    (new LifecycleCallbacks[_callbacks[event].size()]),
                _highs[event]);
        }
        _callbacks = null;
        _highs = null;
    }

    protected boolean startOrderColumn(Attributes attrs)
        throws SAXException {
        return true;
    }

    /**
     * Instantiate the given class, taking into account the default package.
	 */
	protected Class<?> classForName(String name)
		throws SAXException {
		if ("Entity".equals(name))
			return PersistenceCapable.class;
		return super.classForName(name, isRuntime());
	}

	/**
	 * Process all deferred embeddables using an unknown access type.
	 */
	protected void addDeferredEmbeddableMetaData() {
	    if (_embeddables != null && _embeddables.size() > 0) {
	        // Reverse iterate the array of remaining deferred embeddables
	        // since elements will be removed as they are processed.
	        Class<?>[] classes = _embeddables.keySet().toArray(
	            new Class<?>[_embeddables.size()]);
	        for (int i = classes.length - 1 ; i >= 0; i--) {
	            try {
	                Integer access = _embeddableAccess.get(classes[i]);
	                if (access == null) {
	                    access = AccessCode.UNKNOWN;
	                }
	                addDeferredEmbeddableMetaData(classes[i],
	                    access);
	            }
	            catch (Exception e) {
	                throw new MetaDataException(
	                    _loc.get("no-embeddable-metadata",
	                        classes[i].getName()), e);
	            }
	        }
	    }	
	}
	
    /**
     * Process all deferred embeddables and embeddable mapping overrides
     * for a given class.  This should only happen after the access type
     * of the embeddable is known.
     *
     * @param embedType embeddable class
     * @param access class level access for embeddable
     * @throws SAXException
     */
    protected void addDeferredEmbeddableMetaData(Class<?> embedType,
        int access) throws SAXException {
        ArrayList<MetaDataContext> fmds = _embeddables.get(embedType);
        if (fmds != null && fmds.size() > 0) {
            for (MetaDataContext md : fmds) {
                if (md instanceof FieldMetaData) {
                    FieldMetaData fmd = (FieldMetaData)md;
                    fmd.addEmbeddedMetaData(access);
                }
                else if (md instanceof ValueMetaData) {
                    ValueMetaData vmd = (ValueMetaData)md;
                    vmd.addEmbeddedMetaData(access);
                }
            }
            applyDeferredEmbeddableOverrides(embedType);
            // Clean up deferrals after they have been processed
            fmds.clear();
            _embeddables.remove(embedType);
        }
    }
    protected void setDeferredEmbeddableAccessType(Class<?> embedType,
        int access) {
        _embeddableAccess.put(embedType, access);
    }

    /*
     * Clear any deferred metadata
     */
    @Override
    protected void clearDeferredMetaData() {
        _embeddables.clear();
        _embeddableAccess.clear();
    }

    /*
     * Determines whether the embeddable type is deferred.
     */
    protected boolean isDeferredEmbeddable(Class<?> embedType,
        MetaDataContext fmd) {
        ArrayList<MetaDataContext> fmds = _embeddables.get(embedType);
        if (fmds != null) {
            return fmds.contains(fmd);
        }
        return false;
    }

    /*
     * Add the fmd to the defer list for for the given embeddable type
     */
    protected void deferEmbeddable(Class<?> embedType, MetaDataContext fmd) {
        ArrayList<MetaDataContext> fmds = _embeddables.get(embedType);
        if (fmds == null) {
            fmds = new ArrayList<MetaDataContext>();
            _embeddables.put(embedType, fmds);
        }
        fmds.add(fmd);
    }

    /*
     * Apply any deferred overrides.
     */
    protected void applyDeferredEmbeddableOverrides(Class<?> cls)
        throws SAXException {
    }

	/*
	 * Add the array of classes to the active parse list.
	 */
    public void addToParseList(ArrayList<Class<?>> parseList) {
        if (parseList == null)
            return;
        _parseList.addAll(parseList);
    }

    /*
     * Add the class to the active parse list.
     */
    public void addToParseList(Class<?> parentCls) {
        if (parentCls == null)
            return;
        _parseList.add(parentCls);
    }

    /*
     * Whether the active parse list contains the specified class.
     */
    public boolean parseListContains(Class<?> cls) {
        if (_parseList.size() == 0)
            return false;
        return _parseList.contains(cls);
    }

    /*
     * Returns the list of classes actively being parsed.
     */
    public ArrayList<Class<?>> getParseList() {
        return _parseList;
    }

    /*
     * Returns class currently being parsed.
     */
    public Class<?> getParseClass() {
        return _cls;
    }

    protected boolean startDelimitedIdentifiers() {
        return false;
    }
    
    protected String normalizeSequenceName(String seqName) {
        return seqName;
    }

    protected String normalizeSchemaName(String schName) {
        return schName;
    }

    protected String normalizeCatalogName(String catName) {
        return catName;
    }

    /**
     * Determines whether the ClassMetaData has been resolved more than once. Compares the current sourceName and
     * linenumber to the ones used to originally resolve the metadata.
     * 
     * @param meta The ClassMetaData to inspect.
     * @return true if the source was has already been resolved from a different location. Otherwise return false
     */
    protected boolean isDuplicateClass(ClassMetaData meta) {
        if (!Objects.equals(getSourceName(), meta.getSourceName())) {
            return true;
        }

        if (getLineNum() != meta.getLineNumber()) {
            return true;
        }
        return false;
    }
    
    /**
     * Determines whether the QueryMetaData has been resolved more than once.
     * @param meta QueryMetaData that has already been resolved. 
     * @return true if the QueryMetaData was defined in a different place - e.g. another line in orm.xml.
     */
    protected boolean isDuplicateQuery(QueryMetaData meta) { 
        if(! Objects.equals(getSourceName(), meta.getSourceName())) {
            return true;
        }
        if(getLineNum() != meta.getLineNumber()) { 
            return true;
        }
        return false; 
            
    }
    
    private int getLineNum() { 
        int lineNum = 0;
        Locator loc = getLocation().getLocator();
        if(loc != null ) {
            lineNum = loc.getLineNumber();
        }
        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 (StringUtil.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) (StringUtil.isEmpty(enabledStr) ? true :
            Boolean.parseBoolean(enabledStr));
        
        String timeoutStr = attrs.getValue("timeout");
        int timeout = (Integer) (StringUtil.isEmpty(timeoutStr) ? Integer.MIN_VALUE :
            Integer.parseInt(timeoutStr));
        
        String name = attrs.getValue("name");
        name = StringUtil.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
        String val = attrs.getValue("fetch");
        if (val != null) {
            fmd.setInDefaultFetchGroup("EAGER".equals(val));
        }

        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 (!StringUtil.isEmpty(loadFetchGroup)) {
            fmd.setLoadFetchGroup(loadFetchGroup);
        }
        
        String externalizer = attrs.getValue("externalizer");
        if (!StringUtil.isEmpty(externalizer)) {
            fmd.setExternalizer(externalizer);
        }
        
        String factory = attrs.getValue("factory");
        if (!StringUtil.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 (!StringUtil.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 (!StringUtil.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 (!StringUtil.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 (!StringUtil.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 (!StringUtil.isEmpty(typeStr)) {
            if (StringUtil.endsWithIgnoreCase(typeStr, ".class")) {
                typeStr = typeStr.substring(0, typeStr.lastIndexOf('.'));
            }
            Class<?> typeCls = parseTypeStr(typeStr);

            fmd.setTypeOverride(typeCls);
        }
    }
    
    private void parseLRSAttr(FieldMetaData fmd, Attributes attrs)
        throws SAXException {
        String lrsStr = attrs.getValue("lrs");
        if (!StringUtil.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 (!StringUtil.isEmpty(typeStr)) {
            if (StringUtil.endsWithIgnoreCase(typeStr, ".class")) {
                typeStr = typeStr.substring(0, typeStr.lastIndexOf('.'));
            }
            Class<?> typeCls = parseTypeStr(typeStr);

            fmd.setTypeOverride(typeCls);
        }
    }
    
    private void parseKeyTypeAttr(FieldMetaData fmd, Attributes attrs)
        throws SAXException {

        String typeStr = attrs.getValue("key-type");
        if (!StringUtil.isEmpty(typeStr)) {
            if (StringUtil.endsWithIgnoreCase(typeStr, ".class")) {
                typeStr = typeStr.substring(0, typeStr.lastIndexOf('.'));
            }
            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 (!StringUtil.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;
        }
    }
}
