/*
 * Copyright (c) 1998, 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:
//     Oracle  - initial API and implementation from Oracle TopLink
//     dmccann - Nov. 7/2008 - Added delegate key logic from AbstractHelperDelegator
//     Dmitry Kornilov - 2014/11/25 - ApplicationAccessWLS fixed to reflect changes in WLS
package org.eclipse.persistence.sdo.helper;

import java.io.File;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.management.AttributeChangeNotification;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.Notification;
import javax.management.NotificationFilterSupport;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.eclipse.persistence.exceptions.SDOException;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
import org.eclipse.persistence.internal.security.PrivilegedGetMethod;
import org.eclipse.persistence.sdo.SDOConstants;
import org.eclipse.persistence.sdo.SDOResolvable;
import org.eclipse.persistence.sdo.helper.delegates.SDODataFactoryDelegate;
import org.eclipse.persistence.sdo.helper.delegates.SDOTypeHelperDelegate;
import org.eclipse.persistence.sdo.helper.delegates.SDOTypeHelperDelegate.SDOWrapperTypeId;
import org.eclipse.persistence.sdo.helper.delegates.SDOXMLHelperDelegate;
import org.eclipse.persistence.sdo.helper.delegates.SDOXSDHelperDelegate;
import org.eclipse.persistence.sdo.types.SDOWrapperType;

import commonj.sdo.Type;
import commonj.sdo.helper.CopyHelper;
import commonj.sdo.helper.DataFactory;
import commonj.sdo.helper.DataHelper;
import commonj.sdo.helper.EqualityHelper;
import commonj.sdo.helper.HelperContext;
import commonj.sdo.helper.TypeHelper;
import commonj.sdo.helper.XMLHelper;
import commonj.sdo.helper.XSDHelper;
import commonj.sdo.impl.ExternalizableDelegator;

/**
 * <b>Purpose:</b>
 * <ul>
 * <li>This class represents a local HelperContext.  The global
 * HelperContext can be accessed as HelperProvider.getDefaultContext().</li>
 * </ul>
 * <b>Responsibilities:</b>
 * <ul>
 * <li>Provide access to instances of helper objects.</li>
 * <li>Provide an OSGi compatible HelperContext (when the constructor that takes
 * a ClassLoader is used).</li>
 * </ul>
 *
 * @since Oracle TopLink 11.1.1.0.0
 */
public class SDOHelperContext implements HelperContext {

    private static final Logger LOGGER = Logger.getLogger(SDOHelperContext.class.getName());

    protected CopyHelper copyHelper;
    protected DataFactory dataFactory;
    protected DataHelper dataHelper;
    protected EqualityHelper equalityHelper;
    protected XMLHelper xmlHelper;
    protected TypeHelper typeHelper;
    protected XSDHelper xsdHelper;
    private String identifier;
    private Map<String, Object> properties;
    private boolean isStrictTypeCheckingEnabled = PrivilegedAccessHelper.getSystemPropertyBoolean(
            STRICT_TYPE_CHECKING_PROPERTY_NAME, true);

    /**
     * Property controls strictness of {@link Type#getInstanceClass()} type checking.
     *
     * <p>
     * See {@link #isStrictTypeCheckingEnabled()} for more details.
     * By this property, the initial value can be changed.
     * Default value is <code>true</code>.
     * </p>
     */
    public static final String STRICT_TYPE_CHECKING_PROPERTY_NAME = "eclipselink.sdo.strict.type.checking";

    // Each application will have its own helper context - it is assumed that application
    // names/loaders are unique within each active server instance
    private static ConcurrentHashMap<Object, ConcurrentHashMap<String, HelperContext>> helperContexts = new ConcurrentHashMap<Object, ConcurrentHashMap<String, HelperContext>>();
    // Each application will have a Map of alias' to identifiers
    private static ConcurrentHashMap<Object, ConcurrentHashMap<String, String>> aliasMap = new ConcurrentHashMap<Object, ConcurrentHashMap<String, String>>();
    // Each application could have separate HelperContextResolver
    private static final ConcurrentHashMap<Object, HelperContextResolver> HELPER_CONTEXT_RESOLVERS = new ConcurrentHashMap<>();
    // allow users to set their own classloader to context map pairs
    private static WeakHashMap<ClassLoader, WeakHashMap<String, WeakReference<HelperContext>>> userSetHelperContexts = new WeakHashMap<ClassLoader, WeakHashMap<String, WeakReference<HelperContext>>>();
    // keep a map of application names to application class loaders to handle redeploy
    private static ConcurrentHashMap<String, ClassLoader> appNameToClassLoaderMap = new ConcurrentHashMap<String, ClassLoader>();
    // keep a map of application name to the wrapper types for that application
    private static final ConcurrentHashMap<String,Map<SDOWrapperTypeId,SDOWrapperType>> SDO_WRAPPER_TYPES = new ConcurrentHashMap<>();

    // Application server identifiers
    private static String OC4J_CLASSLOADER_NAME = "oracle";
    private static String WLS_CLASSLOADER_NAME = "weblogic";
    private static String WAS_CLASSLOADER_NAME = "com.ibm.ws";
    private static String JBOSS_CLASSLOADER_NAME = "jboss";
    private static String GLOBAL_HELPER_IDENTIFIER = "";
    private static final int WLS_IDENTIFIER = 0;
    private static final int JBOSS_IDENTIFIER = 1;

    // Common
    private static final int COUNTER_LIMIT = 20;

    // For WebLogic
    private static volatile ApplicationAccessWLS applicationAccessWLS = null;
    private static MBeanServer wlsMBeanServer = null;
    private static ObjectName wlsThreadPoolRuntime = null;
    private static final String WLS_ENV_CONTEXT_LOOKUP = "java:comp/env/jmx/runtime";
    private static final String WLS_CONTEXT_LOOKUP = "java:comp/jmx/runtime";
    private static final String WLS_RUNTIME_SERVICE = "RuntimeService";
    private static final String WLS_SERVICE_KEY = "com.bea:Name=RuntimeService,Type=weblogic.management.mbeanservers.runtime.RuntimeServiceMBean";
    private static final String WLS_APP_RUNTIMES = "ApplicationRuntimes";
    private static final String WLS_SERVER_RUNTIME = "ServerRuntime";
    private static final String WLS_THREADPOOL_RUNTIME = "ThreadPoolRuntime";
    private static final String WLS_EXECUTE_THREAD = "ExecuteThread";
    private static final String WLS_MBEAN_SERVER = "MBeanServer";
    private static final String WLS_EXECUTE_THREAD_GET_METHOD_NAME = "getExecuteThread";
    private static final String WLS_APPLICATION_NAME = "ApplicationName";
    private static final String WLS_APPLICATION_VERSION = "ApplicationVersion";
    private static final String WLS_APPLICATION_NAME_GET_METHOD_NAME = "getApplicationName";
    private static final String WLS_ACTIVE_VERSION_STATE = "ActiveVersionState";
    private static final Class[] WLS_PARAMETER_TYPES = {};

    // For WebSphere
    private static final String WAS_NEWLINE = "\n";
    private static final String WAS_APP_COLON = "[app:";
    private static final String WAS_CLOSE_BRACKET = "]";

