/*
 * 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
//     @author  mobrien
//     @since   EclipseLink 1.0 enh# 235168
package org.eclipse.persistence.services;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.regex.PatternSyntaxException;

import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;

import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
import org.eclipse.persistence.internal.databaseaccess.DatabasePlatform;
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.identitymaps.CacheIdentityMap;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.identitymaps.FullIdentityMap;
import org.eclipse.persistence.internal.identitymaps.HardCacheWeakIdentityMap;
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
import org.eclipse.persistence.internal.identitymaps.NoIdentityMap;
import org.eclipse.persistence.internal.identitymaps.SoftCacheWeakIdentityMap;
import org.eclipse.persistence.internal.identitymaps.SoftIdentityMap;
import org.eclipse.persistence.internal.identitymaps.WeakIdentityMap;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.DefaultSessionLog;
import org.eclipse.persistence.logging.JavaLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.server.JMXEnabledPlatform;
import org.eclipse.persistence.sessions.DatabaseLogin;
import org.eclipse.persistence.sessions.DefaultConnector;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.server.ConnectionPool;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.tools.profiler.PerformanceProfiler;


/**
 * <p>
 * <b>Purpose</b>: Provide a dynamic interface into the EclipseLink Session.
 * <p>
 * <b>Description</b>: This class is meant to provide a framework for gaining access to configuration
 * of the EclipseLink Session during runtime.  It will provide the basis for development
 * of a JMX service and possibly other frameworks.
 *
 */
public abstract class RuntimeServices {

    /** stores access to the session object that we are controlling */
    protected Session session;

    /** This is the profile weight at server startup time. This is read-only */
    private int deployedSessionProfileWeight;

    /** This contains the session log from server startup time. This is read-only. */
    private SessionLog deployedSessionLog;

    public String objectName;

    protected static final String EclipseLink_Product_Name = "EclipseLink";
    /** Short name for the server platform - Must override in subclass */
    protected static String PLATFORM_NAME = "Server";

    /**
     *  Default Constructor
     */
    protected RuntimeServices() {
    }

    /**
     *  Constructor
     *  @param session the session to be used with these RuntimeServices
     */
    protected RuntimeServices(Session session) {
        this.session = session;
    }

    /**
     * INTERNAL:
     */
    protected AbstractSession getSession() {
        return (AbstractSession)this.session;
    }

    /**
     * Answer the name of the EclipseLink session this MBean represents.
     */
    public String getSessionName() {
        return getSession().getName();
    }

    /**
     * This method is used to determine if logging is turned on
     */
    public boolean getShouldLogMessages() {
        return getSession().shouldLogMessages();
    }

    /**
     *        This method is used to turn on Performance Profiling
     */
    public void setShouldProfilePerformance(boolean shouldProfile) {
        if (shouldProfile && (getSession().getProfiler() == null)) {
            getSession().setProfiler(new PerformanceProfiler());
        } else if (!shouldProfile) {
            getSession().setProfiler(null);
        }
    }

    /**
     *     This method will return if profiling is turned on or not
     */
    public boolean getShouldProfilePerformance() {
        return (getSession().getProfiler() != null) && ClassConstants.PerformanceProfiler_Class.isAssignableFrom(getSession().getProfiler().getClass());
    }

    /**
     *     This method is used to turn on Profile logging when using the Performance Profiler
     */
    public void setShouldLogPerformanceProfiler(boolean shouldLogPerformanceProfiler) {
        if ((getSession().getProfiler() != null) && ClassConstants.PerformanceProfiler_Class.isAssignableFrom(getSession().getProfiler().getClass())) {
            ((PerformanceProfiler)getSession().getProfiler()).setShouldLogProfile(shouldLogPerformanceProfiler);
        }
    }

    /**
     *     Method indicates if Performance profile should be logged
     */
    public boolean getShouldLogPerformanceProfiler() {
        if ((getSession().getProfiler() != null) && ClassConstants.PerformanceProfiler_Class.isAssignableFrom(getSession().getProfiler().getClass())) {
            return ((PerformanceProfiler)getSession().getProfiler()).shouldLogProfile();
        }
        return false;
    }

