/*
 * Copyright (c) 1998, 2020 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.exceptions;

import java.io.IOException;

import javax.xml.namespace.QName;

import org.eclipse.persistence.exceptions.i18n.ExceptionMessageGenerator;

/**
 * <b>Purpose:</b>
 * <ul><li>This class provides an implementation of EclipseLinkException specific to the EclipseLink SDO (Service Data Objects) API.</li>
 * </ul>
 * <p>
 * <b>Responsibilities:</b>
 * <ul>
 * <li>Return an SDOException that can be thrown around input parameters.
 * <li>Return an SDOException that wraps an existing exception with additional input parameters.
 * </ul>
 * @since Oracle TopLink 11.1.1.0.0
 */
public class SDOException extends EclipseLinkException {
    /*
     * The following ID's are expanded to Strings in org.eclipse.persistence.exceptions.i18n.SDOExceptionResource
     *
     */
    public static final int NO_ID_SPECIFIED = 45000;
    public static final int ERROR_PROCESSING_IMPORT = 45001;
    public static final int ERROR_PROCESSING_INCLUDE = 45002;
    public static final int REFERENCED_PROPERTY_NOT_FOUND = 45003;
    public static final int OLD_SEQUENCE_NOT_FOUND = 45004;
    public static final int FOUND_SIMPLE_VALUE_FOR_FOR_NON_DATATYPE_PROPERTY = 45005;
    public static final int SEQUENCE_NULL_ON_SEQUENCED_DATAOBJECT = 45006;
    public static final int NO_TYPE_SPECIFIED_FOR_PROPERTY = 45007;
    public static final int IO_EXCEPTION_OCCURRED = 45008;
    public static final int TYPE_NOT_FOUND = 45009;
    public static final int TYPE_NOT_FOUND_FOR_INTERFACE = 45010;
    public static final int ERROR_CREATING_DATAOBJECT_FOR_TYPE = 45011;
    public static final int ERROR_CREATING_DATAOBJECT_FOR_CLASS = 45012;
    public static final int NO_APP_INFO_FOR_NULL = 45013;
    public static final int ERROR_DEFINING_TYPE = 45014;
    public static final int ERROR_DEFINING_TYPE_NO_NAME = 45015;
    public static final int MISSING_REF_ATTRIBUTE = 45016;
    public static final int ERROR_PROCESSING_XPATH = 45017;
    public static final int SEQUENCE_DUPLICATE_ADD_NOT_SUPPORTED = 45018;
    public static final int SEQUENCE_ERROR_PROPERTY_IS_ATTRIBUTE = 45019;
    public static final int SEQUENCE_ERROR_NO_PATH_FOUND = 45020;
    public static final int SEQUENCE_ERROR_DATAOBJECT_IS_NULL = 45021;
    public static final int SEQUENCE_NOT_SUPPORTED_FOR_PROPERTY = 45022;
    public static final int WRONG_VALUE_FOR_PROPERTY = 45023;
    public static final int CONVERSION_ERROR = 45024;
    public static final int PROPERTY_NOT_FOUND_AT_INDEX = 45025;
    public static final int CANNOT_PERFORM_OPERATION_ON_NULL_ARGUMENT = 45026;
    public static final int CLASS_NOT_FOUND = 45027;
    public static final int TYPE_CANNOT_BE_OPEN_AND_DATATYPE = 45028;
    public static final int INVALID_INDEX = 45029;
    public static final int JAVA_CLASS_INVOKING_ERROR = 45030;
    public static final int CANNOT_SET_PROPERTY_TYPE_ANNOTATION_IF_TARGET_DATATYPE_TRUE = 45031;
    public static final int XMLMARSHAL_EXCEPTION_OCCURRED = 45032;
    public static final int TYPE_REFERENCED_BUT_NEVER_DEFINED = 45033;
    public static final int OPTIONS_MUST_BE_A_DATAOBJECT = 45034;
    public static final int TYPE_PROPERTY_MUST_BE_A_TYPE = 45035;
    public static final int GLOBAL_PROPERTY_NOT_FOUND = 45036;
    public static final int PREFIX_USED_BUT_NOT_DEFINED = 45037;
    public static final int CANNOT_PERFORM_OPERATION_ON_PROPERTY = 45038;
    public static final int ERROR_ACCESSING_EXTERNALIZABLEDELEGATOR = 45039;
    public static final int CANNOT_PERFORM_OP_WITH_NULL_PARAM = 45040;
    public static final int INVALID_PROPERTY_VALUE = 45041;
    public static final int ERROR_PERFORMING_WLS_LOOKUP = 45100;
    public static final int ERROR_MAKING_WLS_REFLECTIVE_CALL = 45101;
    public static final int ERROR_GETTING_OBJECTNAME = 45102;
    public static final int ERROR_CREATING_INITIAL_CONTEXT = 45103;
    public static final int SDO_JAXB_NO_DESCRIPTOR_FOR_TYPE = 45200;
    public static final int SDO_JAXB_NO_MAPPING_FOR_PROPERTY = 45201;
    public static final int SDO_JAXB_NO_TYPE_FOR_CLASS = 45202;
    public static final int SDO_JAXB_NO_SCHEMA_REFERENCE = 45203;
    public static final int SDO_JAXB_NO_SCHEMA_CONTEXT = 45204;
    public static final int SDO_JAXB_NO_TYPE_FOR_CLASS_BY_SCHEMA_CONTEXT = 45205;
    public static final int SDO_JAXB_ERROR_CREATING_JAXB_UNMARSHALLER = 45206;
    public static final int ERROR_RESOLVING_ENTITY = 45207;
    public static final int MISSING_DEPENDENCY_FOR_BINARY_MAPPING = 45208;
    public static final int ATTEMPT_TO_RESET_APP_RESOLVER = 45209;
    public static final int DATAOBJECT_FROM_DIFFERENT_HELPERCONTEXT = 45210;
    public static final int ERROR_DEFINING_TYPE_INVALID_NAME = 45211;
    public static final int ERROR_DEFINING_PROPERTY_INVALID_NAME = 45212;