    // For JBoss
    private static MBeanServer jbossMBeanServer = null;
    private static String JBOSS_SERVICE_CONTROLLER = "jboss.system:service=ServiceController";
    private static String JBOSS_TYPE_STOP = "org.jboss.system.ServiceMBean.stop";
    private static String JBOSS_ID_KEY = "id";
    private static final String JBOSS_DEFAULT_DOMAIN_NAME = "jboss";
    private static final String JBOSS_VFSZIP = "vfszip:";
    private static final String JBOSS_VFSFILE = "vfsfile:";
    private static final String JBOSS_EAR = ".ear";
    private static final String JBOSS_JAR = ".jar";
    private static final String JBOSS_WAR = ".war";
    private static final int JBOSS_VFSZIP_OFFSET = JBOSS_VFSZIP.length();
    private static final int JBOSS_VFSFILE_OFFSET = JBOSS_VFSFILE.length();
    private static final int JBOSS_EAR_OFFSET = JBOSS_EAR.length();
    private static final int JBOSS_TRIM_COUNT = 2;  // for stripping off the remaining '/}' chars

    // allow users to provide application info
    private static ApplicationResolver appResolver;
    private static boolean isAppResolverSet = false;

    /**
     * Default strategy for HelperContext creation.
     * Singleton.
     */
    private static final HelperContextResolver DEFAULT_HCR = new DefaultHelperContextResolver();

    /**
     * ADVANCED:
     * Used to set an ApplicationResolver instance that will be used to retrieve
     * info pertaining to a given application, such as the application name, in
     * the case where our logic fails.
     *
     * This method can be called once and only once per active server instance.
     *
     * @param aResolver the ApplicationResolver instance that will be used to retrieve
     *                  info pertaining to a given application.  Note that null is
     *                  considered a valid set operation.
     * @throws SDOException if more than one call is made to this method
     *         in an active server instance.
     */
    public static void setApplicationResolver(ApplicationResolver aResolver) {
        // we only allow one set operation per running server instance
        if (isApplicationResolverSet()) {
            throw SDOException.attemptToResetApplicationResolver();
        }
        appResolver = aResolver;
        isAppResolverSet = true;
    }

    /**
     * Indicates if a call to setApplicationResolver has been made.
     *
     * @return true if a prior call to setApplicationResolver has
     *         been made, false otherwise
     */
    public static boolean isApplicationResolverSet() {
        return isAppResolverSet;
    }

    /**
     * Create a local HelperContext.  The current thread's context ClassLoader
     * will be used to find static instance classes.  In OSGi environments the
     * construct that takes a ClassLoader parameter should be used instead.
     */
    public SDOHelperContext() {
        this(Thread.currentThread().getContextClassLoader());
    }

    /**
     * Create a local HelperContext with the given identifier.  The current
     * thread's context ClassLoader will be used to find static instance
     * classes.  In OSGi environments the construct that takes a ClassLoader
     * parameter should be used instead.
     *
     * @param identifier The unique label for this HelperContext.
     */
    public SDOHelperContext(String identifier) {
        this(identifier, Thread.currentThread().getContextClassLoader());
    }

    /**
     * Create a local HelperContext.  This constructor should be used in OSGi
     * environments.
     *
     * @param aClassLoader This class loader will be used to find static
     * instance classes.
     */
    public SDOHelperContext(ClassLoader aClassLoader) {
        super();
        this.identifier = GLOBAL_HELPER_IDENTIFIER;
        initialize(aClassLoader);
    }

    /**
     * Create a local HelperContext with the given identifier.  This constructor
     * should be used in OSGi environments.
     *
     * @param identifier The unique label for this HelperContext.
     * @param aClassLoader This class loader will be used to find static
     * instance classes.
     */
    public SDOHelperContext(String identifier, ClassLoader aClassLoader) {
        super();
        this.identifier = identifier;
        initialize(aClassLoader);
    }

    /**
     * The underlying helpers for this instance will be instantiated
     * in this method.
     *
     * @param aClassLoader
     */
    protected void initialize(ClassLoader aClassLoader)  {
        copyHelper = new SDOCopyHelper(this);
        dataFactory = new SDODataFactoryDelegate(this);
        dataHelper = new SDODataHelper(this);
        equalityHelper = new SDOEqualityHelper(this);
        xmlHelper = new SDOXMLHelperDelegate(this, aClassLoader);
        typeHelper = new SDOTypeHelperDelegate(this);
        xsdHelper = new SDOXSDHelperDelegate(this);
    }

    /**
     * Reset the Type,XML and XSD helper instances.
     */
    public void reset() {
        ((SDOTypeHelper)getTypeHelper()).reset();
        ((SDOXMLHelper)getXMLHelper()).reset();
        ((SDOXSDHelper)getXSDHelper()).reset();
    }

    /**
     * Return the CopyHelper instance for this helper context.
     */
    @Override
    public CopyHelper getCopyHelper() {
        return copyHelper;
    }

    /**
     * Return the DataFactory instance for this helper context.
     */
    @Override
    public DataFactory getDataFactory() {
        return dataFactory;
    }

    /**
     * Return the DataHelper instance for this helper context.
     */
    @Override
    public DataHelper getDataHelper() {
        return dataHelper;
    }

    /**
     * Return the EqualityHelper instance for this helper context.
     */
    @Override
    public EqualityHelper getEqualityHelper() {
        return equalityHelper;
    }

    /**
     * Return the TypeHelper instance for this helper context.
     */
    @Override
    public TypeHelper getTypeHelper() {
        return typeHelper;
    }

    /**
     * Return the XMLHelper instance for this helper context.
     */
    @Override
    public XMLHelper getXMLHelper() {
        return xmlHelper;
    }

    /**
     * Return the XSDHelper instance for this helper context.
     */
    @Override
    public XSDHelper getXSDHelper() {
        return xsdHelper;
    }

    /**
     * Create and return a new ExternalizableDelegator.Resolvable instance based
     * on this helper context.
     *
     * @return
     */
    public ExternalizableDelegator.Resolvable createResolvable() {
        return new SDOResolvable(this);
    }

    /**
     * Create and return a new ExternalizableDelegator.Resolvable instance based
     * on this helper context and a given target.
     *
     * @param target
     * @return
     */
    public ExternalizableDelegator.Resolvable createResolvable(Object target) {
        return new SDOResolvable(target, this);
    }

    /**
     * INTERNAL:
     * Put a ClassLoader/HelperContext key/value pair in the Thread HelperContext
     * map.  If Thread.currentThread().getContextClassLoader() == key during
     * getHelperContext() call then the HelperContext (value) will be returned.
     * This method will overwrite an existing entry in the map with the same
     * ClassLoader key.
     *
     * @param key class loader
     * @param value helper context
     */
    public static void putHelperContext(ClassLoader key, HelperContext value) {
        if (key == null || value == null) {
            return;
        }
        WeakHashMap<String, WeakReference<HelperContext>> currentMap = userSetHelperContexts.get(key);
        if(currentMap == null) {
            currentMap = new WeakHashMap<String, WeakReference<HelperContext>>();
            userSetHelperContexts.put(key, currentMap);
        }
        currentMap.put(((SDOHelperContext) value).getIdentifier(), new WeakReference(value));
    }