    /**
     *     Method used to set if statements should be cached.  Please note that Statements can not be cached when
     * using an external connection pool
     */
    public void setShouldCacheAllStatements(boolean shouldCacheAllStatements) {
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
            return;
        }
        ((DatabaseLogin)getSession().getDatasourceLogin()).setShouldCacheAllStatements(shouldCacheAllStatements);
    }

    /**
     *     Used to set the statement cache size.  This is only valid if using cached Statements
     */
    public void setStatementCacheSize(int size) {
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
            return;
        }
        ((DatabaseLogin)getSession().getDatasourceLogin()).setStatementCacheSize(size);
    }

    /**
     *        Returns the statement cache size.  Only valid if statements are being cached
     */
    public int getStatementCacheSize() {
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
            return 0;
        }
        return ((DatabaseLogin)getSession().getDatasourceLogin()).getStatementCacheSize();
    }

    /**
     * This method provide access for setting the sequence pre-allocation size
     */
    public void setSequencePreallocationSize(int size) {
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
            return;
        }
        ((DatasourcePlatform)getSession().getDatasourcePlatform()).setSequencePreallocationSize(size);
    }

    /**
     *        Method returns the value of the Sequence Preallocation size
     */
    public int getSequencePreallocationSize() {
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
            return 0;
        }
        return ((DatasourcePlatform)getSession().getDatasourcePlatform()).getSequencePreallocationSize();
    }

    /**
     *     This method allows the client to set the pool size for a particular pool, based on the pool name
     * @param poolName the name of the pool to be updated.
     * @param maxSize the new maximum number of connections
     * @param minSize the new minimum number of connections
     */
    public void updatePoolSize(String poolName, int maxSize, int minSize) {
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
            ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
            if (connectionPool != null) {
                connectionPool.setMaxNumberOfConnections(maxSize);
                connectionPool.setMinNumberOfConnections(minSize);
            }
        }
    }

    /**
     *     This method will return the available Connection pools within this Server Session
     * @return java.util.List the available pools.
     */
    public List getAvailableConnectionPools() {
        Vector list = null;
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
            Map<String, ConnectionPool> pools = ((ServerSession)getSession()).getConnectionPools();
            list = new Vector(pools.size());
            Iterator<String> poolNames = pools.keySet().iterator();
            while (poolNames.hasNext()) {
                list.add(poolNames.next());
            }
        } else {
            list = new Vector();
        }
        return list;
    }

    /**
     *     This method will retrieve the size of a particular connection pool
     * @param poolName the name of the pool to get the size for
     * @return java.util.List a list containing two values. The first value is the Maximun size of the pool.
     * The second value is the Minimum size of the pool.
     */
    public List getSizeForPool(String poolName) {
        Vector results = new Vector(2);
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
            ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
            if (connectionPool != null) {
                results.add(connectionPool.getMaxNumberOfConnections());
                results.add(connectionPool.getMinNumberOfConnections());
            }
        }
        return results;
    }

    /**
     * This method provides client with access to add a new connection pool to a EclipseLink
     * ServerSession.
     * @param poolName the name of the new pool
     * @param maxSize the maximum number of connections in the pool
     * @param minSize the minimum number of connections in the pool
     * @param platform the fully qualified name of the EclipseLink platform to use with this pool.
     * @param driverClassName the fully qualified name of the JDBC driver class
     * @param url the URL of the database to connect to
     * @param userName the user name to connect to the database with
     * @param password the password to connect to the database with
     * @exception ClassNotFoundException if any of the class names are misspelled.
     */
    public void addNewConnectionPool(String poolName, int maxSize, int minSize, String platform, String driverClassName, String url, String userName, String password) throws ClassNotFoundException {
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
            DatabaseLogin login = new DatabaseLogin();
            login.setPlatformClassName(platform);
            login.setDriverClassName(driverClassName);
            login.setConnectionString(url);
            login.setUserName(userName);
            login.setEncryptedPassword(password);
            ((ServerSession)getSession()).addConnectionPool(poolName, login, minSize, maxSize);
        }
    }

    /**
     * This method is used to reset connections from the session to the database.  Please
     * Note that this will not work with a SessionBroker at this time
     */
    public void resetAllConnections() {
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
            Iterator<ConnectionPool> enumtr = ((ServerSession)getSession()).getConnectionPools().values().iterator();
            while (enumtr.hasNext()) {
                ConnectionPool pool = (ConnectionPool)enumtr.next();
                pool.shutDown();
                pool.startUp();
            }
        } else if (ClassConstants.PublicInterfaceDatabaseSession_Class.isAssignableFrom(getSession().getClass())) {
            getSession().getAccessor().reestablishConnection(getSession());
        }
    }

    /**
     *        This method is used to return those Class Names that have identity Maps in the Session.
     * Please note that SubClasses and aggregates will be missing form this list as they do not have
     * separate identity maps.
     * @return java.util.List contains all of the classes which have identity maps in the current session.
     */
    public List getClassesInSession() {
        return getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
    }

    /**
     * This method will return a collection of the objects in the Identity Map.
     * There is no particular order to these objects.
     * @param className the fully qualified classname of the class to the instances of
     * @exception ClassNotFoundException thrown then the IdentityMap for that class name could not be found
     */
    public List getObjectsInIdentityMap(String className) throws ClassNotFoundException {
        Class classToChange = getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
        IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(classToChange);

        Vector results = new Vector(map.getSize());
        Enumeration<CacheKey> objects = map.keys();
        while (objects.hasMoreElements()) {
            results.add(((CacheKey)objects.nextElement()).getObject());
        }
        return results;
    }

    /**
     *        This method is used to return the number of objects in a particular Identity Map
     * @param className the fully qualified name of the class to get number of instances of.
     * @exception ClassNotFoundException thrown then the IdentityMap for that class name could not be found
     */
    public Integer getNumberOfObjectsInIdentityMap(String className) throws ClassNotFoundException {
        Class classToChange = getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
        return getSession().getIdentityMapAccessorInstance().getIdentityMap(classToChange).getSize();
    }

    /**
     * This method is used to return a Map of the objects in a particular Identity Map's
     * subcache.  Only works for those identity Maps with a sub cache (ie Hard Cache Weak Identity Map)
     * This method replaces getObjectsInIdentityMapSubCache(className) which returns a list instead
     * of a Map
     * @param className the fully qualified name of the class to get number of instances of.
     * @exception ClassNotFoundException thrown then the IdentityMap for that class name could not be found
     */
    public List getObjectsInIdentityMapSubCacheAsMap(String className) throws ClassNotFoundException {
        Class classToChange = getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
        IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(classToChange);

        //CR3855
        List subCache = new ArrayList(0);
        if (ClassConstants.HardCacheWeakIdentityMap_Class.isAssignableFrom(map.getClass())) {
            subCache = ((HardCacheWeakIdentityMap)map).getReferenceCache();
        }
        return subCache;
    }

    /**
     * This method is used to return the number of objects in a particular Identity Map's
     * subcache.  Only works for those identity Maps with a sub cache (ie Hard Cache Weak Identity Map)
     * @param className the fully qualified name of the class to get number of instances of.
     * @exception ClassNotFoundException thrown then the IdentityMap for that class name could not be found
     */
    public Integer getNumberOfObjectsInIdentityMapSubCache(String className) throws ClassNotFoundException {
        //This needs to use the Session's active class loader (not implemented yet)
        Integer result = 0;
        Class classToChange = getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
        IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(classToChange);
        if (map.getClass().isAssignableFrom(ClassConstants.HardCacheWeakIdentityMap_Class)) {
            List subCache = ((HardCacheWeakIdentityMap)map).getReferenceCache();
            result = subCache.size();
        }
        return result;
    }

    /**
     * <p>
     * Return the log level
     * </p>
     * @param category  the string representation of an EclipseLink category, e.g. "sql", "transaction" ...
     * @return the log level
     */
    public int getLogLevel(String category) {
        return getSession().getLogLevel(category);
    }

    /**
     * <p>
     * Set the log level
     * </p>
     *
     * @param level     the new log level
     */
    public void setLogLevel(int level) {
        getSession().setLogLevel(level);
    }

    /**
     * <p>
     * Check if a message of the given level would actually be logged.
     * </p>
     *
     * @param Level  the log request level
     * @param category  the string representation of an EclipseLink category
     * @return true if the given message level will be logged
     */
    public boolean shouldLog(int Level, String category) {
        return getSession().shouldLog(Level, category);
    }

    /**
     * Return the DMS sensor weight
     */
    public int getProfileWeight() {
        if (getSession().isInProfile()) {
            return getSession().getProfiler().getProfileWeight();
        } else {
            return 0;
        }
    }

    /**
     *    This method is used to change DMS sensor weight.
     */
    public void setProfileWeight(int weight) {
        if (getSession().isInProfile()) {
            getSession().getProfiler().setProfileWeight(weight);
        }
    }

    /**
     *    This method is used to initialize the identity maps specified by className.
     * @param className the fully qualified classnames identifying the identity map to initialize
     */
     public synchronized void initializeIdentityMap(String className) throws ClassNotFoundException {
         Class registeredClass;

         //get identity map, and initialize
         registeredClass = getSession().getDatasourcePlatform().getConversionManager()
             .convertObject(className, ClassConstants.CLASS);
         getSession().getIdentityMapAccessor().initializeIdentityMap(registeredClass);
         ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_initialized", className);
     }

     /**
      *        This method will log the instance level locks in all Identity Maps in the session.
      */
      public void printIdentityMapLocks() {
          getSession().getIdentityMapAccessorInstance().getIdentityMapManager().printLocks();
      }

      /**
      *        This method will log the instance level locks in the Identity Map for the given class in the session.
      */
      public void printIdentityMapLocks(String registeredClassName) {
          Class registeredClass = getSession().getDatasourcePlatform().getConversionManager()
              .convertObject(registeredClassName, ClassConstants.CLASS);
          getSession().getIdentityMapAccessorInstance().getIdentityMapManager().printLocks(registeredClass);
      }

      /**
       *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
       *        This will log at the INFO level a summary of all elements in the profile.
       */
       public void printProfileSummary() {
           if (!this.getUsesEclipseLinkProfiling()) {
               return;
           }
           PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
           getSession().getSessionLog().info(performanceProfiler.buildProfileSummary().toString());
       }

       /**
        * INTERNAL:
        * utility method to get rid of leading and trailing {}'s
        */
       private String trimProfileString(String originalProfileString) {
           String trimmedString;

           if (originalProfileString.length() > 1) {
               trimmedString = originalProfileString.substring(0, originalProfileString.length());
               if ((trimmedString.charAt(0) == '{') && (trimmedString.charAt(trimmedString.length() - 1) == '}')) {
                   trimmedString = trimmedString.substring(1, trimmedString.length() - 1);
               }
               return trimmedString;
           } else {
               return originalProfileString;
           }
       }

       /**
       *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
       *        This will log at the INFO level a summary of all elements in the profile, categorized
       *        by Class.
       */
       public void printProfileSummaryByClass() {
           if (!this.getUsesEclipseLinkProfiling()) {
               return;
           }
           PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
           //trim the { and } from the beginning at end, because they cause problems for the logger
           getSession().getSessionLog().info(trimProfileString(performanceProfiler.buildProfileSummaryByClass().toString()));
       }

       /**
       *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
       *        This will log at the INFO level a summary of all elements in the profile, categorized
       *        by Query.
       */
       public void printProfileSummaryByQuery() {
           if (!this.getUsesEclipseLinkProfiling()) {
               return;
           }
           PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
           getSession().getSessionLog().info(trimProfileString(performanceProfiler.buildProfileSummaryByQuery().toString()));
       }

       /**
        *        This method is used to get the type of profiling.
        *   Possible values are: "EclipseLink" or "None".
        */
        public synchronized String getProfilingType() {
            if (getUsesEclipseLinkProfiling()) {
                return EclipseLink_Product_Name;
            } else {
                return "None";
            }
        }

        /**
        *        This method is used to select the type of profiling.
        *   Valid values are: "EclipseLink" or "None". These values are not case sensitive.
        *   null is considered  to be "None".
        */
        public synchronized void setProfilingType(String profileType) {
            if ((profileType == null) || (profileType.compareToIgnoreCase("None") == 0)) {
                this.setUseNoProfiling();
            } else if (profileType.compareToIgnoreCase(EclipseLink_Product_Name) == 0) {
                this.setUseEclipseLinkProfiling();
            }
        }

        /**
        *        This method is used to turn on EclipseLink Performance Profiling
        */
        public void setUseEclipseLinkProfiling() {
            if (getUsesEclipseLinkProfiling()) {
                return;
            }
            getSession().setProfiler(new PerformanceProfiler());
        }


        /**
        *        This method is used to turn off all Performance Profiling, DMS or EclipseLink.
        */
        public void setUseNoProfiling() {
            getSession().setProfiler(null);
        }

       /**
        *        This method answers true if EclipseLink Performance Profiling is on.
        */
        public Boolean getUsesEclipseLinkProfiling() {
            return getSession().getProfiler() instanceof PerformanceProfiler;
        }

        /**
         * PUBLIC: Answer the EclipseLink log level at deployment time. This is read-only.
         */
        public String getDeployedEclipseLinkLogLevel() {
            return getNameForLogLevel(getDeployedSessionLog().getLevel());
        }

        /**
         * PUBLIC: Answer the EclipseLink log level that is changeable.
         * This does not affect the log level in the project (i.e. The next
         * time the application is deployed, changes are forgotten)
         */
        public String getCurrentEclipseLinkLogLevel() {
            return getNameForLogLevel(this.getSession().getSessionLog().getLevel());
        }

        /**
         * PUBLIC: Set the EclipseLink log level to be used at runtime.
         *
         * This does not affect the log level in the project (i.e. The next
         * time the application is deployed, changes are forgotten)
         *
         * @param newLevel new log level
         */
        public synchronized void setCurrentEclipseLinkLogLevel(String newLevel) {
            this.getSession().setLogLevel(this.getLogLevelForName(newLevel));
        }

        /**
         * INTERNAL: Answer the name for the log level given.
         *
         * @return String (one of OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL)
         */
        private String getNameForLogLevel(int logLevel) {
            switch (logLevel) {
            case SessionLog.ALL:
                return SessionLog.ALL_LABEL;
            case SessionLog.SEVERE:
                return SessionLog.SEVERE_LABEL;
            case SessionLog.WARNING:
                return SessionLog.WARNING_LABEL;
            case SessionLog.INFO:
                return SessionLog.INFO_LABEL;
            case SessionLog.CONFIG:
                return SessionLog.CONFIG_LABEL;
            case SessionLog.FINE:
                return SessionLog.FINE_LABEL;
            case SessionLog.FINER:
                return SessionLog.FINER_LABEL;
            case SessionLog.FINEST:
                return SessionLog.FINEST_LABEL;
            case SessionLog.OFF:
                return SessionLog.OFF_LABEL;
            default:
                return "N/A";
            }
        }

        /**
         * INTERNAL: Answer the log level for the given name.
         *
         * @return int for OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
         */
        private int getLogLevelForName(String levelName) {
            if (levelName.equals(SessionLog.ALL_LABEL)) {
                return SessionLog.ALL;
            }
            if (levelName.equals(SessionLog.SEVERE_LABEL)) {
                return SessionLog.SEVERE;
            }
            if (levelName.equals(SessionLog.WARNING_LABEL)) {
                return SessionLog.WARNING;
            }
            if (levelName.equals(SessionLog.INFO_LABEL)) {
                return SessionLog.INFO;
            }
            if (levelName.equals(SessionLog.CONFIG_LABEL)) {
                return SessionLog.CONFIG;
            }
            if (levelName.equals(SessionLog.FINE_LABEL)) {
                return SessionLog.FINE;
            }
            if (levelName.equals(SessionLog.FINER_LABEL)) {
                return SessionLog.FINER;
            }
            if (levelName.equals(SessionLog.FINEST_LABEL)) {
                return SessionLog.FINEST;
            }
            return SessionLog.OFF;
        }
     /**
      *  INTERNAL:
      *  Define the deployment time data associated with logging and profiling
      *
      */
     protected void updateDeploymentTimeData() {
         this.deployedSessionLog = (SessionLog) session.getSessionLog().clone();
         if (session.getProfiler() == null) {
             this.deployedSessionProfileWeight = -1;//there is no profiler
         } else {
             this.deployedSessionProfileWeight = session.getProfiler().getProfileWeight();
         }
     }

     public int getDeployedSessionProfileWeight() {
         return deployedSessionProfileWeight;
     }

     public SessionLog getDeployedSessionLog() {
         return deployedSessionLog;
     }

     public String getObjectName() {
         return objectName;
     }

     /**
      * Return whether this session is an EclipseLink JPA session.
      * The absence of this function or a value of false will signify that the session
      * belongs to a provider other than EclipseLink.
      */
     public boolean isJPASession() {
         return true;
     }

     /**
      * Answer the type of the EclipseLink session this MBean represents.
      * Types include: "ServerSession", "DatabaseSession", "SessionBroker"
      */
     public String getSessionType() {
         return Helper.getShortClassName(getSession().getClass());
     }

     /**
      * Provide an instance of 2 Dimensional Array simulating tabular format information about all
      * classes in the session whose class names match the provided filter.
      *
      * The 2 Dimensional array contains each item with values being row object array. Each row object array
      * represents EclipseLink class details info with respect to below attributes:
      * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
      *
      */
     public Object[][] getClassSummaryDetailsUsingFilter(String filter){
         try{
            return  tabularDataTo2DArray(buildClassSummaryDetailsUsingFilter(filter),new String[] {
                "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" });
         } catch (Exception exception) {
             AbstractSessionLog.getLog().log(SessionLog.SEVERE, "jmx_enabled_platform_mbean_runtime_exception", PLATFORM_NAME, exception);
         }
         return null;
     }

     /**
      * PUBLIC: Provide an instance of 2 Dimensional Array simulating tabular format information about all
      * classes in the session.
      *
      * The 2 Dimensional array contains each item with values being row object array. Each row object array
      * represents EclipseLink class details info with respect to below attributes:
      * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
      *
      */
     public Object[][] getClassSummaryDetails() {
         try{
            return tabularDataTo2DArray(buildClassSummaryDetails(),new String[] {
                "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" });
         } catch (Exception exception){
             AbstractSessionLog.getLog().log(SessionLog.SEVERE, "jmx_enabled_platform_mbean_runtime_exception", PLATFORM_NAME, exception);
         }
         return null;
     }

     /**
      * INTERNAL:
      * Answer the fully qualified names of the classes mapped in the session.
      * This uses the mappedClass from the CMPPolicy.
      *
      * @return java.util.Vector
      */
     private Vector<String> getMappedClassNames() {
         Map<String, Boolean> alreadyAdded = new HashMap<>();
         Vector<String> mappedClassNames = new Vector<>();
         String mappedClassName = null;

         Iterator<ClassDescriptor> descriptorsIterator = getSession().getProject().getDescriptors()
                 .values().iterator();
         while (descriptorsIterator.hasNext()) {
             ClassDescriptor nextDescriptor = descriptorsIterator.next();

             // differentiate between a generated class and not, by comparing the descriptor's Java class
             if (nextDescriptor.getCMPPolicy() != null) {
                 if (nextDescriptor.getCMPPolicy().getMappedClass() != null) {
                     mappedClassName = nextDescriptor.getCMPPolicy().getMappedClass().getName();
                 }
             }

             if (mappedClassName == null) {
                 mappedClassName = nextDescriptor.getJavaClassName();
             }
             if (alreadyAdded.get(mappedClassName) == null) {
                 alreadyAdded.put(mappedClassName, Boolean.TRUE);
                 mappedClassNames.addElement(mappedClassName);
             }
             mappedClassName = null;
         }
         return mappedClassNames;
     }

     /**
     *  INTERNAL:
     *  This method traverses the EclipseLink descriptors and returns a Vector of the descriptor's
     *   reference class names that match the provided filter. The filter is a comma separated
     *   list of strings to match against.
     *
     *   @param filter A comma separated list of strings to match against.
     *   @return A Vector of class names that match the filter.
     */
     public Vector<String> getMappedClassNamesUsingFilter(String filter) {
         //Output Vector
         Vector<String> outputVector = new Vector<>();

         //Input mapped class names
         Vector<String> mappedClassNames = getMappedClassNames();

         //Input filter values
         List<String> filters = new ArrayList<>();
         StringTokenizer lineTokens = new StringTokenizer(filter, ",");
         while (lineTokens.hasMoreTokens()) {
             filters.add(lineTokens.nextToken());
         }
         for (int i = 0; i < mappedClassNames.size(); i++) {
             String className = (String)mappedClassNames.get(i);
             String classNameLowerCase = ((String)mappedClassNames.get(i)).toLowerCase();
             for (int j = 0; j < filters.size(); j++) {
                 String filterValue = (Helper.rightTrimString((String)filters.get(j)).trim()).toLowerCase();
                 if (filterValue.indexOf('*') == 0) {
                     filterValue = filterValue.substring(1);
                 }
                 try {
                     //Note: String.matches(String regex) since jdk1.4
                     if (classNameLowerCase.matches(new StringBuilder().append("^.*").append(filterValue).append(".*$").toString())) {
                         if (!outputVector.contains(className)) {
                             outputVector.add(className);
                         }
                     }
                 } catch (PatternSyntaxException exception) {
                     //regular expression syntax error
                     AbstractSessionLog.getLog().log(SessionLog.FINEST, "pattern_syntax_error", exception);
                 }
             }
         }
         Collections.sort(outputVector);
         return outputVector;
     }



     /**
      * INTERNAL:
      * getCacheTypeFor: Give a more UI-friendly version of the cache type
      */
     protected String getCacheTypeFor(Class identityMapClass) {
         if (identityMapClass == CacheIdentityMap.class) {
             return "Cache";
         } else if (identityMapClass == FullIdentityMap.class) {
             return "Full";
         } else if (identityMapClass == HardCacheWeakIdentityMap.class) {
             return "HardWeak";
         } else if (identityMapClass == NoIdentityMap.class) {
             return "None";
         } else if (identityMapClass == SoftCacheWeakIdentityMap.class) {
             return "SoftWeak";
         } else if (identityMapClass == WeakIdentityMap.class) {
             return "Weak";
         } else if (identityMapClass == SoftIdentityMap.class) {
             return "Soft";
         }
         return "N/A";
     }

     /**
      * getModuleName(): Answer the name of the context-root of the application that this session is associated with.
      * Answer "unknown" if there is no module name available.
      * Default behavior is to return "unknown" - we override this behavior here for WebLogic.
      */
     public String getModuleName() {
         return getSession()
             .getServerPlatform().getModuleName();
     }


     /**
      * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
      * Answer "unknown" if there is no application name available.
      * Default behavior is to return "unknown" - we override this behavior here for all platform implementors of JMXEnabledPlatform
      */
     public String getApplicationName() {
         return ((JMXEnabledPlatform) getSession()
                 .getServerPlatform()).getApplicationName();
     }

     /**
      *     Method returns if all Parameters should be bound or not
      */
     public Boolean getShouldBindAllParameters() {
         if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
             return Boolean.FALSE;
         }
         return ((DatabaseLogin) getSession().getDatasourceLogin()).shouldBindAllParameters();
     }

     /**
       *     Return the size of strings after which will be bound into the statement
       *     If we are not using a DatabaseLogin, or we're not using string binding,
       *     answer 0 (zero).
       */
     public Integer getStringBindingSize() {
         if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
             return 0;
         }
         if (!getSession().getDatasourceLogin().getPlatform().usesStringBinding()) {
             return 0;
         }
         return ((DatabaseLogin) getSession().getDatasourceLogin()).getStringBindingSize();
     }

     /**
       *        This method will return if batchWriting is in use or not.
       */
     public Boolean getUsesBatchWriting() {
         return getSession().getDatasourceLogin().getPlatform().usesBatchWriting();
     }

     /**
       *        This method will return a long indicating the exact time in Milliseconds that the
       *   session connected to the database.
       */
     public Long getTimeConnectionEstablished() {
         return ((DatabaseSessionImpl) getSession()).getConnectedTime();
     }

     /**
       *        This method will return if batchWriting is in use or not.
       */
     public Boolean getUsesJDBCBatchWriting() {
         if (!(getSession().getDatasourceLogin().getDatasourcePlatform() instanceof DatabasePlatform)) {
             return Boolean.FALSE;
         }
         return getSession().getDatasourceLogin().getPlatform().usesJDBCBatchWriting();
     }

     /**
       *     Shows if Byte Array Binding is turned on or not
       */
     public Boolean getUsesByteArrayBinding() {
         if (!(getSession().getDatasourceLogin().getDatasourcePlatform() instanceof DatabasePlatform)) {
             return Boolean.FALSE;
         }
         return getSession().getDatasourceLogin().getPlatform().usesByteArrayBinding();
     }

     /**
       *     Shows if native SQL is being used
       */
     public Boolean getUsesNativeSQL() {
         if (!(getSession().getDatasourceLogin().getDatasourcePlatform() instanceof DatabasePlatform)) {
             return Boolean.FALSE;
         }
         return getSession().getDatasourceLogin().getPlatform().usesNativeSQL();
     }

     /**
       *     This method indicates if streams are being used for binding
       */
     public Boolean getUsesStreamsForBinding() {
         if (!(getSession().getDatasourceLogin().getDatasourcePlatform() instanceof DatabasePlatform)) {
             return Boolean.FALSE;
         }
         return getSession().getDatasourceLogin().getPlatform().usesStreamsForBinding();
     }

     /**
       *     This method indicates if Strings are being bound
       */
     public Boolean getUsesStringBinding() {
         if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
             return Boolean.FALSE;
         }
         return getSession().getDatasourceLogin().getPlatform().usesStringBinding();
     }

     /**
     *     Returns if statements should be cached or not
     */
     public boolean getShouldCacheAllStatements() {
         if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
             return Boolean.FALSE;
         }
         return ((DatabaseLogin) getSession().getDatasourceLogin()).shouldCacheAllStatements();
     }

     /**
     *     Used to clear the statement cache. Only valid if statements are being cached
     */
     public synchronized void clearStatementCache() {
         if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
             return;
         }
         ((DatabaseAccessor)getSession().getAccessor()).clearStatementCache(getSession());
         ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_statement_cache_cleared");

     }

     /**
     *     This method will print the available Connection pools to the SessionLog.
     */
     public void printAvailableConnectionPools() {
         if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
             Map<String, ConnectionPool> pools = ((ServerSession)getSession()).getConnectionPools();
             Iterator<String> poolNames = pools.keySet().iterator();
             while (poolNames.hasNext()) {
                 String poolName = poolNames.next().toString();
                 ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_pool_name", poolName);
             }
         } else {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_connection_pools_available");

         }
     }

     /**
     *     This method will retrieve the max size of a particular connection pool
     * @param poolName the name of the pool to get the max size for
     * @return Integer for the max size of the pool. Return -1 if pool doesn't exist.
     */
     public Integer getMaxSizeForPool(String poolName) {
         if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
             ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
             if (connectionPool != null) {
                 return connectionPool.getMaxNumberOfConnections();
             }
         }
         return -1;
     }

     /**
     *     This method will retrieve the min size of a particular connection pool
     * @param poolName the name of the pool to get the min size for
     * @return Integer for the min size of the pool. Return -1 if pool doesn't exist.
     */
     public Integer getMinSizeForPool(String poolName) {
         if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
             ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
             if (connectionPool != null) {
                 return connectionPool.getMinNumberOfConnections();
             }
         }
         return -1;
     }

     /**
     *        This method is used to output those Class Names that have identity Maps in the Session.
     * Please note that SubClasses and aggregates will be missing from this list as they do not have
     * separate identity maps.
     */
     public void printClassesInSession() {
         Vector classes = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
         int index;
         if (classes.isEmpty()) {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_classes_in_session");
             return;
         }

         for (index = 0; index < classes.size(); index++) {
             getSession().getSessionLog().log(SessionLog.FINEST, (String)classes.elementAt(index));
         }
     }

     /**
     *        This method will log the objects in the Identity Map.
     * There is no particular order to these objects.
     * @param className the fully qualified classname identifying the identity map
     * @exception ClassNotFoundException thrown then the IdentityMap for that class name could not be found
     */
     public void printObjectsInIdentityMap(String className) throws ClassNotFoundException {
         Class classWithMap = getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
         IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(classWithMap);

         //check if the identity map exists
         if (null == map) {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_non_existent", className);
             return;
         }

         //check if there are any objects in the identity map. Print if so.
         Enumeration<CacheKey> objects = map.keys();
         if (!objects.hasMoreElements()) {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_empty", className);
         }

         CacheKey cacheKey;
         while (objects.hasMoreElements()) {
             cacheKey = (CacheKey)objects.nextElement();
             if(null != cacheKey && null != cacheKey.getKey() && null != cacheKey.getObject()) {
                 ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_print_cache_key_value",
                     cacheKey.getKey().toString(), cacheKey.getObject().toString());
             }
         }
     }

     /**
     *        This method will log the types of Identity Maps in the session.
     */
     public void printAllIdentityMapTypes() {
         Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
         String registeredClassName;
         Class registeredClass;

         //Check if there aren't any classes registered
         if (classesRegistered.size() == 0) {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
             return;
         }

         //get each identity map, and log the type
         for (int index = 0; index < classesRegistered.size(); index++) {
             registeredClassName = (String)classesRegistered.elementAt(index);
             registeredClass = getSession().getDatasourcePlatform().getConversionManager().convertObject(registeredClassName, ClassConstants.CLASS);
             IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(registeredClass);
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_class",
                     registeredClassName, map.getClass());
         }
     }

     /**
     *        This method will log all objects in all Identity Maps in the session.
     */
     public void printObjectsInIdentityMaps() {
         Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
         String registeredClassName;

         //Check if there aren't any classes registered
         if (classesRegistered.size() == 0) {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
             return;
         }

         //get each identity map, and log the type
         for (int index = 0; index < classesRegistered.size(); index++) {
             registeredClassName = (String)classesRegistered.elementAt(index);
             try {
                 this.printObjectsInIdentityMap(registeredClassName);
             } catch (ClassNotFoundException classNotFound) {
                 //we are enumerating registered classes, so this shouldn't happen. Print anyway
                 classNotFound.printStackTrace();
                 AbstractSessionLog.getLog().log(SessionLog.SEVERE, "jmx_enabled_platform_mbean_runtime_exception", PLATFORM_NAME, classNotFound);
             }
         }
     }

     /**
     *        This method will SUM and return the number of objects in all Identity Maps in the session.
     */
     public Integer getNumberOfObjectsInAllIdentityMaps() {
         Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
         String registeredClassName;
         int sum = 0;

         //Check if there aren't any classes registered
         if (classesRegistered.size() == 0) {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
             return 0;
         }

         //get each identity map, and log the size
         for (int index = 0; index < classesRegistered.size(); index++) {
             registeredClassName = (String)classesRegistered.elementAt(index);
             try {
                 sum += this.getNumberOfObjectsInIdentityMap(registeredClassName);
             } catch (ClassNotFoundException classNotFound) {
                 //we are enumerating registered classes, so this shouldn't happen. Print anyway
                 classNotFound.printStackTrace();
                 AbstractSessionLog.getLog().log(SessionLog.SEVERE, "jmx_enabled_platform_mbean_runtime_exception", PLATFORM_NAME, classNotFound);
             }
         }

         return sum;
     }

     /**
      * This method will answer the number of persistent classes contained in the session.
      * This does not include aggregates.
      */
     public Integer getNumberOfPersistentClasses() {
         Map classesTable = new HashMap();
         ClassDescriptor currentDescriptor;

         //use a table to eliminate duplicate classes. Ignore Aggregates
         Iterator<ClassDescriptor> descriptors = getSession().getProject().getDescriptors().values().iterator();
         while (descriptors.hasNext()) {
             currentDescriptor = (ClassDescriptor)descriptors.next();
             if (!currentDescriptor.isAggregateDescriptor()) {
                 classesTable.put(currentDescriptor.getJavaClassName(), Boolean.TRUE);
             }
         }

         return classesTable.size();
     }

     /**
     * Return the log type, either "EclipseLink",  "Java" or the simple name of the logging class used.
     *
     * @return the log type
     */
     public String getLogType() {
         if (this.getSession().getSessionLog().getClass() == JavaLog.class) {
             return "Java";
         } else if (this.getSession().getSessionLog().getClass() == DefaultSessionLog.class) {
             return EclipseLink_Product_Name;
         } else {
             return this.getSession().getSessionLog().getClass().getSimpleName();
         }
     }

     /**
     * Return the database platform used by the DatabaseSession.
     *
     * @return String databasePlatform
     */
     public String getDatabasePlatform() {
         return getSession().getDatasourcePlatform().getClass().getName();
     }

     /**
     *        Return JDBCConnection detail information. This includes URL and datasource information.
     */
     public synchronized String getJdbcConnectionDetails() {
         return getSession().getLogin().getConnector().getConnectionDetails();
     }

     /**
     *        Return connection pool type. Values include: "Internal", "External" and "N/A".
     */
     public synchronized String getConnectionPoolType() {
         if (getSession().getLogin().shouldUseExternalConnectionPooling()) {
             return "External";
         } else {
             return "N/A";
         }
     }

     /**
     *        Return db driver class name. This only applies to DefaultConnector. Return "N/A" otherwise.
     */
     public synchronized String getDriver() {
         if (getSession().getLogin().getConnector() instanceof DefaultConnector) {
             return getSession().getLogin().getDriverClassName();
         }
         return "N/A";
     }

     /**
     * Return the log filename. This returns the fully qualified path of the log file when
     * EclipseLink DefaultSessionLog instance is used. Null is returned otherwise.
     *
     * @return String logFilename
     */
     public String getLogFilename() {
         // returns String or null.
         if ( session.getSessionLog() instanceof DefaultSessionLog) {
                 return ((DefaultSessionLog)session.getSessionLog()).getWriterFilename();
         } else {
             return null;
         }
     }

     /**
     *    This method is used to initialize the identity maps in the session.
     */
     public synchronized void initializeAllIdentityMaps() {
         getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
     }

     /**
     *    This method is used to initialize the identity maps specified by the Vector of classNames.
     *
     * @param classNames String[] of fully qualified classnames identifying the identity maps to initialize
     */
     public synchronized void initializeIdentityMaps(String[] classNames) throws ClassNotFoundException {
         for (int index = 0; index < classNames.length; index++) {
             initializeIdentityMap(classNames[index]);
         }
     }

     /**
     *    This method is used to invalidate the identity maps in the session.
     */
     public synchronized void invalidateAllIdentityMaps() {
         Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
         String registeredClassName;
         Class registeredClass;

         if (classesRegistered.isEmpty()) {
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
         }

         //get each identity map, and invalidate
         for (int index = 0; index < classesRegistered.size(); index++) {
             registeredClassName = (String)classesRegistered.elementAt(index);
             registeredClass = getSession().getDatasourcePlatform().getConversionManager()
                 .convertObject(registeredClassName, ClassConstants.CLASS);
             getSession().getIdentityMapAccessor().invalidateClass(registeredClass);
             ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_invalidated", registeredClassName);
         }
     }

     /**
     *    This method is used to invalidate the identity maps specified by the String[] of classNames.
     *
     * @param classNamesParam String[] of fully qualified classnames identifying the identity maps to invalidate
     * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
     */
     public synchronized void invalidateIdentityMaps(String[] classNamesParam, Boolean recurse) throws ClassNotFoundException {
         String[] classNames = classNamesParam;
         for (int index = 0; index < classNames.length; index++) {
             invalidateIdentityMap(classNames[index], recurse);
         }
     }

     /**
     *    This method is used to invalidate the identity maps specified by className. This does not
     * invalidate the children identity maps
     *
     * @param className the fully qualified classname identifying the identity map to invalidate
     */
     public synchronized void invalidateIdentityMap(String className) throws ClassNotFoundException {
         this.invalidateIdentityMap(className, Boolean.FALSE);
     }

     /**
     *    This method is used to invalidate the identity maps specified by className.
     *
     * @param className the fully qualified classname identifying the identity map to invalidate
     * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
     */
     public synchronized void invalidateIdentityMap(String className, Boolean recurse) throws ClassNotFoundException {
         Class registeredClass;

         //get identity map, and invalidate
         registeredClass = getSession().getDatasourcePlatform().getConversionManager()
             .convertObject(className, ClassConstants.CLASS);
         getSession().getIdentityMapAccessor().invalidateClass(registeredClass);
         ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_invalidated", className);
     }

     /**
      *
     * INTERNAL:
      * Convert the TabularData to a two-dimensional array
      * @param tdata the TabularData to be converted
      * @param names the order of the columns
      * @return a two-dimensional array
      */
     private Object[][] tabularDataTo2DArray(TabularData tdata, String[] names) throws Exception {
         if(tdata==null){
             return null;
         }
         Object[] rows = tdata.values().toArray();
         Object[][] data = new Object[rows.length][];

         for (int i = 0; i < rows.length; i++) {
             CompositeData cdata = ((CompositeData) rows[i]);
             Object[] returnRow = new Object[names.length];
             for (int j = 0; j < names.length; j++) {
                 String name = names[j];
                 Object value = cdata.get(name);
                 returnRow[j] = name + " : " + String.valueOf(value);
             }
             data[i] = returnRow;
         }
         return data;
     }

     /**
      *  INTERNAL:
      *  Define the session that this instance is providing runtime services for
      *
      *  @param newSession The session to be used with these RuntimeServices
      */
     protected void setSession(AbstractSession newSession) {
         this.session = newSession;
         this.updateDeploymentTimeData();
     }

     /**
      * INTERNAL:
      * Answer the CompositeType describing the CompositeData that we return for
      * each IdentityMap (or subclass).
      *
      * This is mostly for the client side to see what kind of information is returned.
      * @return javax.management.openmbean.CompositeType
      */
     private CompositeType buildCompositeTypeForClassSummaryDetails() throws OpenDataException {
         return new CompositeType("Class Details", "Details of class for Class Summary", new String[] {
                 "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" }, new String[] {
                 "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" }, new OpenType[] {
                 SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING });
     }


     /**
      * Provide a list of instance of ClassSummaryDetail containing information about the
      * classes in the session whose class names match the provided filter.
      *
      * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
      * convert class attribute to JMX required open type, it has:-
      *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
      *    2. convert methods.
      *
      * @param filter A comma separated list of strings to match against.
      * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
      */
     public List<ClassSummaryDetailBase>  getClassSummaryDetailsUsingFilterArray(String filter) {
         try {
             // if the filter is null, return all the details
             Vector<String> mappedClassNames = getMappedClassNamesUsingFilter(filter);
             String mappedClassName;
             List<ClassSummaryDetailBase> classSummaryDetails = new ArrayList<>();
             // Check if there aren't any classes mapped
             if (mappedClassNames.size() == 0) {
                 return null;
             }
             CompositeType type = buildCompositeTypeForClassSummaryDetails();
             // get details for each class, and add the details to the summary
             for (int index = 0; index < mappedClassNames.size(); index++) {
                 mappedClassName = (String)mappedClassNames.elementAt(index);
                 Map<String, String> data = buildLowlevelDetailsFor(mappedClassName);
                 final CompositeDataSupport support = new CompositeDataSupport(type, buildLowlevelDetailsFor(mappedClassName));
                 classSummaryDetails.add(ClassSummaryDetailBase.from(support));
             }
             return classSummaryDetails;
         } catch (Exception openTypeException) {
             AbstractSessionLog.getLog().log(SessionLog.SEVERE, "jmx_enabled_platform_mbean_runtime_exception", PLATFORM_NAME, openTypeException);
             openTypeException.printStackTrace();
         }

         // wait to get requirements from EM
         return null;
     }

     /**
      * Provide a list of instance of ClassSummaryDetail containing information about all
      * classes in the session.
      *
      * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
      * convert class attribute to JMX required open type, it has:-
      *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
      *    2. convert methods.
      *
      * @return A List of instance of ClassSummaryDetail objects containing class information for the class names that match the filter.
      */
     public List<ClassSummaryDetailBase> getClassSummaryDetailsArray() {
         // wait to get requirements from EM
         return getClassSummaryDetailsUsingFilterArray(".*");
     }

     /**
      * INTERNAL:
      * Answer the TabularType describing the TabularData that we return from
      * getCacheSummaryDetails() and getCacheSummaryDetails(String filter)
      *
      * This is mostly for the client side to see what kind of information is returned.
      *
      * @return javax.management.openmbean.TabularType
      */
     private TabularType buildTabularTypeForClassSummaryDetails() throws OpenDataException {
         return new TabularType(getSessionName(), "Session description", buildCompositeTypeForClassSummaryDetails(),
                 new String[] { "Class Name" });
     }


     /**
      * INTERNAL:
      * Answer the CompositeData containing the cache details for the given mappedClassName
      * This uses a CompositeDataSupport, which implements CompositeData
      *
      * @param mappedClassName fullyQualified class name of the class
      * @param detailsType describes the format of the returned CompositeData

      * @return javax.management.openmbean.CompositeData
      */
     private CompositeData buildDetailsFor(String mappedClassName, CompositeType detailsType) throws Exception {
         return new CompositeDataSupport(detailsType, buildLowlevelDetailsFor(mappedClassName));
     }

     /**
      * INTERNAL:
      * Helper to build a HashMap to help in the construction of a CompositeData
      *
      * @param mappedClassName fullyQualified class name of the class

      * @return HashMap
      */
     private Map<String, String> buildLowlevelDetailsFor(String mappedClassName) {
         Class mappedClass = getSession().getDatasourcePlatform().getConversionManager().convertObject(mappedClassName, ClassConstants.CLASS);
         ClassDescriptor descriptor = getSession().getProject().getDescriptor(mappedClass);

         String cacheType = "";
         String configuredSize = "";
         String currentSize = "";
         String parentClassName = "";

         // Aggregate descriptors do not have an IdentityMap
         if (!descriptor.isAggregateDescriptor()) {
             IdentityMap identityMap = getSession().getIdentityMapAccessorInstance().getIdentityMap(descriptor);
             cacheType = getCacheTypeFor(identityMap.getClass());
             configuredSize = String.valueOf(identityMap.getMaxSize());
             //show the current size, including subclasses
             currentSize = String.valueOf(identityMap.getSize(mappedClass, true));
         }

         //If I have a parent class name, get it. Otherwise, leave blank
         if (descriptor.hasInheritance()) {
             if (descriptor.getInheritancePolicy().getParentDescriptor() != null) {
                 parentClassName = descriptor.getInheritancePolicy().getParentClassName();
             }
         }

         boolean isChildDescriptor = descriptor.isChildDescriptor();

         Map<String, String> details = new HashMap<>(5);
         details.put("Class Name", mappedClassName);
         details.put("Cache Type", (isChildDescriptor ? "" : cacheType));
         details.put("Configured Size", (isChildDescriptor ? "" : configuredSize));
         details.put("Current Size", currentSize);
         details.put("Parent Class Name", parentClassName);

         return details;
     }


     /**
      * INTERNAL:
      * Provide an instance of TabularData containing information about the
      * classes in the session whose class names match the provided filter.
      *
      * The TabularData contains rowData with values being CompositeData(s)
      *
      * CompositeData has:
      *    CompositeType: column names are ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
      *
      *  Each CompositeData can have get(myColumnName) sent to it.
      *
      *
      * @param filter A comma separated list of strings to match against.
      * @return A TabularData of information for the class names that match the filter.
      */
     private TabularData buildClassSummaryDetailsUsingFilter(String filter) {
         // if the filter is null, return all the details
         if (filter == null) {
             return buildClassSummaryDetails();
         }

         try {
             Vector<String> mappedClassNames = getMappedClassNamesUsingFilter(filter);
             String mappedClassName;
             TabularDataSupport rowData = new TabularDataSupport(buildTabularTypeForClassSummaryDetails());
             // Check if there aren't any classes mapped
             if (mappedClassNames.size() == 0) {
                 return null;
             }

             // get details for each class, and add the details to the summary
             for (int index = 0; index < mappedClassNames.size(); index++) {
                 mappedClassName = (String)mappedClassNames.elementAt(index);
                 String[] key = new String[] { mappedClassName };
                 rowData.put(key, buildDetailsFor(mappedClassName, rowData.getTabularType().getRowType()));
             }
             return rowData;
         } catch (Exception exception) {
             AbstractSessionLog.getLog().log(SessionLog.SEVERE, "jmx_enabled_platform_mbean_runtime_exception", PLATFORM_NAME, exception);
         }

         // wait to get requirements from EM
         return null;
     }

     /**
      * INTERNAL:
      * Provide an instance of TabularData containing information about all
      * classes in the session.
      *
      * The TabularData contains rowData with values being CompositeData(s)
      *
      * CompositeData has:
      *    CompositeType: column names are ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
      *
      *  Each CompositeData can have get(myColumnName) sent to it.
      *
      */
     private TabularData buildClassSummaryDetails() {
         try {
             Vector<String> mappedClassNames = getMappedClassNames();
             String mappedClassName;
             TabularDataSupport rowData = new TabularDataSupport(buildTabularTypeForClassSummaryDetails());
             // Check if there aren't any classes mapped
             if (mappedClassNames.size() == 0) {
                 return null;
             }

             // get details for each class, and add the details to the summary
             for (int index = 0; index < mappedClassNames.size(); index++) {
                 mappedClassName = (String)mappedClassNames.elementAt(index);
                 String[] key = new String[] { mappedClassName };
                 rowData.put(key, buildDetailsFor(mappedClassName, rowData.getTabularType().getRowType()));
             }

             return rowData;
         } catch (Exception exception) {
             AbstractSessionLog.getLog().log(SessionLog.SEVERE, "jmx_enabled_platform_mbean_runtime_exception", PLATFORM_NAME, exception);
         }

         // wait to get requirements from EM
         return null;
     }
}
