/*
 * 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 static javax.persistence.CascadeType.DETACH;
import static javax.persistence.CascadeType.MERGE;
import static javax.persistence.CascadeType.PERSIST;
import static javax.persistence.CascadeType.REFRESH;
import static javax.persistence.CascadeType.REMOVE;
import static org.apache.openjpa.meta.MetaDataModes.MODE_MAPPING;
import static org.apache.openjpa.meta.MetaDataModes.MODE_META;
import static org.apache.openjpa.meta.MetaDataModes.MODE_NONE;
import static org.apache.openjpa.meta.MetaDataModes.MODE_QUERY;
import static org.apache.openjpa.persistence.MetaDataTag.DATASTORE_ID;
import static org.apache.openjpa.persistence.MetaDataTag.DATA_CACHE;
import static org.apache.openjpa.persistence.MetaDataTag.EMBEDDED_ID;
import static org.apache.openjpa.persistence.MetaDataTag.ENTITY_LISTENERS;
import static org.apache.openjpa.persistence.MetaDataTag.EXCLUDE_DEFAULT_LISTENERS;
import static org.apache.openjpa.persistence.MetaDataTag.EXCLUDE_SUPERCLASS_LISTENERS;
import static org.apache.openjpa.persistence.MetaDataTag.EXTERNALIZER;
import static org.apache.openjpa.persistence.MetaDataTag.EXTERNAL_VAL;
import static org.apache.openjpa.persistence.MetaDataTag.EXTERNAL_VALS;
import static org.apache.openjpa.persistence.MetaDataTag.FACTORY;
import static org.apache.openjpa.persistence.MetaDataTag.FETCH_ATTRIBUTE;
import static org.apache.openjpa.persistence.MetaDataTag.FETCH_GROUP;
import static org.apache.openjpa.persistence.MetaDataTag.FETCH_GROUPS;
import static org.apache.openjpa.persistence.MetaDataTag.FLUSH_MODE;
import static org.apache.openjpa.persistence.MetaDataTag.GENERATED_VALUE;
import static org.apache.openjpa.persistence.MetaDataTag.ID;
import static org.apache.openjpa.persistence.MetaDataTag.ID_CLASS;
import static org.apache.openjpa.persistence.MetaDataTag.LOB;
import static org.apache.openjpa.persistence.MetaDataTag.MAPPED_BY_ID;
import static org.apache.openjpa.persistence.MetaDataTag.MAP_KEY;
import static org.apache.openjpa.persistence.MetaDataTag.MAP_KEY_CLASS;
import static org.apache.openjpa.persistence.MetaDataTag.NATIVE_QUERY;
import static org.apache.openjpa.persistence.MetaDataTag.OPENJPA_VERSION;
import static org.apache.openjpa.persistence.MetaDataTag.ORDER_BY;
import static org.apache.openjpa.persistence.MetaDataTag.ORDER_COLUMN;
import static org.apache.openjpa.persistence.MetaDataTag.POST_LOAD;
import static org.apache.openjpa.persistence.MetaDataTag.POST_PERSIST;
import static org.apache.openjpa.persistence.MetaDataTag.POST_REMOVE;
import static org.apache.openjpa.persistence.MetaDataTag.POST_UPDATE;
import static org.apache.openjpa.persistence.MetaDataTag.PRE_PERSIST;
import static org.apache.openjpa.persistence.MetaDataTag.PRE_REMOVE;
import static org.apache.openjpa.persistence.MetaDataTag.PRE_UPDATE;
import static org.apache.openjpa.persistence.MetaDataTag.QUERY;
import static org.apache.openjpa.persistence.MetaDataTag.QUERY_HINT;
import static org.apache.openjpa.persistence.MetaDataTag.QUERY_STRING;
import static org.apache.openjpa.persistence.MetaDataTag.READ_ONLY;
import static org.apache.openjpa.persistence.MetaDataTag.REFERENCED_FETCH_GROUP;
import static org.apache.openjpa.persistence.MetaDataTag.SEQ_GENERATOR;
import static org.apache.openjpa.persistence.MetaDataTag.VERSION;
import static org.apache.openjpa.persistence.PersistenceStrategy.BASIC;
import static org.apache.openjpa.persistence.PersistenceStrategy.ELEM_COLL;
import static org.apache.openjpa.persistence.PersistenceStrategy.EMBEDDED;
import static org.apache.openjpa.persistence.PersistenceStrategy.MANY_MANY;
import static org.apache.openjpa.persistence.PersistenceStrategy.MANY_ONE;
import static org.apache.openjpa.persistence.PersistenceStrategy.ONE_MANY;
import static org.apache.openjpa.persistence.PersistenceStrategy.ONE_ONE;
import static org.apache.openjpa.persistence.PersistenceStrategy.PERS;
import static org.apache.openjpa.persistence.PersistenceStrategy.PERS_COLL;
import static org.apache.openjpa.persistence.PersistenceStrategy.PERS_MAP;
import static org.apache.openjpa.persistence.PersistenceStrategy.TRANSIENT;

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 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.lib.util.StringUtil;
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.MetaDataRepository;
import org.apache.openjpa.meta.Order;
import org.apache.openjpa.meta.QueryMetaData;
import org.apache.openjpa.meta.SequenceMetaData;
import org.apache.openjpa.meta.UpdateStrategies;
import org.apache.openjpa.meta.ValueMetaData;
import org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.FetchAttributeImpl;
import org.apache.openjpa.persistence.AnnotationPersistenceMetaDataParser.FetchGroupImpl;
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<>();

    // Map for storing deferred metadata which needs to be populated
    // after embeddables are loaded.
    private static final Map<Class<?>, ArrayList<MetaDataContext>>
        _embeddables = new HashMap<>();
    private static final Map<Class<?>, Integer>
        _embeddableAccess = new HashMap<>();

    // 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<>();
    private final Stack<Object> _parents = new Stack<>();

    private StringBuffer _externalValues = null;

    protected Class<?> _cls = null;
    // List of classes currently being parsed
    private ArrayList<Class<?>> _parseList = new ArrayList<>();
    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";
    private static final String ORM_XSD_2_1 = "orm_2_1.xsd";
    private static final String ORM_XSD_2_2 = "orm_2_2.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.
     */
    @Override
    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.
     */
    @Override
    public void setMode(int mode) {
        _mode = mode;
        if (_parser != null)
            _parser.setMode(mode);
    }

    @Override
    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);
    }

    @Override
    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 (XMLVersionParser.VERSION_1_0.equals(_ormVersion)
                || (_schemaLocation != null && _schemaLocation.indexOf(ORM_XSD_1_0) > -1)) {
            ormxsd = "orm-xsd.rsrc";
            useExtendedSchema = false;
        } else if (XMLVersionParser.VERSION_2_0.equals(_ormVersion)
                || (_schemaLocation != null && _schemaLocation.indexOf(ORM_XSD_2_0) > -1)) {
            ormxsd = "orm_2_0-xsd.rsrc";
        } else if (XMLVersionParser.VERSION_2_1.equals(_ormVersion)
                || (_schemaLocation != null && _schemaLocation.indexOf(ORM_XSD_2_1) > -1)) {
            ormxsd = "orm_2_1.xsd.rsrc";
        } else if (XMLVersionParser.VERSION_2_2.equals(_ormVersion)
                || (_schemaLocation != null && _schemaLocation.indexOf(ORM_XSD_2_2) > -1)) {
            ormxsd = "orm_2_2.xsd.rsrc";
        }

        List<InputStream> schema = new ArrayList<>();
        schema.add(XMLPersistenceMetaDataParser.class.getResourceAsStream(ormxsd));

        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 (FieldMetaData fmd : fmds) {
                    fmd.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()) {
                        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<>();
            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 event : events) {
            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<>(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.computeIfAbsent(embedType, k -> new ArrayList<>());
        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<>();
        }
        return true;
    }

    private boolean startFetchGroup(Attributes attrs)
        throws SAXException {

        if (_fgList == null) {
            _fgList = new ArrayList<>();
        }
        _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 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<>();
        }

        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;
        }
    }
}