    /**
     * INTERNAL:
     * Retrieve the HelperContext for a given ClassLoader from the Thread
     * HelperContext map.
     *
     * @param key class loader
     * @return HelperContext for the given key if key exists in the map, otherwise null
     */
    private static HelperContext getUserSetHelperContext(String identifier, ClassLoader key) {
        if (key == null) {
            return null;
        }
        WeakHashMap<String, WeakReference<HelperContext>> currentMap = userSetHelperContexts.get(key);
        if(currentMap == null) {
            return null;
        }
        WeakReference<HelperContext> ref = currentMap.get(identifier);
        if(ref == null) {
            return null;
        }
        return ref.get();
    }

    /**
     * INTERNAL:
     * Remove a ClassLoader/HelperContext key/value pair from the Thread
     * HelperContext map. If there are multiple local helper contexts associated
     * with this ClassLoader, they will all be removed from the map.
     *
     * @param key class loader
     */
    public static void removeHelperContext(ClassLoader key) {
        if (key == null) {
            return;
        }
        userSetHelperContexts.remove(key);
    }

    /**
     * INTERNAL
     * @param identifier the specific identifier of the HelperContext to be removed. "" for a Global helper
     * @param key the ClassLoader associated with the HelperContext to be removed
     */
    public static void removeHelperContext(String identifier, ClassLoader key) {
        if(key == null) {
            return;
        }
        WeakHashMap<String, WeakReference<HelperContext>> currentMap = userSetHelperContexts.get(key);
        if(currentMap != null) {
            currentMap.remove(identifier);
        }
    }

    /**
     * INTERNAL:
     * Return the helper context for a given key.  The key will either
     * be a ClassLoader or a String (representing an application name).
     * A new context will be created and put in the map if none exists
     * for the given key.
     *
     * The key is assumed to be non-null -  getDelegateKey should always
     * return either a string representing the application name (for WLS,
     * WAS and JBoss if available) or a class loader.  This is relevant
     * since 'putIfAbsent' will throw a null pointer exception if the
     * key is null.
     */
    public static HelperContext getHelperContext() {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        // check the map for contextClassLoader and return it if it exists
        HelperContext hCtx = getUserSetHelperContext(GLOBAL_HELPER_IDENTIFIER, contextClassLoader);
        if (hCtx != null) {
            return hCtx;
        }
        return getHelperContext(GLOBAL_HELPER_IDENTIFIER);
    }

    /**
     * Return the local helper context associated with the given identifier, or
     * create one if it does not already exist.  If identifier is an alias, the
     * value associated with it in the alias Map will be used as the identifier
     * value.
     *
     * @param identifier the identifier or alias to use for lookup/creation
     * @return HelperContext associated with identifier, or a new HelperContext
     * keyed on identifier if none eixsts
     */
    public static HelperContext getHelperContext(String identifier) {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        return getHelperContext(identifier, contextClassLoader);
    }

    /**
     * Return the local helper context with the given identifier, or create
     * one if it does not already exist.
     */
    public static HelperContext getHelperContext(String identifier, ClassLoader classLoader) {
        // if identifier is an alias, we need the actual id value
        ConcurrentMap<String, String> aliasEntries = getAliasMap();
        if (aliasEntries.containsKey(identifier)) {
            identifier = aliasEntries.get(identifier);
        }
        HelperContext helperContext = getUserSetHelperContext(identifier, classLoader);
        if (helperContext != null) {
            return helperContext;
        }
        ConcurrentMap<String, HelperContext> contextMap = getContextMap();
        helperContext = contextMap.get(identifier);
        if (null == helperContext) {
            LOGGER.fine("helperContext not found.");
            helperContext = getHelperContextResolver().getHelperContext(identifier, classLoader);
            HelperContext existingContext = contextMap.putIfAbsent(identifier, helperContext);
            if (existingContext != null) {
                LOGGER.fine(String.format("contextMap already has context for id: %s. Existing one will be used.", identifier));
                helperContext = existingContext;
            }
        }
        return helperContext;
    }

    /**
     * Returns the map of helper contexts, keyed on Identifier, for the current application
     * @return
     */
    static ConcurrentMap<String, HelperContext> getContextMap() {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        String classLoaderName = contextClassLoader.getClass().getName();
        // get a MapKeyLookupResult instance based on the context loader
        MapKeyLookupResult hCtxMapKey = getContextMapKey(contextClassLoader, classLoaderName);
        // at this point we will have a loader and possibly an application name
        String appName = hCtxMapKey.getApplicationName();
        ClassLoader appLoader = hCtxMapKey.getLoader();
        // we will use the application name as the map key if set; otherwise we use the loader
        Object contextMapKey = appName != null ? appName : appLoader;
        ConcurrentHashMap<String, HelperContext> contextMap = helperContexts.get(contextMapKey);

        // handle possible redeploy
        // the following block only applies to WAS - hence the loader name check
        if (contextMap != null && appName != null && classLoaderName.contains(WAS_CLASSLOADER_NAME)) {
            // at this point there is an existing entry in the map - if the context is keyed
            // on application name we need to check to see if a redeployment occurred; in
            // that case the app names will match, but the class loaders will not
            ClassLoader currentAppLoader = appNameToClassLoaderMap.get(appName);
            if (currentAppLoader != null && currentAppLoader != appLoader) {
                // concurrency - use remove(key, value) to ensure we don't remove a newly added entry
                appNameToClassLoaderMap.remove(appName, currentAppLoader);
                helperContexts.remove(appName, contextMap);
                contextMap = null;
            }
        }

        // may need to add a new entry
        if (null == contextMap) {
            contextMap = new ConcurrentHashMap<String, HelperContext>();
            // use putIfAbsent to avoid concurrent entries in the map
            ConcurrentHashMap<String, HelperContext> existingMap = helperContexts.putIfAbsent(contextMapKey, contextMap);
            if (existingMap != null) {
                // if a new entry was just added, use it instead of the one we just created
                contextMap = existingMap;
            } else if (appName != null) {
                // add an appName/appLoader pair to the appNameToClassLoader map
                appNameToClassLoaderMap.put(appName, appLoader);

                if (classLoaderName.contains(WLS_CLASSLOADER_NAME)) {
                    // add a loader/context pair to the helperContexts map to handle case where appName
                    // is no longer available, but the loader from a previous lookup is being used
                    helperContexts.put(appLoader, contextMap);
                    // add a notification listener to handle redeploy
                    addWLSNotificationListener(appName);
                } else if (classLoaderName.contains(JBOSS_CLASSLOADER_NAME)) {
                    // add a notification listener to handle redeploy - the listener will only be added once
                    addJBossNotificationListener();
                }
            }
        }
        return contextMap;
    }

    /**
     * Replaces the provided  helper context in the map of identifiers to
     * helper contexts for this application. ctx.getIdentifier()  will be
     * used to obtain the identifier value. If identifier is a key in the
     * the alias Map, i.e. was previously set as alias, the corresponding
     * entry will be removed from the alias Map.
     *
     * @param ctx the HelperContext to be added to the context Map for
     * the current application
     */
    public static void putHelperContext(HelperContext ctx) {
        String identifier = ((SDOHelperContext) ctx).getIdentifier();
        if (GLOBAL_HELPER_IDENTIFIER.equals(identifier)) {
            // The global HelperContext cannot be replaced
            return;
        }
        getContextMap().put(identifier, ctx);
        // identifier may have been an alias at one point
        getAliasMap().remove(identifier);
    }

