/*
 * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Denise Smith - 2.5 - initial implementation
package org.eclipse.persistence.internal.oxm.mappings;

import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.xml.namespace.QName;

import org.eclipse.persistence.core.descriptors.CoreInheritancePolicy;
import org.eclipse.persistence.core.mappings.CoreAttributeAccessor;
import org.eclipse.persistence.core.mappings.CoreMapping;
import org.eclipse.persistence.core.queries.CoreAttributeGroup;
import org.eclipse.persistence.internal.core.descriptors.CoreInstantiationPolicy;
import org.eclipse.persistence.internal.core.descriptors.CoreObjectBuilder;
import org.eclipse.persistence.internal.core.helper.CoreField;
import org.eclipse.persistence.internal.core.helper.CoreTable;
import org.eclipse.persistence.internal.oxm.NamespaceResolver;
import org.eclipse.persistence.internal.oxm.Unmarshaller;
import org.eclipse.persistence.internal.oxm.record.UnmarshalRecord;
import org.eclipse.persistence.oxm.schema.XMLSchemaReference;

public interface Descriptor <
    ATTRIBUTE_ACCESSOR extends CoreAttributeAccessor,
    CORE_MAPPING extends CoreMapping,
    FIELD extends CoreField,
    INHERITANCE_POLICY extends CoreInheritancePolicy,
    INSTANTIATION_POLICY extends CoreInstantiationPolicy,
    NAMESPACE_RESOLVER extends NamespaceResolver,
    OBJECT_BUILDER extends CoreObjectBuilder,
    TABLE extends CoreTable,
    UNMARSHAL_RECORD extends UnmarshalRecord,
    UNMARSHALLER extends Unmarshaller> {

    /**
     * Add a database mapping to the receiver. Perform any required
     * initialization of both the mapping and the receiving descriptor
     * as a result of adding the new mapping.
     */
    CORE_MAPPING addMapping(CORE_MAPPING mapping);

    /**
     * ADVANCED:
     * Specify the primary key field of the descriptors table.
     * This should be called for each field that makes up the primary key of the table.
     * This can be used for advanced field types, such as XML nodes, or to set the field type.
     */
    void addPrimaryKeyField(FIELD field);

    /**
        * Add a root element name for the Descriptor
        * This value is stored in place of a table name
        * @param rootElementName a root element to specify on this Descriptor
        */
        void addRootElement(String rootElementName);
    /**
      * Get the alias
      */
     String getAlias();

    /**
      * Return the default root element name for the ClassDescriptor
      * This value is stored in place of a table name
      * This value is mandatory for all root objects
      * @return the default root element specified on this ClassDescriptor
      */
     String getDefaultRootElement();

     QName getDefaultRootElementType();

     Field getDefaultRootElementField();

    /**
     * The inheritance policy is used to define how a descriptor takes part in inheritance.
     * All inheritance properties for both child and parent classes is configured in inheritance policy.
     * Caution must be used in using this method as it lazy initializes an inheritance policy.
     * Calling this on a descriptor that does not use inheritance will cause problems, #hasInheritance() must always first be called.
     */
    INHERITANCE_POLICY getInheritancePolicy();

    /**
     * INTERNAL:
     * Return the inheritance policy.
     */
    INHERITANCE_POLICY getInheritancePolicyOrNull();

    /**
     * INTERNAL:
     * Returns the instantiation policy.
     */
    INSTANTIATION_POLICY getInstantiationPolicy();

    /**
     * Return the java class.
     */
    <T> Class<T> getJavaClass();

    /**
     * Return the class name, used by the MW.
     */
    String getJavaClassName();

    /**
     * INTERNAL:
     * Returns this Descriptor's location accessor, if one is defined.
     */
    ATTRIBUTE_ACCESSOR getLocationAccessor();

     /**
     * Returns the mapping associated with a given attribute name.
     * This can be used to find a descriptors mapping in a amendment method before the descriptor has been initialized.
     */
    CORE_MAPPING getMappingForAttributeName(String attributeName);

     /**
     * Returns mappings
     */
    Vector<CORE_MAPPING> getMappings();


     /**
     * Return the NamespaceResolver associated with this descriptor
     * @return the NamespaceResolver associated with this descriptor
     */
     NAMESPACE_RESOLVER getNamespaceResolver();

     NAMESPACE_RESOLVER getNonNullNamespaceResolver();


     /**
     * INTERNAL:
     * Return the object builder
     */
    OBJECT_BUILDER getObjectBuilder();

     /**
     * Return the names of all the primary keys.
     */
    Vector<String> getPrimaryKeyFieldNames();

     /**
     * INTERNAL:
     * Return all the primary key fields
     */
    List<FIELD> getPrimaryKeyFields();

     /**
      * Return the SchemaReference associated with this descriptor
      * @return the SchemaReference associated with this descriptor
      * @see org.eclipse.persistence.oxm.schema
      */
      XMLSchemaReference getSchemaReference();

     /**
      * Return the table names.
      */
     Vector getTableNames();

     /**
      * INTERNAL:
      * Return all the tables.
      */
     Vector<TABLE> getTables();

     /**
      * INTERNAL:
      * searches first descriptor than its ReturningPolicy for an equal field
      */
     FIELD getTypedField(FIELD field);


    /**
     * INTERNAL:
     * Return if this descriptor is involved in inheritance, (is child or parent).
     * Note: If this class is part of table per class inheritance strategy this
     * method will return false.
     */
    boolean hasInheritance();
    /**
     * If true, the descriptor may be lazily initialized.  This is useful if the
     * descriptor may not get used.
     */
    boolean isLazilyInitialized();

    boolean isResultAlwaysXMLRoot();

    /**
      * INTERNAL:
      * <p>Indicates if the Object mapped by this descriptor is a sequenced data object
      * and should be marshalled accordingly.
      */
    boolean isSequencedObject();

     boolean isWrapper();

     /**
       * Return the default root element name for the ClassDescriptor
       * This value is stored in place of a table name
       * This value is mandatory for all root objects
       * @param newDefaultRootElement the default root element to specify on this ClassDescriptor
       */
       void setDefaultRootElement(String newDefaultRootElement);

     /**
       * INTERNAL:
       * Sets the instantiation policy.
       */
      void setInstantiationPolicy(INSTANTIATION_POLICY instantiationPolicy);

      /**
      * Set the Java class that this descriptor maps.
      * Every descriptor maps one and only one class.
      */
      void setJavaClass(Class<?> theJavaClass);

      /**
       * INTERNAL:
       * Return the java class name, used by the MW.
       */
      void setJavaClassName(String theJavaClassName);

      /**
     * INTERNAL:
     * Set this Descriptor's location accessor.
     */
    void setLocationAccessor(ATTRIBUTE_ACCESSOR attributeAccessor);

       /**
     * Set the NamespaceResolver to associate with this descriptor
     * @param newNamespaceResolver the NamespaceResolver to associate with this descriptor
     */
     void setNamespaceResolver(NAMESPACE_RESOLVER newNamespaceResolver);

        /**
         * INTERNAL:
         * Set the user defined properties.
         */
        void setProperties(Map properties);

        void setResultAlwaysXMLRoot(boolean resultAlwaysXMLRoot);

        /**
         * Set the SchemaReference to associate with this descriptor
         * @param newSchemaReference the SchemaReference to associate with this descriptor
         * @see org.eclipse.persistence.oxm.schema
         */
        void setSchemaReference(XMLSchemaReference newSchemaReference);

        /**
          * Return if unmapped information from the XML document should be maintained for this
          * descriptor
          * By default unmapped data is not preserved.
          * @return if this descriptor should preserve unmapped data
          */
         boolean shouldPreserveDocument();

        /**
          * INTERNAL:
          * Determines the appropriate object to return from the unmarshal
          * call.  The method will either return the object created in the
          * xmlReader.parse() call or an instance of XMLRoot.  An XMLRoot
          * instance will be returned if the DOMRecord element being
          * unmarshalled does not equal the descriptor's default root
          * element.
          *
          * @return object
          */
        Object wrapObjectInXMLRoot(Object object, String elementNamespaceUri, String elementLocalName, String elementPrefix, boolean forceWrap, boolean isNamespaceAware, UNMARSHALLER xmlUnmarshaller);

        /**
         * INTERNAL:
         */
        Object wrapObjectInXMLRoot(Object object, String elementNamespaceUri, String elementLocalName, String elementPrefix, String encoding, String version, boolean forceWrap, boolean isNamespaceAware, UNMARSHALLER unmarshaller);

        /**
          * INTERNAL:
          * Determines the appropriate object to return from the unmarshal
          * call.  The method will either return the object created in the
          * xmlReader.parse() call or an instance of XMLRoot.  An XMLRoot
          * instance will be returned if the DOMRecord element being
          * unmarshalled does not equal the descriptor's default root
          * element.
          *
          * @return object
          */
         Object wrapObjectInXMLRoot(UNMARSHAL_RECORD unmarshalRecord, boolean forceWrap);

        CoreAttributeGroup getAttributeGroup(String subgraph);

}