    protected SDOException(String message) {
        super(message);
    }

    protected SDOException(String message, Exception internalException) {
        super(message, internalException);
    }

    /**
     * INTERNAL:
     * Exception when acquiring the SDOHelperContext cache key for WLS.  This method should be
     * used when a lookup fails.  The lookup strings would typically be:
     *   - "java:comp/jmx/runtime"
     *   - "java:comp/env/jmx/runtime"
     */
    public static SDOException errorPerformingWLSLookup(String failedLookup, Exception nestedException) {
        Object[] args = { failedLookup };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(//
                SDOException.class, ERROR_PERFORMING_WLS_LOOKUP, args), nestedException);
        exception.setErrorCode(ERROR_PERFORMING_WLS_LOOKUP);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when acquiring the SDOHelperContext cache key for WLS.  This method should be
     * used when a reflective call fails.  The method names would typically be:
     *   - "getExecuteThread"
     *   - "getApplicationName"
     */
    public static SDOException errorInvokingWLSMethodReflectively(String methodName, String theClass, Exception nestedException) {
        Object[] args = { methodName, theClass };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(//
                SDOException.class, ERROR_MAKING_WLS_REFLECTIVE_CALL, args), nestedException);
        exception.setErrorCode(ERROR_MAKING_WLS_REFLECTIVE_CALL);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when acquiring the SDOHelperContext cache key for WLS.  This method should be
     * used when an attempt to get an ObjectName fails.  The object names would typically be:
     *   - "com.bea:Name=RuntimeService,Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean"
     *   - "ServerRuntime"
     *   - "ThreadPoolRuntime"
     */
    public static SDOException errorGettingWLSObjectName(String objectName, Exception nestedException) {
        Object[] args = { objectName };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(//
                SDOException.class, ERROR_GETTING_OBJECTNAME, args), nestedException);
        exception.setErrorCode(ERROR_GETTING_OBJECTNAME);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when acquiring the SDOHelperContext cache key for WLS.  This method should be
     * used when an attempt to create an InitialContext fails.
     */
    public static SDOException errorCreatingWLSInitialContext(Exception nestedException) {
        Object[] args = {};
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(//
                SDOException.class, ERROR_CREATING_INITIAL_CONTEXT, args), nestedException);
        exception.setErrorCode(ERROR_CREATING_INITIAL_CONTEXT);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when building an ObjectReferenceMapping and referenced object does not have an id property
     */
    public static SDOException noTargetIdSpecified(String uri, String name) {
        Object[] args = { uri, name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, NO_ID_SPECIFIED, args));
        exception.setErrorCode(NO_ID_SPECIFIED);
        return exception;
    }

    /**
      * INTERNAL:
      * Exception when processing an import during xsdhelper.define
      */
    public static SDOException errorProcessingImport(String schemaLocation, String namespace, Exception nestedException) {
        Object[] args = { schemaLocation, namespace };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(//
                SDOException.class, ERROR_PROCESSING_IMPORT, args), nestedException);
        exception.setErrorCode(ERROR_PROCESSING_IMPORT);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when processing an include during xsdhelper.define
     */
    public static SDOException errorProcessingInclude(String schemaLocation, Exception nestedException) {
        Object[] args = { schemaLocation };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(//
                SDOException.class, ERROR_PROCESSING_INCLUDE, args), nestedException);
        exception.setErrorCode(ERROR_PROCESSING_INCLUDE);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when trying to find a referenced property during xsdhelper.define
     */
    public static SDOException referencedPropertyNotFound(String uri, String localName) {
        Object[] args = { uri, localName };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, REFERENCED_PROPERTY_NOT_FOUND, args));
        exception.setErrorCode(REFERENCED_PROPERTY_NOT_FOUND);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when trying to find a global property during an unmarshal
     */
    public static SDOException globalPropertyNotFound() {
        Object[] args = { };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, GLOBAL_PROPERTY_NOT_FOUND, args));
        exception.setErrorCode(GLOBAL_PROPERTY_NOT_FOUND);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when old sequence is not found in the changesummary
     */
    public static SDOException oldSequenceNotFound() {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, OLD_SEQUENCE_NOT_FOUND, args));
        exception.setErrorCode(OLD_SEQUENCE_NOT_FOUND);
        return exception;
    }

    /**
      * INTERNAL:
      * Exception when the value should be a dataObject and it's not
      */
    public static SDOException foundSimpleValueForNonDataTypeProperty(String propertyName) {
        Object[] args = { propertyName };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, FOUND_SIMPLE_VALUE_FOR_FOR_NON_DATATYPE_PROPERTY, args));
        exception.setErrorCode(FOUND_SIMPLE_VALUE_FOR_FOR_NON_DATATYPE_PROPERTY);
        return exception;
    }

    /**
    * INTERNAL:
     * Exception when sequence is null on a dataObject with sequenced set to true
     */
    public static SDOException sequenceNullOnSequencedDataObject() {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SEQUENCE_NULL_ON_SEQUENCED_DATAOBJECT, args));
        exception.setErrorCode(SEQUENCE_NULL_ON_SEQUENCED_DATAOBJECT);
        return exception;
    }

    /**
      * INTERNAL:
      * Exception when a property does not have a type specified
      */
    public static SDOException noTypeSpecifiedForProperty(String propertyName) {
        Object[] args = { propertyName };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, NO_TYPE_SPECIFIED_FOR_PROPERTY, args));
        exception.setErrorCode(NO_TYPE_SPECIFIED_FOR_PROPERTY);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when an ioException happens
     */
    public static SDOException ioExceptionOccurred(IOException nestedException) {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, IO_EXCEPTION_OCCURRED, args), nestedException);
        exception.setErrorCode(IO_EXCEPTION_OCCURRED);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when an XMLMarshalException happens
     */
    public static SDOException xmlMarshalExceptionOccurred(XMLMarshalException nestedException, String rootElementURI, String rootElementName) {
        Object[] args = { nestedException.getLocalizedMessage(), rootElementURI, rootElementName};
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, XMLMARSHAL_EXCEPTION_OCCURRED, args), nestedException);
        exception.setErrorCode(XMLMARSHAL_EXCEPTION_OCCURRED);
        return exception;
    }

    /**
      * INTERNAL:
      * Exception trying to lookup a type with the given uri and name
      */
    public static SDOException typeNotFound(String uri, String name) {
        Object[] args = { uri, name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, TYPE_NOT_FOUND, args));
        exception.setErrorCode(TYPE_NOT_FOUND);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to lookup a type with the given interface
     */
    public static SDOException typeNotFoundForInterface(String className, boolean loadersAreRelated) {
        Object[] args = { className, loadersAreRelated };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, TYPE_NOT_FOUND_FOR_INTERFACE, args));
        exception.setErrorCode(TYPE_NOT_FOUND_FOR_INTERFACE);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to create a dataObject with a type with the given uri and name
     */
    public static SDOException errorCreatingDataObjectForType(String uri, String name) {
        Object[] args = { uri, name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_CREATING_DATAOBJECT_FOR_TYPE, args));
        exception.setErrorCode(ERROR_CREATING_DATAOBJECT_FOR_TYPE);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to call a method with a null input parameter
     */
    public static SDOException cannotPerformOperationWithNullInputParameter(String operation, String parameter) {
        Object[] args = { operation, parameter };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, CANNOT_PERFORM_OP_WITH_NULL_PARAM, args));
        exception.setErrorCode(CANNOT_PERFORM_OP_WITH_NULL_PARAM);
        return exception;
    }

    /**
     * INTERNAL: Exception trying to call a method with a null input parameter
     */
    public static SDOException invalidPropertyValue(String property, String type, String valueType, String value, ConversionException coe) {
        Object[] args = { value, valueType, property, type };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, INVALID_PROPERTY_VALUE, args), coe);
        exception.setErrorCode(INVALID_PROPERTY_VALUE);
        return exception;
    }

    /**
      * INTERNAL:
      * Exception trying to create a dataObject with a type with the given interface
      */
    public static SDOException errorCreatingDataObjectForClass(Exception nestedException, String className, String uri, String name) {
        Object[] args = { className, uri, name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_CREATING_DATAOBJECT_FOR_CLASS, args), nestedException);
        exception.setErrorCode(ERROR_CREATING_DATAOBJECT_FOR_CLASS);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to lookup an appinfo with a null property or type
     */
    public static SDOException noAppInfoForNull() {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, NO_APP_INFO_FOR_NULL, args));
        exception.setErrorCode(NO_APP_INFO_FOR_NULL);
        return exception;
    }

    /**
    * INTERNAL:
    * Exception trying to define a type
    */
    public static SDOException errorDefiningType() {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_DEFINING_TYPE, args));
        exception.setErrorCode(ERROR_DEFINING_TYPE);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to create a type without a name
     */
    public static SDOException errorDefiningTypeNoName() {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_DEFINING_TYPE_NO_NAME, args));
        exception.setErrorCode(ERROR_DEFINING_TYPE_NO_NAME);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to create a type with invalid name.
     * @param name type name
     * @return {@link SDOException}
     */
    public static SDOException errorDefiningTypeInvalidName(String name) {
        Object[] args = { name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_DEFINING_TYPE_INVALID_NAME, args));
        exception.setErrorCode(ERROR_DEFINING_TYPE_INVALID_NAME);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to create a type with property of invalid name.
     * @param name property name
     * @return {@link SDOException}
     */
    public static SDOException errorDefiningPropertyInvalidName(String name) {
        Object[] args = { name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_DEFINING_PROPERTY_INVALID_NAME, args));
        exception.setErrorCode(ERROR_DEFINING_PROPERTY_INVALID_NAME);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when an sdo:ref attribute is missing during xmlhelper.load
     */
    public static SDOException missingRefAttribute() {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, MISSING_REF_ATTRIBUTE, args));
        exception.setErrorCode(MISSING_REF_ATTRIBUTE);
        return exception;
    }

    /**
    * INTERNAL:
    * Exception processing an xpath during xmlhelper.load
    */
    public static SDOException errorProcessingXPath(String xpath) {
        Object[] args = { xpath };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_PROCESSING_XPATH, args));
        exception.setErrorCode(ERROR_PROCESSING_XPATH);
        return exception;
    }

    /**
     * INTERNAL:
     * Return an exception when attempting to add a setting to a sequene that already has
     * an existing entry.  The existing entry will not be updated or moved to the end of the sequence.
     * This exception occurs only for complex single types.
     */
    public static SDOException sequenceDuplicateSettingNotSupportedForComplexSingleObject(int index, String settingPropertyName) {
        Object[] args = { Integer.valueOf(index), settingPropertyName };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SEQUENCE_DUPLICATE_ADD_NOT_SUPPORTED, args));
        exception.setErrorCode(SEQUENCE_DUPLICATE_ADD_NOT_SUPPORTED);
        return exception;
    }

    /**
     * INTERNAL:
     * Error when we attempt to add an attribute property to a sequence
     */
    public static SDOException sequenceAttributePropertyNotSupported(String settingPropertyName) {
        Object[] args = {settingPropertyName};
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SEQUENCE_ERROR_PROPERTY_IS_ATTRIBUTE, args));
        exception.setErrorCode(SEQUENCE_ERROR_PROPERTY_IS_ATTRIBUTE);
        return exception;
    }

    /**
     * INTERNAL:
     * Error when we attempt find a sequence by path
     */
    public static SDOException sequenceNotFoundForPath(String path) {
        Object[] args = { path };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SEQUENCE_ERROR_NO_PATH_FOUND, args));
        exception.setErrorCode(SEQUENCE_ERROR_NO_PATH_FOUND);
        return exception;
    }

    /**
     * INTERNAL:
     * Error passing in a null dataObject into the sequence constructor
     */
    public static SDOException sequenceDataObjectInstanceFieldIsNull() {
        Object[] args = {  };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SEQUENCE_ERROR_DATAOBJECT_IS_NULL, args));
        exception.setErrorCode(SEQUENCE_ERROR_DATAOBJECT_IS_NULL);
        return exception;
    }

    /**
     * INTERNAL:
     * Error passing in a null dataObject into the sequence constructor
     */
    public static SDOException sequenceNotSupportedForProperty(String propertyName) {
        Object[] args = { propertyName };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SEQUENCE_NOT_SUPPORTED_FOR_PROPERTY, args));
        exception.setErrorCode(SEQUENCE_NOT_SUPPORTED_FOR_PROPERTY);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when trying to set a property to value that is an unsupported conversion
     */
    public static SDOException wrongValueForProperty(String typeUri, String typeName, Class valueClass) {
        Object[] args = { typeUri, typeName, valueClass.getName() };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, WRONG_VALUE_FOR_PROPERTY, args) );
        exception.setErrorCode(WRONG_VALUE_FOR_PROPERTY);
        return exception;
    }

    /**
    * INTERNAL:
    * Exception when trying to set a property to value that is an unsupported conversion
    */
    public static SDOException conversionError(Exception e) {
        Object[] args = {  };
        SDOException exception = null;
        if (e != null) {
            exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, CONVERSION_ERROR, args), e);
        } else {
            exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, CONVERSION_ERROR, args));
        }
        exception.setErrorCode(CONVERSION_ERROR);
        return exception;
    }

   /**
    * INTERNAL:
    * Exception when trying to find a property at an invalid index
    */
    public static SDOException propertyNotFoundAtIndex(Exception e, int propIndex) {
        Object[] args = { Integer.valueOf(propIndex) };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, PROPERTY_NOT_FOUND_AT_INDEX, args), e);
        exception.setErrorCode(PROPERTY_NOT_FOUND_AT_INDEX);
        return exception;
    }

    /**
    * INTERNAL:
    * Exception when trying to perform an operation with a null argument
    */
    public static SDOException cannotPerformOperationOnNullArgument(String methodName) {
        Object[] args = { methodName};
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, CANNOT_PERFORM_OPERATION_ON_NULL_ARGUMENT, args));
        exception.setErrorCode(CANNOT_PERFORM_OPERATION_ON_NULL_ARGUMENT);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception when trying to set a property via path based access.
     */
     public static SDOException cannotPerformOperationOnProperty(String propertyName, String path) {
         Object[] args = { propertyName, path };
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, CANNOT_PERFORM_OPERATION_ON_PROPERTY, args));
         exception.setErrorCode(CANNOT_PERFORM_OPERATION_ON_PROPERTY);
         return exception;
     }

    /**
     * INTERNAL:
     * Exception trying to load the instance class for a given type
     */
    public static SDOException classNotFound(Exception nestedException, String uri, String name) {
        Object[] args = { uri, name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, CLASS_NOT_FOUND, args), nestedException);
        exception.setErrorCode(CLASS_NOT_FOUND);
        return exception;
    }


   /**
     * INTERNAL:
     * Exception trying to set a type to be both open and dataType
     */
    public static SDOException typeCannotBeOpenAndDataType(String uri, String name) {
        Object[] args = { uri, name };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, TYPE_CANNOT_BE_OPEN_AND_DATATYPE, args));
        exception.setErrorCode(TYPE_CANNOT_BE_OPEN_AND_DATATYPE);
        return exception;
    }

    /**
     * INTERNAL:
     * Exception trying to pass an invalid index to a method
     */
    public static SDOException invalidIndex(IndexOutOfBoundsException nestedException, int index) {
        Object[] args = {Integer.valueOf(index) };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, INVALID_INDEX, args),nestedException);
        exception.setErrorCode(INVALID_INDEX);
        return exception;
    }

    /**
     * INTERNAL:
     * thrown from InstanceClassConverter
     */
     public static SDOException noConstructorWithString(Exception nestedException, String className) {
        Object[] args = {className };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, JAVA_CLASS_INVOKING_ERROR, args), nestedException);
        exception.setErrorCode(JAVA_CLASS_INVOKING_ERROR);
        return exception;
    }

     /**
      * INTERNAL:
      * Exception when trying to resolve an sdo xml [propertyType] annotation on a target Type of dataType==true.<br>
      * See Sect 9.2 (1) of the SDO Specification.
      * thrown from SDOTypesGenerator.postProcessing()
      */
      public static SDOException propertyTypeAnnotationTargetCannotBeDataTypeTrue(String targetTypeName, String sourcePropertyName) {
          Object[] args = { targetTypeName, sourcePropertyName};
          SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(//
                  SDOException.class, CANNOT_SET_PROPERTY_TYPE_ANNOTATION_IF_TARGET_DATATYPE_TRUE, args));
          exception.setErrorCode(CANNOT_SET_PROPERTY_TYPE_ANNOTATION_IF_TARGET_DATATYPE_TRUE);
          return exception;
      }

      public static SDOException typeReferencedButNotDefined(String namespaceUri, String typeName) {
          Object[] args = {namespaceUri, typeName};
          SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(
                  SDOException.class, TYPE_REFERENCED_BUT_NEVER_DEFINED, args));
          exception.setErrorCode(TYPE_REFERENCED_BUT_NEVER_DEFINED);
          return exception;
      }

    /**
     * INTERNAL:
     * thrown from SDOXMLHelperDelegate
     */
     public static SDOException optionsMustBeADataObject(Exception nestedException, String uri, String name) {
        Object[] args = {uri, name};
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, OPTIONS_MUST_BE_A_DATAOBJECT, args), nestedException);
        exception.setErrorCode(OPTIONS_MUST_BE_A_DATAOBJECT);
        return exception;
    }

      /**
     * INTERNAL:
     * thrown from SDOXMLHelperDelegate
     */
     public static SDOException typePropertyMustBeAType(Exception nestedException) {
        Object[] args = {};
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, TYPE_PROPERTY_MUST_BE_A_TYPE, args), nestedException);
        exception.setErrorCode(TYPE_PROPERTY_MUST_BE_A_TYPE);
        return exception;
    }

    /**
     * INTERNAL:
     * thrown from SDOTypesGenerator
     */
     public static SDOException prefixUsedButNotDefined(String prefix) {
        Object[] args = {prefix};
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, PREFIX_USED_BUT_NOT_DEFINED, args));
        exception.setErrorCode(PREFIX_USED_BUT_NOT_DEFINED);
        return exception;
    }
     /**
      * INTERNAL:
      */
     public static SDOException errorAccessingExternalizableDelegator(String fieldName, Exception nestedException) {
         Object[] args = { fieldName };
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_ACCESSING_EXTERNALIZABLEDELEGATOR, args), nestedException);
         exception.setErrorCode(ERROR_ACCESSING_EXTERNALIZABLEDELEGATOR);
         return exception;
     }

     public static SDOException sdoJaxbNoDescriptorForType(QName sdoQName, QName xmlQName) {
         Object[] args = {sdoQName.toString(), xmlQName.toString()};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SDO_JAXB_NO_DESCRIPTOR_FOR_TYPE, args));
         exception.setErrorCode(SDO_JAXB_NO_DESCRIPTOR_FOR_TYPE);
         return exception;
     }

     public static SDOException sdoJaxbNoMappingForProperty(String propertyName, String xPath) {
         Object[] args = {propertyName, xPath};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SDO_JAXB_NO_MAPPING_FOR_PROPERTY, args));
         exception.setErrorCode(SDO_JAXB_NO_MAPPING_FOR_PROPERTY);
         return exception;
     }

     public static SDOException sdoJaxbNoTypeForClass(Class clazz) {
         Object[] args = {clazz.toString()};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SDO_JAXB_NO_TYPE_FOR_CLASS, args));
         exception.setErrorCode(SDO_JAXB_NO_TYPE_FOR_CLASS);
         return exception;
     }

     public static SDOException sdoJaxbNoSchemaReference(Class clazz) {
         Object[] args = {clazz.toString()};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SDO_JAXB_NO_SCHEMA_REFERENCE, args));
         exception.setErrorCode(SDO_JAXB_NO_SCHEMA_REFERENCE);
         return exception;
     }

     public static SDOException sdoJaxbNoSchemaContext(Class clazz) {
         Object[] args = {clazz.toString()};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SDO_JAXB_NO_SCHEMA_CONTEXT, args));
         exception.setErrorCode(SDO_JAXB_NO_SCHEMA_CONTEXT);
         return exception;
     }

     public static SDOException sdoJaxbNoTypeForClassBySchemaContext(Class clazz, QName schemaContext) {
         Object[] args = {clazz.toString(), schemaContext.toString()};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SDO_JAXB_NO_TYPE_FOR_CLASS_BY_SCHEMA_CONTEXT, args));
         exception.setErrorCode(SDO_JAXB_NO_TYPE_FOR_CLASS_BY_SCHEMA_CONTEXT);
         return exception;
     }

     public static SDOException sdoJaxbErrorCreatingJAXBUnmarshaller(Exception jaxbException) {
         Object[] args = {};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, SDO_JAXB_ERROR_CREATING_JAXB_UNMARSHALLER, args), jaxbException);
         exception.setErrorCode(SDO_JAXB_ERROR_CREATING_JAXB_UNMARSHALLER);
         return exception;
     }

     public static SDOException errorResolvingSchema(Exception nestedException) {
         Object[] args = {};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ERROR_RESOLVING_ENTITY, args));
         exception.setErrorCode(ERROR_RESOLVING_ENTITY);
         exception.setInternalException(nestedException);
         return exception;
     }

     public static SDOException unableToMapDataHandlerDueToMissingDependency(String propertyName, String typeName) {
         Object[] args = {propertyName, typeName};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, MISSING_DEPENDENCY_FOR_BINARY_MAPPING, args));
         exception.setErrorCode(MISSING_DEPENDENCY_FOR_BINARY_MAPPING);
         return exception;
     }

     public static SDOException attemptToResetApplicationResolver() {
         Object[] args = {};
         SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, ATTEMPT_TO_RESET_APP_RESOLVER, args));
         exception.setErrorCode(ATTEMPT_TO_RESET_APP_RESOLVER);
         return exception;
     }

     /**
      * INTERNAL:
      * Exception trying to marshal a dataobject from a different HelperContext
      */
    public static SDOException dataObjectNotFromHelperContext() {
        Object[] args = { };
        SDOException exception = new SDOException(ExceptionMessageGenerator.buildMessage(SDOException.class, DATAOBJECT_FROM_DIFFERENT_HELPERCONTEXT, args));
        exception.setErrorCode(DATAOBJECT_FROM_DIFFERENT_HELPERCONTEXT);
        return exception;
    }

}