    /**
     * ADVANCED:
     * Remove the HelperContext for the application associated with a
     * given key, if it exists in the map.
     */
    private static void resetHelperContext(String key) {
        // remove entry from helperContext map
        boolean successHc = removeAppFromMap(helperContexts, key, false);
        // remove app's helperContextResolver
        boolean successHcr = removeAppFromMap(HELPER_CONTEXT_RESOLVERS, key, true);
        if (LOGGER.isLoggable(Level.WARNING) && !successHc && !successHcr) {
            LOGGER.warning("No entries found in maps for application:" + key);
        }

        // remove the appName entry in the appNameToClassLoader map
        appNameToClassLoaderMap.remove(key);
        // remove static SDOWrapperType instances bound to this application
        SDO_WRAPPER_TYPES.remove(key);
        // remove the alias map for this app
        aliasMap.remove(key);
    }

    /**
     * Trying to remove entry for a given app the provided map.
     *
     * @param map from which app value should be removed
     * @param appName application name
     * @param removeDefaultClassloader whether to try removing the default classloader
     * @return true if any removal took place
     */
    private static boolean removeAppFromMap(Map map, String appName, boolean removeDefaultClassloader) {
        boolean result = map.remove(appName) != null;
        // there may be a loader/context pair to remove
        ClassLoader appLoader = appNameToClassLoaderMap.get(appName);
        if (appLoader != null) {
            result = result | map.remove(appLoader) != null;
        } else if (removeDefaultClassloader) {
            // try with Thread ContextClassLoader
            result = result | map.remove(Thread.currentThread().getContextClassLoader()) != null;
        }
        return result;
    }

    /**
     * INTERNAL:
     * Return the key to be used for Map lookups based in the current thread's
     * context loader.  The returned value will be the application name (if
     * available) or the context loader.
     *
     */
    private static Object getMapKey() {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        String classLoaderName = contextClassLoader.getClass().getName();
        // get a MapKeyLookupResult instance based on the context loader
        MapKeyLookupResult hCtxMapKey = getContextMapKey(contextClassLoader, classLoaderName);
        // at this point we will have a loader and possibly an application name
        String appName = hCtxMapKey.getApplicationName();
        ClassLoader appLoader = hCtxMapKey.getLoader();
        // we will use the application name as the map key if set; otherwise we use the loader
        return appName != null ? appName : appLoader;
    }

    /**
     * Bug #506919
     * Retrieves the application name for current {@link ClassLoader}.
     *
     * @param classLoader the ClassLoader to use for searching application name
     * @return the application name
     */
    private static String getApplicationName(ClassLoader classLoader) {
        String classLoaderName = classLoader.getClass().getName();
        // get a MapKeyLookupResult instance based on the context loader
        MapKeyLookupResult hCtxMapKey = getContextMapKey(classLoader, classLoaderName);
        // at this point we will have a loader and possibly an application name
        String applicationName = hCtxMapKey.getApplicationName();
        return applicationName != null? applicationName : "DEFAULT";
    }

    /**
     * INTERNAL:
     * This method will return the MapKeyLookupResult instance to be used to
     * store/retrieve the global helper context for a given application.
     *
     * OC4J classLoader levels:
     *      0 - APP.web (servlet/jsp) or APP.wrapper (ejb)
     *      1 - APP.root (parent for helperContext)
     *      2 - default.root
     *      3 - system.root
     *      4 - oc4j.10.1.3 (remote EJB) or org.eclipse.persistence:11.1.1.0.0
     *      5 - api:1.4.0
     *      6 - jre.extension:0.0.0
     *      7 - jre.bootstrap:1.5.0_07 (with various J2SE versions)
     *
     * @return MapKeyLookupResult wrapping the application classloader for OC4J,
     *         the application name for WebLogic and WebSphere, the archive file
     *         name for JBoss - if available; otherwise a MapKeyLookupResult
     *         wrapping Thread.currentThread().getContextClassLoader()
     */
    private static MapKeyLookupResult getContextMapKey(ClassLoader classLoader, String classLoaderName) {
        // Helper contexts in OC4J server will be keyed on classloader
        if (classLoaderName.startsWith(OC4J_CLASSLOADER_NAME)) {
            // Check to see if we are running in a Servlet container or a local EJB container
            if ((classLoader.getParent() != null) //
                    && ((classLoader.toString().indexOf(SDOConstants.CLASSLOADER_WEB_FRAGMENT) != -1) //
                    ||  (classLoader.toString().indexOf(SDOConstants.CLASSLOADER_EJB_FRAGMENT) != -1))) {
                classLoader = classLoader.getParent();
            }
            return new MapKeyLookupResult(classLoader);
        }
        // Helper contexts in WebLogic server will be keyed on application name if available
        if (classLoaderName.contains(WLS_CLASSLOADER_NAME)) {
            if (null == applicationAccessWLS) {
                synchronized (SDOHelperContext.class) {
                    if (applicationAccessWLS == null) {
                         applicationAccessWLS = new ApplicationAccessWLS();
                    }
                }
            }
            Object appName = applicationAccessWLS.getApplicationName(classLoader);
            if (appName != null) {
                return new MapKeyLookupResult(appName.toString(), classLoader);
            }

            Object executeThread = getExecuteThread();
            if (executeThread != null) {
                try {
                    Method getMethod = PrivilegedAccessHelper.getPublicMethod(executeThread.getClass(), WLS_APPLICATION_NAME_GET_METHOD_NAME, WLS_PARAMETER_TYPES, false);
                    appName = PrivilegedAccessHelper.invokeMethod(getMethod, executeThread);
                } catch (Exception e) {
                    throw SDOException.errorInvokingWLSMethodReflectively(WLS_APPLICATION_NAME_GET_METHOD_NAME, WLS_EXECUTE_THREAD, e);
                }
            }
            // if ExecuteThread is null or doesn't return the app name, attempt
            // to use the user-set ApplicationResolver (if set)
            if (appName == null && appResolver != null) {
                appName = appResolver.getApplicationName();
            }
            // use the application name if set, otherwise key on the class loader
            if (appName != null) {
                return new MapKeyLookupResult(appName.toString(), classLoader);
            }
            // couldn't get the application name, so default to the context loader
            return new MapKeyLookupResult(classLoader);
        }
        // Helper contexts in WebSphere server will be keyed on application name if available
        if (classLoaderName.contains(WAS_CLASSLOADER_NAME)) {
            return getContextMapKeyForWAS(classLoader);
        }
        // Helper contexts in JBoss server will be keyed on archive file name if available
        if (classLoaderName.contains(JBOSS_CLASSLOADER_NAME)) {
            return getContextMapKeyForJBoss(classLoader);
        }
        // at this point we will default to the context loader
        return new MapKeyLookupResult(classLoader);
    }

    /**
     * Lazy load the WebLogic MBeanServer instance.
     *
     * @return
     */
    private static MBeanServer getWLSMBeanServer() {
        if (wlsMBeanServer == null) {
            Context weblogicContext = null;
            try {
                weblogicContext = new InitialContext();
                try {
                    // The lookup string used depends on the context from which this class is being
                    // accessed, i.e. servlet, EJB, etc.  Try java:comp/env lookup
                    wlsMBeanServer = (MBeanServer) weblogicContext.lookup(WLS_ENV_CONTEXT_LOOKUP);
                } catch (NamingException e) {
                    // Lookup failed - try java:comp
                    try {
                        wlsMBeanServer = (MBeanServer) weblogicContext.lookup(WLS_CONTEXT_LOOKUP);
                    } catch (NamingException ne) {
                        throw SDOException.errorPerformingWLSLookup(WLS_MBEAN_SERVER, ne);
                    }
                }
            } catch (NamingException nex) {
                throw SDOException.errorCreatingWLSInitialContext(nex);
            }
        }
        return wlsMBeanServer;
    }

    /**
     * INTERNAL:
     * This convenience method will look up a WebLogic execute thread from the runtime
     * MBean tree.  The execute thread contains application information.  This code
     * will use the name of the current thread to lookup the corresponding ExecuteThread.
     * The ExecuteThread will allow us to obtain the application name (and version, etc).
     *
     * @return application name or null if the name cannot be obtained
     */
    private static Object getExecuteThread() {
        if (getWLSMBeanServer() != null) {
            // Lazy load the ThreadPoolRuntime instance
            if (wlsThreadPoolRuntime == null) {
                ObjectName service = null;
                ObjectName serverRuntime = null;
                try {
                    service = new ObjectName(WLS_SERVICE_KEY);
                } catch (Exception x) {
                    throw SDOException.errorGettingWLSObjectName(WLS_RUNTIME_SERVICE + " [" + WLS_SERVICE_KEY + "]", x);
                }
                try {
                    serverRuntime = (ObjectName) wlsMBeanServer.getAttribute(service, WLS_SERVER_RUNTIME);
                } catch (Exception x) {
                    throw SDOException.errorGettingWLSObjectName(WLS_SERVER_RUNTIME, x);
                }
                try {
                    wlsThreadPoolRuntime = (ObjectName) wlsMBeanServer.getAttribute(serverRuntime, WLS_THREADPOOL_RUNTIME);
                } catch (Exception x) {
                    throw SDOException.errorGettingWLSObjectName(WLS_THREADPOOL_RUNTIME, x);
                }
            }
            try {
                return wlsMBeanServer.invoke(wlsThreadPoolRuntime, WLS_EXECUTE_THREAD_GET_METHOD_NAME, new Object[] { Thread.currentThread().getName() }, new String[] { String.class.getName() });
            } catch (Exception x) {
                throw SDOException.errorInvokingWLSMethodReflectively(WLS_EXECUTE_THREAD_GET_METHOD_NAME, WLS_THREADPOOL_RUNTIME, x);
            }
        }
        return null;
    }

    /**
     * INTERNAL:
     * Adds a notification listener to the ApplicationRuntimeMBean instance with "ApplicationName"
     * attribute equals to 'mapKey.applicationName'.  The listener will handle application
     * re-deployment.
     *
     * If any errors occur, we will fail silently, i.e. the listener will not be added.
     *
     * This method should only be called when running in an active WLS instance.
     *
     * @param applicationName
     */
    private static void addWLSNotificationListener(String applicationName) {
        try {
            if (getWLSMBeanServer() != null) {
                ObjectName service = new ObjectName(WLS_SERVICE_KEY);
                ObjectName serverRuntime = (ObjectName) wlsMBeanServer.getAttribute(service, WLS_SERVER_RUNTIME);
                ObjectName[] appRuntimes = (ObjectName[]) wlsMBeanServer.getAttribute(serverRuntime, WLS_APP_RUNTIMES);
                for (int i=0; i < appRuntimes.length; i++) {
                    try {
                        ObjectName appRuntime = appRuntimes[i];
                        Object appName = wlsMBeanServer.getAttribute(appRuntime, WLS_APPLICATION_NAME);
                        Object appVersion = wlsMBeanServer.getAttribute(appRuntime, WLS_APPLICATION_VERSION);
                        String appIdentifier = null;
                        if (appName != null) {
                            if (appVersion != null) {
                                appIdentifier = appName.toString() + "#" + appVersion.toString();
                            } else {
                                appIdentifier = appName.toString();
                            }
                            if (appIdentifier != null && appIdentifier.equals(applicationName)) {
                                wlsMBeanServer.addNotificationListener(appRuntime, new MyNotificationListener(applicationName, WLS_IDENTIFIER), null, null);
                                break;
                            }
                        }
                    } catch (Exception ex) {
                        if (LOGGER.isLoggable(Level.FINE)) {
                            LOGGER.fine("Failed to retrieve application name in runtime " + appRuntimes[i].toString() + ":\n" + Helper.printStackTraceToString(ex));
                        }
                    }
                }
            }
        } catch (Exception x) {
            if (LOGGER.isLoggable(Level.WARNING)) {
                LOGGER.warning("Failed to add notification listener for application " + applicationName + ":\n" + Helper.printStackTraceToString(x));
            }
        }
    }

    /**
     * INTERNAL:
     * The listener will handle application re-deployment.  If any errors occur, we will
     * fail silently, i.e. the listener will not be added.  Since we cannot register for
     * notifications for a particular application, and hence recieve notifications for
     * all apps that are redeployed, we only add the listener once - each time we receive
     * notification we will check the map and remove the corresponding entry if it exists.
     *
     * This method should only be called when running in an active JBoss instance.
     *
     */
    private static void addJBossNotificationListener() {
        if (jbossMBeanServer == null) {
            List<MBeanServer> mbeanServers = MBeanServerFactory.findMBeanServer(null);
            for (MBeanServer server : mbeanServers) {
                if (server.getDefaultDomain().equals(JBOSS_DEFAULT_DOMAIN_NAME)) {
                    jbossMBeanServer = server;
                    try {
                        jbossMBeanServer.addNotificationListener(new ObjectName(JBOSS_SERVICE_CONTROLLER), new MyNotificationListener(JBOSS_IDENTIFIER), new MyNotificationFilter(), null);
                    } catch (Exception e) {}
                    break;
                }
            }
        }
    }

    /**
     * Getter for HelperContextResolver
     * @return actual strategy
     */
    public static HelperContextResolver getHelperContextResolver() {
        Object key = getMapKey();
        HelperContextResolver result = HELPER_CONTEXT_RESOLVERS.get(key);
        if (result == null) {
            result = DEFAULT_HCR;
            HELPER_CONTEXT_RESOLVERS.putIfAbsent(key, result);
        }
        return result;
    }

    /**
     * Method allows dynamically change HelperContext creation strategy.
     *
     * @param helperContextResolver on this object {@link HelperContextResolver#getHelperContext(String, ClassLoader)} will be called.
     *                              If it is null - then default strategy will be set.
     */
    public static void setHelperContextResolver(Object helperContextResolver) {
        Object key = getMapKey();
        if (helperContextResolver == null)
            HELPER_CONTEXT_RESOLVERS.put(key, DEFAULT_HCR);
        else
            HELPER_CONTEXT_RESOLVERS.put(key, new ReflectionHelperContextResolver(helperContextResolver));
    }

    /**
     * Method allows dynamically change HelperContext creation strategy.
     *
     * @param helperContextResolver strategy to be used. If it is null - then default strategy will be set.
     */
    public static void setHelperContextResolver(HelperContextResolver helperContextResolver) {
        Object key = getMapKey();
        if (helperContextResolver == null)
            HELPER_CONTEXT_RESOLVERS.put(key, DEFAULT_HCR);
        else
            HELPER_CONTEXT_RESOLVERS.put(key, helperContextResolver);
    }

    /**
     * Removes HelperContextResolver for the current application.
     * Application is resolved based on applicationName or classLoader.
     */
    public static void removeHelerContextResolver() {
        HELPER_CONTEXT_RESOLVERS.remove(getMapKey());
    }

    /**
     * INTERNAL:
     * This class will be handed in as a parameter when adding a JBoss notification listener.
     * The purpose of this class is to restrict notifications to "stop", i.e. we don't
     * care about "destroy", "start" etc.
     *
     */
    static class MyNotificationFilter extends NotificationFilterSupport {
        MyNotificationFilter() {
            super.enableType(JBOSS_TYPE_STOP);
        }
    }

    /**
     * INTERNAL:
     * Inner class used to catch application re-deployment.  Upon notification of this event,
     * the helper context for the given application will be removed from the helper context
     * to application map.  This method will also remove the corresponding entry in the
     * application name to application loader map if necessary.
     *
     * For WebLogic, 'appName' will be set; we will regester a listener for each application
     * name we key a context on, and will only receive a notification if a particular app
     * is redeployed.  Upon notification we will remove the context entry for 'appName'.
     *
     * For JBoss, 'appName' will not be set; we will only register the listener once,
     * and each time we're notified of an application redeployment, we will reset the
     * associated helper context if one exists.
     *
     */
    private static class MyNotificationListener implements NotificationListener {
        int server;
        String appName;

        /**
         * This is the default constructor - typically used when running in an
         * actove JBoss instance.
         *
         * @param server
         */
        public MyNotificationListener(int server) {
            this.server = server;
        }

        /**
         * This constructor will set 'appName' - typically used when running in
         * an active WebLogic instance.
         *
         * @param appName
         * @param server
         */
        public MyNotificationListener(String appName, int server) {
            this.server = server;
            this.appName = appName;
        }

        @Override
        public void handleNotification(Notification notification, Object handback) {
            switch (server) {
            case 0: {  // handle WebLogic notification
                if (notification instanceof AttributeChangeNotification) {
                    AttributeChangeNotification acn = (AttributeChangeNotification) notification;
                    if (acn.getAttributeName().equals(WLS_ACTIVE_VERSION_STATE)) {
                        if (acn.getNewValue().equals(0)) {
                            resetHelperContext(appName);
                        }
                    }
                }
                break;
            }
            case 1: {  // handle JBoss notification
                // assumes 'user data' is an ObjectName containing an 'id' property which indicates the archive file name
                appName = getApplicationNameFromJBossClassLoader(((ObjectName) notification.getUserData()).getKeyProperty(JBOSS_ID_KEY));
                // we receive notifications for all service stops in JBoss;  only call reset if necessary
                if (helperContexts.containsKey(appName)) {
                    resetHelperContext(appName);
                }
                break;
            }
            }
        }
    }

    /**
     * ADVANCED
     * Promote this helper context to be the default or global one.
     * This will completely replace the existing default context including
     * all types and properties defined.
     */
    public void makeDefaultContext() {
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
        MapKeyLookupResult hCtxMapKey = getContextMapKey(contextClassLoader, contextClassLoader.getClass().getName());

        String appName = hCtxMapKey.getApplicationName();
        ClassLoader appLoader = hCtxMapKey.getLoader();
        Object contextMapKey = appName != null ? appName : appLoader;

        ConcurrentHashMap<String, HelperContext> contexts = helperContexts.get(contextMapKey);
        if (contexts == null) {
            contexts = new ConcurrentHashMap<String, HelperContext>();
            ConcurrentHashMap<String, HelperContext> existingContexts = helperContexts.putIfAbsent(contextMapKey, contexts);
            if (existingContexts != null) {
                contexts = existingContexts;
            } else if (appName != null) {
                appNameToClassLoaderMap.put(appName, appLoader);
            }
        }
        this.identifier = GLOBAL_HELPER_IDENTIFIER;
        contexts.put(GLOBAL_HELPER_IDENTIFIER, this);
    }

    /**
     * Attempt to return the WAS application name based on a given class loader.
     * For WAS, the application loader's toString will contain "[app:".
     *
     * @param loader
     * @return String representing the application name, or null if the loader's toString
     *         doesn't contain "[app:".
     */
    private static String getApplicationNameFromWASClassLoader(final ClassLoader loader) {
        String applicationName = null;
        String loaderString = loader.toString().trim();
        while ((loaderString.startsWith(WAS_NEWLINE)) && (loaderString.length() > 0)) {
            loaderString = loaderString.substring(1).trim();
        }
        String loaderStringLines[] = loaderString.split(WAS_NEWLINE, 2);
        if (loaderStringLines.length > 0) {
            String firstLine = loaderStringLines[0].trim();
            int appPos = firstLine.indexOf(WAS_APP_COLON);
            if ((appPos >= 0) && (appPos + WAS_APP_COLON.length() < firstLine.length())) {
                String appNameSegment = firstLine.substring(appPos + WAS_APP_COLON.length());
                int closingBracketPosition = appNameSegment.indexOf(WAS_CLOSE_BRACKET);
                if (closingBracketPosition > 0) {
                    applicationName = appNameSegment.substring(0, closingBracketPosition);
                } else {
                    applicationName = appNameSegment;
                }
            }
        }
        return applicationName;
    }

    /**
     * Attempt to return a MapKeyLookupResult instance wrapping the application name and
     * application loader based on a given WAS classloader.  Here we will traverse up the
     * loader hierarchy looking for the top-most application loader.
     *
     * For WAS, the application loader's toString (and those of it's children) will
     * contain "[app:".
     *
     * @param loader
     * @return a MapKeyLookupResult instance wrapping application name/loader if
     *         successfully retrieved (i.e. at least one loader exists in the
     *         hierarchy with toString containing "[app:"), or a MapKeyLookupResult
     *         instance wrapping the given loader if not found
     */
    private static MapKeyLookupResult getContextMapKeyForWAS(ClassLoader loader) {
        ClassLoader applicationLoader = loader;
        String applicationName = null;
        // Safety counter to keep from taking too long or looping forever, just in case of some unexpected circumstance.
        int i = 0;
        // iterate up the loader hierarchy looking for the top-level application loader
        while (i < COUNTER_LIMIT) {
            if (wasClassLoaderHasApplicationName(loader)) {
                // current loader has application name info - store it
                applicationLoader = loader;
            }
            final ClassLoader parent = loader.getParent();
            // once we have hit the top we will stop looking
            if (parent == null || parent == loader) {
                // get the application name from the loader we are going to return
                applicationName = getApplicationNameFromWASClassLoader(applicationLoader);
                break;
            }
            // move up and try again
            loader = parent;
            i++;
        }
        // if we found the application name, use it as the key
        if (applicationName != null) {
            return new MapKeyLookupResult(applicationName, applicationLoader);

        }
        // at this point we don't know the application name so the loader will be the key
        return new MapKeyLookupResult(applicationLoader);
    }

    /**
     * Indicates if a given WAS class loader contains a application name.
     *
     * Assumptions:
     * 1 - The toString of a WAS application loader will contain "[app:".
     *
     * @param loader
     * @return true if the WAS class loader's toString contains "[app:"; false otherwise
     */
    private static boolean wasClassLoaderHasApplicationName(ClassLoader loader) {
        String loaderString = loader.toString().trim();
        while ((loaderString.startsWith(WAS_NEWLINE)) && (loaderString.length() > 0)) {
            loaderString = loaderString.substring(1).trim();
        }
        String loaderStringLines[] = loaderString.split(WAS_NEWLINE, 2);
        if (loaderStringLines.length > 0) {
            String firstLine = loaderStringLines[0].trim();
            int appPos = firstLine.indexOf(WAS_APP_COLON);
            if ((appPos >= 0) && (appPos + WAS_APP_COLON.length() < firstLine.length())) {
                return true;
            }
        }
        return false;
    }

    /**
     * Attempt to get the application name (archive file name) based on a given JBoss classloader.
     *
     * Here is an example toString result of the classloader which loaded the application in JBoss:
     * BaseClassLoader@1316dd{vfszip:/ade/xidu_j2eev5/oracle/work/utp/resultout/functional/jrf/
     *       jboss-jrfServer/deploy/jrftestapp.jar/}
     * or {vfsfile:/net/stott18.ca.oracle.com/scratch/xidu/view_storage/xidu_j2eev5/work/jboss/
     *       server/default/deploy/testapp.ear/} in exploded deployment
     * war: BaseClassLoader@bfe0e4{vfszip:/ade/xidu_j2eebug/oracle/work/utp/resultout/functional/
     *       jrf/jboss-jrfServer/jrfServer/deploy/jrftestapp.ear/jrftestweb.war/}
     *
     * Assumptions:
     * 1 - A given toString may contain both .ear and .jar, or .ear and .war, i.e.
     *     "{vfszip:/.../xxx.ear/.../xxx.war/}".  In this case we want to return
     *     xxx.ear as the application name.
     * 2 - A given toString will end in '/}'.
     * 3 - A toString containing the application name will have one of "vfszip:" or "vfsfile:".
     *
     * @param loaderToString the toString of the loader being processed
     * @return application name (archive file name) if successfully retrieved (i.e. loader
     *         exists in the hierarchy with toString containing "vfszip:" or "vfsfile:")
     *         or null
     */
    private static String getApplicationNameFromJBossClassLoader(String loaderToString) {
        String appNameSegment = null;
        int idx;
        // handle "vfszip:<archive-file-name>"
        if ((idx = loaderToString.indexOf(JBOSS_VFSZIP)) != -1) {
            appNameSegment = loaderToString.substring(idx + JBOSS_VFSZIP_OFFSET, loaderToString.length() - JBOSS_TRIM_COUNT);
            // handle case where the string contains both .ear and .war (remove the .war portion)
            if ((appNameSegment.indexOf(JBOSS_WAR) != -1) && (appNameSegment.indexOf(JBOSS_EAR) != -1)) {
                appNameSegment = appNameSegment.substring(0, appNameSegment.indexOf(JBOSS_EAR) + JBOSS_EAR_OFFSET);
            }
            // handle case where the string contains both .ear and .jar (remove the .jar portion)
            else if ((appNameSegment.indexOf(JBOSS_JAR) != -1) && (appNameSegment.indexOf(JBOSS_EAR) != -1)) {
                appNameSegment = appNameSegment.substring(0, appNameSegment.indexOf(JBOSS_EAR) + JBOSS_EAR_OFFSET);
            }
        }
        // handle "vfsfile:<archive-file-name>"
        else if ((idx = loaderToString.indexOf(JBOSS_VFSFILE)) != -1) {
            appNameSegment = loaderToString.substring(idx + JBOSS_VFSFILE_OFFSET, loaderToString.length() - JBOSS_TRIM_COUNT);
        }
        return appNameSegment != null ? new File(appNameSegment).getName() : null;
    }

    /**
     * Attempt to return a MapKeyLookupResult instance wrapping the archive file name and
     * application loader based on a given JBoss classloader.  Here we will traverse up the
     * loader hierarchy looking for the top-most application loader.
     *
     * @param loader
     * @return a MapKeyLookupResult instance wrapping archive file name/loader if
     *         successfully retrieved (i.e. at least one loader exists in the
     *         hierarchy with toString containing containing "vfszip:" or "vfsfile:"),
     *         or a MapKeyLookupResult instance wrapping the given loader if not found
     */
    private static MapKeyLookupResult getContextMapKeyForJBoss(ClassLoader loader) {
        ClassLoader applicationLoader = loader;
        String archiveFileName = null;
        // safety counter to keep from taking too long or looping forever, just in case of some unexpected circumstance
        int i = 0;
        // iterate up the loader hierarchy looking for the top-level application loader
        while (i < COUNTER_LIMIT) {
            if (jBossClassLoaderHasArchiveFileInfo(loader)) {
                // current loader has archive file info - store it
                applicationLoader = loader;
            }
            final ClassLoader parent = loader.getParent();
            // once we have hit the top we will stop looking
            if (parent == null || parent == loader) {
                // get the archive file name from the loader we are going to return
                archiveFileName = getApplicationNameFromJBossClassLoader(applicationLoader.toString());
                break;
            }
            // move up and try again
            loader = parent;
            i++;
        }
        // if we found the archive file name, use it as the key
        if (archiveFileName != null) {
            return new MapKeyLookupResult(archiveFileName, applicationLoader);
        }
        // at this point we don't know the archive file name so the loader will be the key
        return new MapKeyLookupResult(applicationLoader);
    }

    /**
     * Indicates if a given JBoss class loader contains an archive file name; i.e. is an application
     * loader.
     *
     * Here is an example toString result of the classloader which loaded the application in JBoss:
     * BaseClassLoader@1316dd{vfszip:/ade/xidu_j2eev5/oracle/work/utp/resultout/functional/jrf/
     *       jboss-jrfServer/deploy/jrftestapp.jar/}
     * or {vfsfile:/net/stott18.ca.oracle.com/scratch/xidu/view_storage/xidu_j2eev5/work/jboss/
     *       server/default/deploy/testapp.ear/} in exploded deployment
     * war: BaseClassLoader@bfe0e4{vfszip:/ade/xidu_j2eebug/oracle/work/utp/resultout/functional/
     *       jrf/jboss-jrfServer/jrfServer/deploy/jrftestapp.ear/jrftestweb.war/}
     *
     * Assumptions:
     * 1 - The toString of an application loader will have one of "vfszip:" or "vfsfile:".
     *
     * @param loader
     * @return true if the given JBoss loader has a toString containing "vfszip:" or "vfsfile:");
     *         false otherwise
     */
    private static boolean jBossClassLoaderHasArchiveFileInfo(ClassLoader loader) {
        // look for "vfszip:<archive-file-name>" or "vfsfile:<archive-file-name>"
        return (loader.toString().indexOf(JBOSS_VFSZIP) != -1 || loader.toString().indexOf(JBOSS_VFSFILE) != -1);
    }

    /**
     * Return the unique label for this HelperContext.
     *
     * @return String representing the unique label for this HelperContext
     */
    public String getIdentifier() {
        return this.identifier;
    }

    /**
     * Return true if a HelperContext corresponding to this identifier or alias
     * already exists, else false.  If identifer is an alias, the corresponding
     * value in the alias Map will be used as the identifier for the lookup.
     *
     * @param identifier the alias or identifier used to lookup a helper context
     * @return true if an entry exists in the helper context map for identifier (or
     * the associated identifier value if identifier is an alias), false otherwise.
     */
    public static boolean hasHelperContext(String identifier) {
        String id = identifier;
        Object appKey = getMapKey();
        // if identifier is an alias, we need the actual id value
        ConcurrentMap<String, String> aliasEntries = getAliasMap(appKey);
        if (aliasEntries.containsKey(identifier)) {
            id = aliasEntries.get(identifier);
        }
        // now check the Map of user set identifiers to helperContexts
        WeakHashMap<String, WeakReference<HelperContext>> userSetMap = userSetHelperContexts.get(appKey);
        if (userSetMap != null && userSetMap.containsKey(id)) {
            return true;
        }

        // lastly, check the Map of identifiers to helperContexts
        ConcurrentHashMap<String, HelperContext> contextMap = helperContexts.get(appKey);
        return (contextMap != null && contextMap.containsKey(id));
    }

    /**
     * Add an alias to identifier pair to the alias Map for the current
     * application.
     *
     * @param identifier assumed to be a key in the helper context Map
     * @param alias the alias to be associated with identifier
     */
    public static void addAlias(String identifier, String alias) {
        getAliasMap().put(alias, identifier);
    }

    /**
     * INTERNAL:
     * Returns the map of alias' to identifiers for the current application.
     *
     * @return Map of alias' to identifiers for the current application
     */
    private static ConcurrentMap<String, String> getAliasMap() {
        return getAliasMap(getMapKey());
    }

    /**
     * INTERNAL:
     * Returns the map of alias' to identifiers for the current application.
     *
     * @param mapKey application name or classloader used to lookup the alias map
     * @return Map of alias' to identifiers for the current application
     */
    private static ConcurrentMap<String, String> getAliasMap(Object mapKey) {
        ConcurrentHashMap<String, String> alias = aliasMap.get(mapKey);

        // may need to add a new entry
        if (null == alias) {
            alias = new ConcurrentHashMap<String, String>();
            // use putIfAbsent to avoid concurrent entries in the map
            ConcurrentHashMap<String, String> existingMap = aliasMap.putIfAbsent(mapKey, alias);
            if (existingMap != null) {
                // if a new entry was just added, use it instead of the one we just created
                alias = existingMap;
            }
        }
        return alias;
    }

    /**
     * Lazily initialize the Map of user properties.
     */
    private Map<String, Object> getProperties() {
        if (properties == null) {
            properties = new HashMap<String, Object>();
        }
        return properties;
    }

    /**
     * Add a name/value pair to the properties Map.  If name is
     * null, nothing will be done. If value is null, the entry
     * in the Map will be removed (if an entry exists for name).
     *
     * @param name the name of the property
     * @param value the value of the property
     */
    public void setProperty(String name, Object value) {
        // if the key is null there is nothing to do
        if (name == null) {
            return;
        }
        // if value is null, remove the entry
        if (value == null) {
            getProperties().remove(name);
        } else {
            // put the name/value pair in the map
            getProperties().put(name, value);
        }
    }

    /**
     * Return the value stored in the properties Map for a given
     * name, or null if an entry for name does not exist.
     *
     * @param name the name of the property to be returned
     * @return the value associated with name, or null
     */
    public Object getProperty(String name) {
        return getProperties().get(name);
    }

    /**
     * Indicates whether strict type checking is enabled.
     *
     * <p>
     * If strict type checking is enabled then {@link Type#getInstanceClass()}
     * interface is checked whether it contains getters for all the properties
     * of the {@link Type} upon initialization of the {@link Type}.
     * If any getter is missing then the interface is ignored and
     * {@link Type#getInstanceClass()} will return {@code null}.
     * </p>
     *
     * <p>
     * The getters are not checked if the strict type checking is disabled.
     * </p>
     *
     * @return boolean value
     */
    public boolean isStrictTypeCheckingEnabled() {
        return this.isStrictTypeCheckingEnabled;
    }

    /**
     * Controls type checking strictness.
     *
     * See {@link #isStrictTypeCheckingEnabled()} for more details.
     *
     * @param enabled new value ({@code true} to enable the strict validation)
     */
    public void setStrictTypeCheckingEnabled(boolean enabled) {
        this.isStrictTypeCheckingEnabled = enabled;
    }

    /**
     * Strategy for {@link HelperContext} creation.
     *
     * If is not set explicitly the default one is used.
     */
    public interface HelperContextResolver {

        /**
         * Should return instance of {@link HelperContext}.
         *
         * @param id          the unique label for this HelperContext
         * @param classLoader this class loader will be used to find static instance classes
         * @return instance of {@link HelperContext}
         */
        HelperContext getHelperContext(String id, ClassLoader classLoader);
    }

    /**
     * Default implementation of {@link HelperContextResolver}
     */
    private static class DefaultHelperContextResolver implements HelperContextResolver {

        @Override
        public HelperContext getHelperContext(String id, ClassLoader classLoader) {
            LOGGER.fine(String.format("DefaultHelperContextResolver: new HelperContext will be created for id: %s and classLoader: %s",
                    id, classLoader));
            return new SDOHelperContext(id, classLoader);
        }
    }

    /**
     * Implementation of {@link HelperContextResolver} which uses reflection to get {@link HelperContext} instance.
     */
    private static class ReflectionHelperContextResolver implements HelperContextResolver {

        private Method method;
        private Object target;

        /**
         * 'getHelperContext' method will be called on the provided target object.
         *
         * @param target object which has 'getHelperContext(String, Classloader)' method. In case it's not - RuntimeException will be thrown
         */
        public ReflectionHelperContextResolver(Object target) {
            this.target = target;
            try {
                this.method = findMethod(target.getClass(), "getHelperContext", new Class[]{String.class, ClassLoader.class});
            } catch (Exception e) {
                LOGGER.log(Level.SEVERE, e.getMessage(), e);
                throw new IllegalStateException(e);
            }
        }

        private Method findMethod(Class clazz, String methodName, Class[] params) throws java.security.PrivilegedActionException, NoSuchMethodException {
            if (PrivilegedAccessHelper.shouldUsePrivilegedAccess())
                return AccessController.doPrivileged(new PrivilegedGetMethod(clazz, methodName, params, true));
            return PrivilegedAccessHelper.getMethod(clazz, methodName, params, true);
        }

        /**
         * Calling 'getHelperContext' method on provided target object
         *
         * @param id          the unique label for this HelperContext
         * @param classLoader this class loader will be used to find static instance classes
         * @return in case if something goes wrong with method invocation and Exception is thrown - default implementation of
         * {@link HelperContextResolver} will be called
         */
        @Override
        public HelperContext getHelperContext(String id, ClassLoader classLoader) {
            try {
                return (HelperContext) method.invoke(target, id, classLoader);
            } catch (Exception e) {
                LOGGER.log(Level.SEVERE, e.getMessage(), e);
            }
            return DEFAULT_HCR.getHelperContext(id, classLoader);
        }
    }

    /**
     * Returns the {@link SDOWrapperType} instances for current application
     */
    public static Map<SDOWrapperTypeId,SDOWrapperType> getWrapperTypes() {
        return SDO_WRAPPER_TYPES.get(getApplicationName(Thread.currentThread().getContextClassLoader()));
    }

    /**
     * Replaces the {@link SDOWrapperType} instances for current application with the ones passed as an argument
     *
     * @param wrapperTypes the SDOWrapperType instances to use for current application
     * @return SDOWrapperType instances configured for current application
     */
    public static Map<SDOWrapperTypeId,SDOWrapperType> putWrapperTypes(Map<SDOWrapperTypeId,SDOWrapperType> wrapperTypes) {
        return SDO_WRAPPER_TYPES.put(getApplicationName(Thread.currentThread().getContextClassLoader()), wrapperTypes);
    }
}
