This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
View | Details | Raw Unified | Return to bug 316513 | Differences between
and this patch

Collapse All | Expand All

(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/CustomServerPlatform.java (-1 lines)
Lines 40-46 Link Here
40
     */
40
     */
41
    public CustomServerPlatform(DatabaseSession newDatabaseSession) {
41
    public CustomServerPlatform(DatabaseSession newDatabaseSession) {
42
        super(newDatabaseSession);
42
        super(newDatabaseSession);
43
        this.disableRuntimeServices();
44
    }
43
    }
45
44
46
    /**
45
    /**
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/jboss/JBossPlatform.java (-5 / +35 lines)
Lines 9-24 Link Here
9
 *
9
 *
10
 * Contributors:
10
 * Contributors:
11
 *     Oracle - initial API and implementation from Oracle TopLink
11
 *     Oracle - initial API and implementation from Oracle TopLink
12
 *     06/22/2010-2.2 Michael O'Brien 
13
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
14
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
12
 ******************************************************************************/  
15
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.server.jboss;
16
package org.eclipse.persistence.platform.server.jboss;
14
17
15
import javax.persistence.spi.PersistenceUnitInfo;
18
import javax.persistence.spi.PersistenceUnitInfo;
16
19
20
import org.eclipse.persistence.internal.helper.JPAClassLoaderHolder;
21
import org.eclipse.persistence.logging.AbstractSessionLog;
22
import org.eclipse.persistence.platform.server.JMXServerPlatformBase;
23
import org.eclipse.persistence.services.jboss.MBeanJBossRuntimeServices;
24
import org.eclipse.persistence.services.mbean.MBeanRuntimeServicesMBean;
17
import org.eclipse.persistence.sessions.DatabaseSession;
25
import org.eclipse.persistence.sessions.DatabaseSession;
18
import org.eclipse.persistence.transaction.jboss.JBossTransactionController;
26
import org.eclipse.persistence.transaction.jboss.JBossTransactionController;
19
import org.eclipse.persistence.internal.helper.JPAClassLoaderHolder;
20
import org.eclipse.persistence.logging.AbstractSessionLog;
21
import org.eclipse.persistence.platform.server.ServerPlatformBase;
22
27
23
/**
28
/**
24
 * PUBLIC:
29
 * PUBLIC:
Lines 30-36 Link Here
30
 * getExternalTransactionControllerClass(): to use an JBoss-specific controller class
35
 * getExternalTransactionControllerClass(): to use an JBoss-specific controller class
31
 *
36
 *
32
 */
37
 */
33
public class JBossPlatform extends ServerPlatformBase {
38
public class JBossPlatform extends JMXServerPlatformBase {
34
39
35
    /**
40
    /**
36
     * INTERNAL:
41
     * INTERNAL:
Lines 38-45 Link Here
38
     */
43
     */
39
    public JBossPlatform(DatabaseSession newDatabaseSession) {
44
    public JBossPlatform(DatabaseSession newDatabaseSession) {
40
        super(newDatabaseSession);
45
        super(newDatabaseSession);
46
        this.enableRuntimeServices();
41
    }
47
    }
42
48
49
    public boolean isJMXEnabled() {
50
        return true;
51
    }
52
    
43
    /**
53
    /**
44
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of external transaction controller to use
54
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of external transaction controller to use
45
     * for JBoss. This is read-only.
55
     * for JBoss. This is read-only.
Lines 75-79 Link Here
75
        AbstractSessionLog.getLog().log(AbstractSessionLog.WARNING, "persistence_unit_processor_jboss_temp_classloader_bypassed",//
85
        AbstractSessionLog.getLog().log(AbstractSessionLog.WARNING, "persistence_unit_processor_jboss_temp_classloader_bypassed",//
76
                puInfo.getPersistenceUnitName(), realClassLoader);
86
                puInfo.getPersistenceUnitName(), realClassLoader);
77
        return new JPAClassLoaderHolder(realClassLoader, false);
87
        return new JPAClassLoaderHolder(realClassLoader, false);
78
    }    
88
    }
89
    
90
    /**
91
     * INTERNAL: 
92
     * serverSpecificRegisterMBean(): Server specific implementation of the
93
     * creation and deployment of the JMX MBean to provide runtime services for my
94
     * databaseSession.
95
     *
96
     * @return void
97
     * @see #isRuntimeServicesEnabled()
98
     * @see #disableRuntimeServices()
99
     * @see #registerMBean()
100
     */
101
    public void serverSpecificRegisterMBean() {
102
        MBeanRuntimeServicesMBean runtimeBean = null;
103
        // No check for an existing cached MBean - we will replace it if it exists
104
        if(shouldRegisterRuntimeBean) {
105
            runtimeBean = new MBeanJBossRuntimeServices(getDatabaseSession());
106
        }
107
        genericRegisterMBean(runtimeBean);
108
    }
79
}
109
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/JMXServerPlatformBase.java (+265 lines)
Line 0 Link Here
1
package org.eclipse.persistence.platform.server;
2
3
import javax.management.InstanceAlreadyExistsException;
4
import javax.management.InstanceNotFoundException;
5
import javax.management.MBeanRegistrationException;
6
import javax.management.MBeanServer;
7
import javax.management.MBeanServerFactory;
8
import javax.management.MalformedObjectNameException;
9
import javax.management.ObjectInstance;
10
import javax.management.ObjectName;
11
12
import org.eclipse.persistence.logging.AbstractSessionLog;
13
import org.eclipse.persistence.logging.SessionLog;
14
import org.eclipse.persistence.services.mbean.MBeanDevelopmentServices;
15
import org.eclipse.persistence.services.mbean.MBeanRuntimeServicesMBean;
16
import org.eclipse.persistence.sessions.DatabaseSession;
17
18
public abstract class JMXServerPlatformBase extends ServerPlatformBase {// implements JMXEnabledPlatform {
19
20
    /** Cache the JBoss MBeanServer for performance */
21
    private MBeanServer mBeanServer = null;
22
    
23
    /** cache the RuntimeServices MBean */
24
    private MBeanRuntimeServicesMBean runtimeServicesMBean = null;    
25
26
    /** moduleName determination is available during MBean registration only */
27
    private String moduleName = null;
28
29
    /** applicationName determination is available during MBean registration only */
30
    private String applicationName = null;
31
    
32
    /**
33
     * INTERNAL:
34
     * Default Constructor: Initialize so that runtime services and JTA are enabled. Set the DatabaseSession that I
35
     * will be helping.
36
     */
37
    public JMXServerPlatformBase(DatabaseSession newDatabaseSession) {
38
        super(newDatabaseSession);
39
        /**
40
         * INTERNAL:
41
         * Answer "unknown" as a default for platforms that do not implement getModuleName()
42
         */
43
        applicationName = DEFAULT_SERVER_NAME_AND_VERSION;
44
        moduleName = DEFAULT_SERVER_NAME_AND_VERSION;        
45
    }
46
    
47
    public MBeanServer getMBeanServer() {
48
        // lazy initialize the MBeanServer reference
49
        if(null == mBeanServer) {
50
            try {
51
                mBeanServer = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0);
52
            } catch (Exception e) {
53
                e.printStackTrace();
54
            }
55
        }
56
        return mBeanServer;
57
    } 
58
    
59
    /**
60
     * INTERNAL: 
61
     * serverSpecificRegisterMBean(): Server specific implementation of the
62
     * creation and deployment of the JMX MBean to provide runtime services for my
63
     * databaseSession.
64
     *
65
     * @return void
66
     * @see #isRuntimeServicesEnabled()
67
     * @see #disableRuntimeServices()
68
     * @see #registerMBean()
69
     */
70
    public void genericRegisterMBean(MBeanRuntimeServicesMBean servicesMBean) {
71
        // get and cache module and application name during registration
72
        //initializeApplicationNameAndModuleName();
73
        MBeanServer mBeanServerRuntime = getMBeanServer();      
74
        ObjectName name = null;      
75
        String sessionName = getMBeanSessionName();
76
        if (null != sessionName && (shouldRegisterDevelopmentBean || shouldRegisterRuntimeBean)) {
77
            try {                    
78
                    // Attempt to register new mBean with the server
79
                if (null != mBeanServerRuntime && shouldRegisterDevelopmentBean) {
80
                    try {
81
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Development-" + sessionName + ",Type=Configuration");
82
                    } catch (MalformedObjectNameException mne) {
83
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", mne);
84
                    } catch (Exception exception) {
85
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", exception);
86
                    }
87
88
                    MBeanDevelopmentServices developmentMBean = new MBeanDevelopmentServices(getDatabaseSession());
89
                    ObjectInstance info = null;
90
                    try {
91
                        info = mBeanServerRuntime.registerMBean(developmentMBean, name);
92
                    } catch(InstanceAlreadyExistsException iaee) {
93
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", iaee);
94
                    } catch (MBeanRegistrationException registrationProblem) {
95
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", registrationProblem);
96
                    } catch (Exception e) {
97
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", e);
98
                    }
99
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "registered_mbean", info);
100
                }
101
102
                if (null != mBeanServerRuntime && shouldRegisterRuntimeBean) {
103
                    try {
104
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Session(" + sessionName + ")");                        
105
                    } catch (MalformedObjectNameException mne) {
106
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", mne);
107
                    } catch (Exception exception) {
108
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", exception);
109
                    }
110
                    
111
                    ObjectInstance runtimeInstance = null;
112
                    try {
113
                        runtimeInstance = mBeanServerRuntime.registerMBean(servicesMBean, name);
114
                        setRuntimeServicesMBean(servicesMBean);
115
                    } catch(InstanceAlreadyExistsException iaee) {
116
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", iaee);
117
                    } catch (MBeanRegistrationException registrationProblem) {
118
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", registrationProblem);
119
                    } catch (Exception e) {
120
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", e);
121
                    }
122
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "registered_mbean", runtimeInstance);          
123
                }
124
            } catch (Exception exception) {
125
                AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", exception);
126
            }
127
        }
128
    }
129
    
130
    /**
131
     * INTERNAL: 
132
     * serverSpecificUnregisterMBean(): Server specific implementation of the
133
     * de-registration of the JMX MBean from its server during session logout.
134
     *
135
     * @return void
136
     * @see #isRuntimeServicesEnabled()
137
     * @see #disableRuntimeServices()
138
     */
139
    public void serverSpecificUnregisterMBean() {
140
        MBeanServer mBeanServerRuntime = getMBeanServer();      
141
        ObjectName name = null;      
142
        String sessionName = getMBeanSessionName();
143
        if (null != sessionName && (shouldRegisterDevelopmentBean || shouldRegisterRuntimeBean)) {
144
            try {
145
                
146
                // Attempt to register new mBean with the server
147
                if (shouldRegisterDevelopmentBean) {
148
                    try {
149
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Development_" + sessionName + ",Type=Configuration");
150
                    } catch (MalformedObjectNameException mne) {
151
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", mne);
152
                    } catch (Exception exception) {
153
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", exception);
154
                    }
155
156
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "unregistering_mbean", name);
157
                    try {
158
                        mBeanServerRuntime.unregisterMBean(name);
159
                    } catch(InstanceNotFoundException inf) {
160
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", inf);
161
                    } catch (MBeanRegistrationException mbre) {
162
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", mbre);                        
163
                    }                                        
164
                }
165
166
                if (shouldRegisterRuntimeBean) {
167
                    try {                        
168
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Session(" + sessionName + ")");                        
169
                    } catch (MalformedObjectNameException mne) {
170
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", mne);
171
                    } catch (Exception exception) {
172
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", exception);
173
                    }
174
175
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "unregistering_mbean", name);
176
                    try {
177
                        mBeanServerRuntime.unregisterMBean(name);
178
                    } catch(InstanceNotFoundException inf) {
179
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", inf);
180
                    } catch (MBeanRegistrationException registrationProblem) {
181
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", registrationProblem);
182
                    }                              
183
                }
184
            } catch (Exception exception) {
185
                AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", exception);
186
            } finally {
187
                // de reference the mbean
188
                this.setRuntimeServicesMBean(null);
189
            }
190
        }
191
    }    
192
    
193
    /**
194
     * Remove JMX reserved characters from the session name
195
     * @param aSession
196
     * @return
197
     */
198
    protected String getMBeanSessionName() {
199
        // Check for a valid session - should never occur though        
200
        if(null != getDatabaseSession() && null != getDatabaseSession().getName()) {
201
            // remove any JMX reserved characters when the session name is file:/drive:/directory
202
            return getDatabaseSession().getName().replaceAll("[=,:]", "_");
203
        } else {
204
            AbstractSessionLog.getLog().log(SessionLog.WARNING, "session_key_for_mbean_name_is_null");
205
            return null;
206
        }
207
    }
208
209
    
210
    protected MBeanRuntimeServicesMBean getRuntimeServicesMBean() {
211
        return runtimeServicesMBean;
212
    }
213
214
    protected void setRuntimeServicesMBean(
215
            MBeanRuntimeServicesMBean runtimeServicesMBean) {
216
        this.runtimeServicesMBean = runtimeServicesMBean;
217
    }
218
219
    /**
220
     * INTERNAL: 
221
     * getModuleName(): Answer the name of the context-root of the application that this session is associated with.
222
     * Answer "unknown" if there is no module name available.
223
     * Default behavior is to return "unknown" - we override this behavior here for JBoss.
224
     * 
225
     * There are 4 levels of implementation.
226
     * 1) use the property override jboss.moduleName, or
227
     * 2) perform a reflective jboss.work.executeThreadRuntime.getModuleName() call, or
228
     * 3) extract the moduleName:persistence_unit from the jboss classloader string representation, or
229
     * 3) defer to superclass - usually return "unknown"
230
     *
231
     * @return String moduleName
232
     */
233
    @Override
234
    public String getModuleName() {        
235
        return this.moduleName;
236
    }
237
    
238
    protected void setModuleName(String aName) {
239
        moduleName = aName;
240
    }
241
    
242
    /**
243
     * INTERNAL: 
244
     * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
245
     * Answer "unknown" if there is no application name available.
246
     * Default behavior is to return "unknown" - we override this behavior here for JBoss.
247
     * 
248
     * There are 4 levels of implementation.
249
     * 1) use the property override weblogic.applicationName, or
250
     * 2) perform a reflective weblogic.work.executeThreadRuntime.getApplicationName() call, or
251
     * 3) extract the moduleName:persistence_unit from the weblogic classloader string representation, or
252
     * 3) defer to superclass - usually return "unknown"
253
     *
254
     * @return String applicationName
255
     */
256
    public String getApplicationName() {
257
        return this.applicationName;
258
    }
259
    
260
    
261
    public void setApplicationName(String aName) {
262
        applicationName = aName;
263
    }
264
265
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/NoServerPlatform.java (-1 lines)
Lines 37-43 Link Here
37
     */
37
     */
38
    public NoServerPlatform(DatabaseSession newDatabaseSession) {
38
    public NoServerPlatform(DatabaseSession newDatabaseSession) {
39
        super(newDatabaseSession);
39
        super(newDatabaseSession);
40
        this.disableRuntimeServices();
41
        this.disableJTA();
40
        this.disableJTA();
42
    }
41
    }
43
42
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/ServerPlatform.java (-1 / +3 lines)
Lines 122-127 Link Here
122
     */
122
     */
123
    public abstract boolean isJTAEnabled();
123
    public abstract boolean isJTAEnabled();
124
124
125
    public abstract boolean isJMXEnabled();
126
    
125
    /**
127
    /**
126
     * INTERNAL: disableJTA(): Configure the receiver such that my external transaction controller class will
128
     * INTERNAL: disableJTA(): Configure the receiver such that my external transaction controller class will
127
     * be ignored, and will NOT be used to populate DatabaseSession's external transaction controller class
129
     * be ignored, and will NOT be used to populate DatabaseSession's external transaction controller class
Lines 172-178 Link Here
172
     * @see #registerMBean()
174
     * @see #registerMBean()
173
     */
175
     */
174
    public abstract void unregisterMBean();
176
    public abstract void unregisterMBean();
175
177
    
176
    /**
178
    /**
177
     * INTERNAL:  This method is used to unwrap the oracle connection wrapped by
179
     * INTERNAL:  This method is used to unwrap the oracle connection wrapped by
178
     * the application server.  TopLink needs this unwrapped connection for certain
180
     * the application server.  TopLink needs this unwrapped connection for certain
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/ServerPlatformBase.java (-79 / +126 lines)
Lines 9-14 Link Here
9
 *
9
 *
10
 * Contributors:
10
 * Contributors:
11
 *     Oracle - initial API and implementation from Oracle TopLink
11
 *     Oracle - initial API and implementation from Oracle TopLink
12
 *     06/22/2010-2.2 Michael O'Brien 
13
 *       - 316509: Move JMX MBean generic registration code up from specific platforms
14
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>        
12
 ******************************************************************************/  
15
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.server;
16
package org.eclipse.persistence.platform.server;
14
17
Lines 44-50 Link Here
44
 * <li> Whether or not to enable runtime services
47
 * <li> Whether or not to enable runtime services
45
 * <li> How to launch container Threads
48
 * <li> How to launch container Threads
46
 * </ul><p>
49
 * </ul><p>
47
 * Subclasses already exist to provide configurations for Oc4J, WebLogic, JBoss, and WebSphere.
50
 * Subclasses already exist to provide configurations for Oc4J, WebLogic, JBoss, NetWeaver, GlassFish and WebSphere.
48
 * <p>
51
 * <p>
49
 * If the user wants a different external transaction controller class or
52
 * If the user wants a different external transaction controller class or
50
 * to provide some different behavior than the provided ServerPlatform(s), we recommend
53
 * to provide some different behavior than the provided ServerPlatform(s), we recommend
Lines 61-85 Link Here
61
 */
64
 */
62
public abstract class ServerPlatformBase implements ServerPlatform {
65
public abstract class ServerPlatformBase implements ServerPlatform {
63
66
67
    // Secondary override properties can be set to disable MBean registration
68
    /** This System property "eclipselink.register.dev.mbean" when set to true will enable registration/unregistration of the DevelopmentServices MBean */
69
    public static final String JMX_REGISTER_DEV_MBEAN_PROPERTY = "eclipselink.register.dev.mbean";
70
    /** This System property "eclipselink.register.run.mbean" when set to true will enable registration/unregistration of the RuntimeServices MBean */    
71
    public static final String JMX_REGISTER_RUN_MBEAN_PROPERTY = "eclipselink.register.run.mbean";
72
    /** This is the prefix for all MBeans that are registered with their specific session name appended */
73
    public static final String JMX_REGISTRATION_PREFIX = "TopLink:Name=";
64
    /**
74
    /**
65
     * externalTransactionControllerClass: This is a user-specifiable class defining the class
75
     * INTERNAL:
66
     * of external transaction controller to be set into the DatabaseSession
76
     * Answer "unknown" as a default for platforms that do not implement getModuleName()
67
     */
77
     */
68
    protected Class externalTransactionControllerClass;
78
    public static final String DEFAULT_SERVER_NAME_AND_VERSION = ToStringLocalization.buildMessage("unknown");
69
	
79
    
80
    
70
    /**
81
    /**
71
     * INTERNAL:
82
     * INTERNAL:
72
     * isRuntimeServicesEnabled: Determines if the JMX Runtime Services will be deployed at runtime
83
     * isRuntimeServicesEnabled: Determines if the JMX Runtime Services will be deployed at runtime
73
     */
84
     */
74
    private boolean isRuntimeServicesEnabled;
85
    private boolean isRuntimeServicesEnabled;
75
86
87
    // Any value such as true will turn on the MBean
88
    protected boolean shouldRegisterDevelopmentBean = false;//System.getProperty(JMX_REGISTER_DEV_MBEAN_PROPERTY) != null;
89
    protected boolean shouldRegisterRuntimeBean = true;//System.getProperty(JMX_REGISTER_RUN_MBEAN_PROPERTY) != null;
90
    
91
    
76
    /**
92
    /**
93
     * externalTransactionControllerClass: This is a user-specifiable class defining the class
94
     * of external transaction controller to be set into the DatabaseSession
95
     */
96
    protected Class externalTransactionControllerClass;
97
	
98
99
    /**
77
     * INTERNAL:
100
     * INTERNAL:
78
     * isJTAEnabled: Determines if the external transaction controller will be populated into the DatabaseSession
101
     * isJTAEnabled: Determines if the external transaction controller will be populated into the DatabaseSession
79
     * at runtime
102
     * at runtime
80
     */
103
     */
81
    private boolean isJTAEnabled;
104
    private boolean isJTAEnabled;
82
105
106
    
83
    /**
107
    /**
84
     * INTERNAL:
108
     * INTERNAL:
85
     * isCMP: true if the container created the server platform, because we're configured
109
     * isCMP: true if the container created the server platform, because we're configured
Lines 101-120 Link Here
101
    
125
    
102
    /**
126
    /**
103
     * INTERNAL:
127
     * INTERNAL:
104
     * Answer "unknown" as a default for platforms that do not implement getModuleName()
105
     */
106
    public static final String DEFAULT_SERVER_NAME_AND_VERSION = ToStringLocalization.buildMessage("unknown");
107
108
    /**
109
     * INTERNAL:
110
     * Default Constructor: Initialize so that runtime services and JTA are enabled. Set the DatabaseSession that I
128
     * Default Constructor: Initialize so that runtime services and JTA are enabled. Set the DatabaseSession that I
111
     * will be helping.
129
     * will be helping.
112
     */
130
     */
113
    public ServerPlatformBase(DatabaseSession newDatabaseSession) {
131
    public ServerPlatformBase(DatabaseSession newDatabaseSession) {
114
        this.isRuntimeServicesEnabled = true;
115
        this.isJTAEnabled = true;
132
        this.isJTAEnabled = true;
133
        // Default JMX support to true for all sub-platforms but disable parent platform where applicable
134
        this.isRuntimeServicesEnabled = false;
116
        this.databaseSession = newDatabaseSession;
135
        this.databaseSession = newDatabaseSession;
117
        this.setIsCMP(false);
136
        this.setIsCMP(false);
137
        //
138
        String shouldRegisterRuntimeBeanProperty = System.getProperty(JMX_REGISTER_RUN_MBEAN_PROPERTY);
139
        if(null != shouldRegisterRuntimeBeanProperty && shouldRegisterRuntimeBeanProperty.toLowerCase().indexOf("true") > -1) {
140
            shouldRegisterRuntimeBean = true;
141
        }
142
        String shouldRegisterDevelopmentBeanProperty = System.getProperty(JMX_REGISTER_DEV_MBEAN_PROPERTY);
143
        if(null != shouldRegisterDevelopmentBeanProperty && shouldRegisterDevelopmentBeanProperty.toLowerCase().indexOf("true") > -1) {
144
            shouldRegisterDevelopmentBean = true;
145
        }        
118
    }
146
    }
119
    
147
    
120
    /**
148
    /**
Lines 281-304 Link Here
281
        return this.isJTAEnabled;
309
        return this.isJTAEnabled;
282
    }
310
    }
283
311
284
    /**
312
    public boolean isJMXEnabled() {
285
     * INTERNAL: disableJTA(): Configure the receiver such that my external transaction controller class will
313
        return false;
286
     * be ignored, and will NOT be used to populate DatabaseSession's external transaction controller class
287
     * at runtime.
288
       *
289
       * TopLink will NOT be configured to register for callbacks for beforeCompletion and afterCompletion.
290
     *
291
     * @return void
292
     * @see #getExternalTransactionControllerClass()
293
     * @see #isJTAEnabled()
294
     */
295
    public void disableJTA() {
296
        this.ensureNotLoggedIn();
297
        this.isJTAEnabled = false;
298
    }
314
    }
299
315
    
300
    /**
316
    /**
301
     * INTERNAL: isRuntimeServicesEnabled(): Answer true if the JMX/MBean providing runtime services for
317
     * INTERNAL: 
318
     * isRuntimeServicesEnabled(): Answer true if the JMX/MBean providing runtime services for
302
     * the receiver's DatabaseSession will be deployed at runtime.
319
     * the receiver's DatabaseSession will be deployed at runtime.
303
     *
320
     *
304
     * @return boolean isRuntimeServicesEnabled
321
     * @return boolean isRuntimeServicesEnabled
Lines 307-313 Link Here
307
    public boolean isRuntimeServicesEnabled() {
324
    public boolean isRuntimeServicesEnabled() {
308
        return this.isRuntimeServicesEnabled;
325
        return this.isRuntimeServicesEnabled;
309
    }
326
    }
310
327
    
311
    /**
328
    /**
312
     * INTERNAL: disableRuntimeServices(): Configure the receiver such that no JMX/MBean will be registered
329
     * INTERNAL: disableRuntimeServices(): Configure the receiver such that no JMX/MBean will be registered
313
     * to provide runtime services for my DatabaseSession at runtime.
330
     * to provide runtime services for my DatabaseSession at runtime.
Lines 321-375 Link Here
321
    }
338
    }
322
339
323
    /**
340
    /**
324
     * INTERNAL: registerMBean(): Create and deploy the JMX MBean to provide runtime services for my
341
     * INTERNAL: 
325
     * databaseSession.
342
     * enableRuntimeServices(): Configure the receiver such that JMX/MBeans will be registered
343
     * to provide runtime services for my DatabaseSession at runtime.
326
     *
344
     *
327
     * Default is to do nothing.
328
     *
329
     * @return void
345
     * @return void
330
     * @see #isRuntimeServicesEnabled()
346
     * @see #isRuntimeServicesEnabled()
331
     * @see #disableRuntimeServices()
347
     * @since EclipseLink 2.2.0
332
     * @see #unregisterMBean()
333
     */
348
     */
334
    public void registerMBean() {
349
    public void enableRuntimeServices() {
335
        if (!this.isRuntimeServicesEnabled()) {
350
        this.ensureNotLoggedIn();
336
            return;
351
        this.isRuntimeServicesEnabled = true;
337
        }
338
        this.serverSpecificRegisterMBean();
339
    }
352
    }
340
353
    
354
    
341
    /**
355
    /**
342
     * INTERNAL: serverSpecificRegisterMBean(): Server specific implementation of the
356
     * INTERNAL: disableJTA(): Configure the receiver such that my external transaction controller class will
343
     * creation and deployment of the JMX MBean to provide runtime services for my
357
     * be ignored, and will NOT be used to populate DatabaseSession's external transaction controller class
344
     * databaseSession.
358
     * at runtime.
359
       *
360
       * TopLink will NOT be configured to register for callbacks for beforeCompletion and afterCompletion.
345
     *
361
     *
346
     * Default is to do nothing. This should be subclassed if required.
347
     *
348
     * @return void
362
     * @return void
349
     * @see #isRuntimeServicesEnabled()
363
     * @see #getExternalTransactionControllerClass()
350
     * @see #disableRuntimeServices()
364
     * @see #isJTAEnabled()
351
     * @see #registerMBean()
352
     */
365
     */
353
    public void serverSpecificRegisterMBean() {
366
    public void disableJTA() {
367
        this.ensureNotLoggedIn();
368
        this.isJTAEnabled = false;
354
    }
369
    }
355
370
356
    /**
371
    /**
357
     * INTERNAL: unregisterMBean(): Unregister the JMX MBean that was providing runtime services for my
358
     * databaseSession.
359
     *
360
     * @return void
361
     * @see #isRuntimeServicesEnabled()
362
     * @see #disableRuntimeServices()
363
     * @see #registerMBean()
364
     */
365
    public void unregisterMBean() {
366
        if (!this.isRuntimeServicesEnabled()) {
367
            return;
368
        }
369
        this.serverSpecificUnregisterMBean();
370
    }
371
372
    /**
373
     * INTERNAL:  This method is used to unwrap the connection wrapped by
372
     * INTERNAL:  This method is used to unwrap the connection wrapped by
374
     * the application server.  TopLink needs this unwrapped connection for certain
373
     * the application server.  TopLink needs this unwrapped connection for certain
375
     * database vendor specific support. (i.e. TIMESTAMPTZ,NCHAR,XMLTYPE)
374
     * database vendor specific support. (i.e. TIMESTAMPTZ,NCHAR,XMLTYPE)
Lines 386-404 Link Here
386
    }  
385
    }  
387
386
388
    /**
387
    /**
389
     * INTERNAL: serverSpecificUnregisterMBean(): Server specific implementation of the
390
     * unregistration of the JMX MBean from its server.
391
     *
392
     * Default is to do nothing. This should be subclassed if required.
393
     *
394
     * @return void
395
     * @see #isRuntimeServicesEnabled()
396
     * @see #disableRuntimeServices()
397
     */
398
    public void serverSpecificUnregisterMBean() {
399
    }
400
401
    /**
402
     * INTERNAL: launchContainerRunnable(Runnable runnable): Use the container library to
388
     * INTERNAL: launchContainerRunnable(Runnable runnable): Use the container library to
403
     * start the provided Runnable.
389
     * start the provided Runnable.
404
     *
390
     *
Lines 487-490 Link Here
487
     */
473
     */
488
    public void clearStatementCache(java.sql.Connection connection) {   
474
    public void clearStatementCache(java.sql.Connection connection) {   
489
    }
475
    }
476
    
477
    /**
478
     * INTERNAL: registerMBean(): Create and deploy the JMX MBean to provide runtime services for my
479
     * databaseSession.
480
     *
481
     * Default is to do nothing.
482
     *
483
     * @return void
484
     * @see #isRuntimeServicesEnabled()
485
     * @see #disableRuntimeServices()
486
     * @see #unregisterMBean()
487
     */
488
    public void registerMBean() {
489
        if (!this.isRuntimeServicesEnabled()) {
490
            return;
491
        }
492
        this.serverSpecificRegisterMBean();
493
    }
494
495
    /**
496
     * INTERNAL: unregisterMBean(): Unregister the JMX MBean that was providing runtime services for my
497
     * databaseSession.
498
     *
499
     * @return void
500
     * @see #isRuntimeServicesEnabled()
501
     * @see #disableRuntimeServices()
502
     * @see #registerMBean()
503
     */
504
    public void unregisterMBean() {
505
        if (!this.isRuntimeServicesEnabled()) {
506
            return;
507
        }
508
        this.serverSpecificUnregisterMBean();
509
    }
510
511
    
512
    /**
513
     * INTERNAL: serverSpecificUnregisterMBean(): Server specific implementation of the
514
     * unregistration of the JMX MBean from its server.
515
     *
516
     * Default is to do nothing. This should be subclassed if required.
517
     *
518
     * @return void
519
     * @see #isRuntimeServicesEnabled()
520
     * @see #disableRuntimeServices()
521
     */
522
    public void serverSpecificUnregisterMBean() { }
523
524
    /**
525
     * INTERNAL: serverSpecificRegisterMBean(): Server specific implementation of the
526
     * creation and deployment of the JMX MBean to provide runtime services for my
527
     * databaseSession.
528
     *
529
     * Default is to do nothing. This should be subclassed if required.
530
     *
531
     * @return void
532
     * @see #isRuntimeServicesEnabled()
533
     * @see #disableRuntimeServices()
534
     * @see #registerMBean()
535
     */
536
    public void serverSpecificRegisterMBean() { }       
490
}
537
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/was/WebSphere_7_Platform.java (-2 / +53 lines)
Lines 12-24 Link Here
12
 ******************************************************************************/  
12
 ******************************************************************************/  
13
package org.eclipse.persistence.platform.server.was;
13
package org.eclipse.persistence.platform.server.was;
14
14
15
import java.lang.reflect.Method;
16
import java.security.AccessController;
17
18
import javax.management.InstanceAlreadyExistsException;
19
import javax.management.InstanceNotFoundException;
20
import javax.management.MBeanRegistrationException;
21
import javax.management.MBeanServer;
22
import javax.management.MBeanServerFactory;
23
import javax.management.MalformedObjectNameException;
24
import javax.management.ObjectInstance;
25
import javax.management.ObjectName;
26
import javax.naming.Context;
27
import javax.naming.InitialContext;
28
import javax.naming.NamingException;
29
import javax.persistence.spi.PersistenceUnitInfo;
30
31
import org.eclipse.persistence.internal.helper.JPAClassLoaderHolder;
32
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
33
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
34
import org.eclipse.persistence.logging.AbstractSessionLog;
35
import org.eclipse.persistence.logging.SessionLog;
36
import org.eclipse.persistence.platform.JMXEnabledPlatform;
37
import org.eclipse.persistence.services.jboss.MBeanJBossRuntimeServices;
38
import org.eclipse.persistence.services.mbean.MBeanDevelopmentServices;
39
import org.eclipse.persistence.services.mbean.MBeanRuntimeServicesMBean;
40
import org.eclipse.persistence.services.websphere.MBeanWebSphereRuntimeServices;
15
import org.eclipse.persistence.sessions.DatabaseSession;
41
import org.eclipse.persistence.sessions.DatabaseSession;
42
import org.eclipse.persistence.transaction.jboss.JBossTransactionController;
16
43
17
/**
44
/**
18
 * PUBLIC:
45
 * PUBLIC:
19
 *
46
 *
20
 * This is the concrete subclass responsible for representing WebSphere 
47
 * This is the concrete subclass responsible for representing WebSphere 7 -specific server behavior.
21
 * 7 -specific server behavior.
22
 *
48
 *
23
 * This platform has:
49
 * This platform has:
24
 * - No JMX MBean runtime services
50
 * - No JMX MBean runtime services
Lines 31-35 Link Here
31
     */
57
     */
32
    public WebSphere_7_Platform(DatabaseSession newDatabaseSession) {
58
    public WebSphere_7_Platform(DatabaseSession newDatabaseSession) {
33
        super(newDatabaseSession);
59
        super(newDatabaseSession);
60
        this.enableRuntimeServices();
34
    }
61
    }
62
    
63
    public boolean isJMXEnabled() {
64
        return true;
65
    }
66
    
67
    /**
68
     * INTERNAL: 
69
     * serverSpecificRegisterMBean(): Server specific implementation of the
70
     * creation and deployment of the JMX MBean to provide runtime services for my
71
     * databaseSession.
72
     *
73
     * @return void
74
     * @see #isRuntimeServicesEnabled()
75
     * @see #disableRuntimeServices()
76
     * @see #registerMBean()
77
     */
78
    public void serverSpecificRegisterMBean() {
79
        MBeanRuntimeServicesMBean runtimeBean = null;
80
        // No check for an existing cached MBean - we will replace it if it exists
81
        if(shouldRegisterRuntimeBean) {
82
            runtimeBean = new MBeanWebSphereRuntimeServices(getDatabaseSession());
83
        }
84
        genericRegisterMBean(runtimeBean);
85
    }
35
}
86
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/was/WebSpherePlatform.java (-2 / +2 lines)
Lines 14-20 Link Here
14
14
15
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
15
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
16
import org.eclipse.persistence.logging.SessionLog;
16
import org.eclipse.persistence.logging.SessionLog;
17
import org.eclipse.persistence.platform.server.ServerPlatformBase;
17
import org.eclipse.persistence.platform.server.JMXServerPlatformBase;
18
import org.eclipse.persistence.sessions.DatabaseSession;
18
import org.eclipse.persistence.sessions.DatabaseSession;
19
19
20
import java.lang.reflect.InvocationTargetException;
20
import java.lang.reflect.InvocationTargetException;
Lines 33-39 Link Here
33
 * <li> DataSource connection unwrapping (Oracle JDBC API support)
33
 * <li> DataSource connection unwrapping (Oracle JDBC API support)
34
 * </ul>
34
 * </ul>
35
 */
35
 */
36
public class WebSpherePlatform extends ServerPlatformBase {
36
public class WebSpherePlatform extends JMXServerPlatformBase {
37
37
38
    /**
38
    /**
39
     * Cached WAS connection class used to reflectively check connections and unwrap them.
39
     * Cached WAS connection class used to reflectively check connections and unwrap them.
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/wls/WebLogic_10_Platform.java (-298 / +42 lines)
Lines 16-43 Link Here
16
 *       - 248746: Add getModuleName() implementation and new getApplicationName()
16
 *       - 248746: Add getModuleName() implementation and new getApplicationName()
17
 *     05/07/2009-1.1.1 Dave Brosius 
17
 *     05/07/2009-1.1.1 Dave Brosius 
18
 *       - 265755: [PATCH] Set application name correctly 
18
 *       - 265755: [PATCH] Set application name correctly 
19
 *     06/22/2010-2.2 Michael O'Brien 
20
 *       - 316509: Move JMX MBean generic registration code up from specific platforms
21
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>        
19
 ******************************************************************************/  
22
 ******************************************************************************/  
20
package org.eclipse.persistence.platform.server.wls;
23
package org.eclipse.persistence.platform.server.wls;
21
24
22
import java.lang.reflect.Method;
25
import java.lang.reflect.Method;
23
import java.security.AccessController;
26
import java.security.AccessController;
24
27
25
import javax.management.InstanceAlreadyExistsException;
26
import javax.management.InstanceNotFoundException;
27
import javax.management.MBeanRegistrationException;
28
import javax.management.MBeanServer;
29
import javax.management.MalformedObjectNameException;
30
import javax.management.ObjectInstance;
31
import javax.management.ObjectName;
28
import javax.management.ObjectName;
32
import javax.naming.Context;
33
import javax.naming.InitialContext;
34
import javax.naming.NamingException;
35
29
36
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
30
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
37
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
31
import org.eclipse.persistence.internal.security.PrivilegedMethodInvoker;
38
import org.eclipse.persistence.logging.AbstractSessionLog;
32
import org.eclipse.persistence.logging.AbstractSessionLog;
39
import org.eclipse.persistence.logging.SessionLog;
33
import org.eclipse.persistence.logging.SessionLog;
40
import org.eclipse.persistence.services.mbean.MBeanDevelopmentServices;
34
import org.eclipse.persistence.services.mbean.MBeanRuntimeServicesMBean;
41
import org.eclipse.persistence.services.weblogic.MBeanWebLogicRuntimeServices;
35
import org.eclipse.persistence.services.weblogic.MBeanWebLogicRuntimeServices;
42
import org.eclipse.persistence.sessions.DatabaseSession;
36
import org.eclipse.persistence.sessions.DatabaseSession;
43
37
Lines 60-85 Link Here
60
     */
54
     */
61
    /** This JNDI address is for JMX MBean unregistration */    
55
    /** This JNDI address is for JMX MBean unregistration */    
62
    private static final String JMX_JNDI_RUNTIME_UNREGISTER = "java:comp/jmx/runtime";
56
    private static final String JMX_JNDI_RUNTIME_UNREGISTER = "java:comp/jmx/runtime";
63
    /** This is the prefix for all MBeans that are registered with their specific session name appended */
64
    private static final String JMX_REGISTRATION_PREFIX = "TopLink:Name=";
65
    // Secondary override properties can be set to disable MBean registration
66
    /** This System property "eclipselink.register.dev.mbean" when set to true will enable registration/unregistration of the DevelopmentServices MBean */
67
    public static final String JMX_REGISTER_DEV_MBEAN_PROPERTY = "eclipselink.register.dev.mbean";
68
    /** This System property "eclipselink.register.run.mbean" when set to true will enable registration/unregistration of the RuntimeServices MBean */    
69
    public static final String JMX_REGISTER_RUN_MBEAN_PROPERTY = "eclipselink.register.run.mbean";
70
    /** This persistence.xml or sessions.xml property is used to override the moduleName */
57
    /** This persistence.xml or sessions.xml property is used to override the moduleName */
71
    public static final String WEBLOGIC_MODULENAME_PROPERTY = "eclipselink.weblogic.moduleName"; 
58
    protected static final String SERVER_SPECIFIC_MODULENAME_PROPERTY = "eclipselink.weblogic.moduleName"; 
72
    /** This persistence.xml or sessions.xml property is used to override the applicationName */
59
    /** This persistence.xml or sessions.xml property is used to override the applicationName */
73
    public static final String WEBLOGIC_APPLICATIONNAME_PROPERTY = "eclipselink.weblogic.applicationName"; 
60
    protected static final String SERVER_SPECIFIC_APPLICATIONNAME_PROPERTY = "eclipselink.weblogic.applicationName"; 
74
    // Any value such as true will turn on the MBean
75
    protected boolean shouldRegisterDevelopmentBean = System.getProperty(JMX_REGISTER_DEV_MBEAN_PROPERTY) != null;
76
    protected boolean shouldRegisterRuntimeBean = System.getProperty(JMX_REGISTER_RUN_MBEAN_PROPERTY) != null;
77
61
78
    /**
62
    /**
79
     * The following constants and attributes are used during reflective API calls
63
     * The following constants and attributes are used during reflective API calls
80
     */
64
     */
81
    /** Cache the WebLogic MBeanServer for performance */
65
    /** Cache the WebLogic MBeanServer for performance */
82
    private MBeanServer wlsMBeanServer = null;
66
    //private MBeanServer wlsMBeanServer = null;
83
    /** Cache the WebLogic ThreadPoolRuntime for performance */    
67
    /** Cache the WebLogic ThreadPoolRuntime for performance */    
84
    private ObjectName wlsThreadPoolRuntime = null;
68
    private ObjectName wlsThreadPoolRuntime = null;
85
    /** The JMX context when running as a module */
69
    /** The JMX context when running as a module */
Lines 97-118 Link Here
97
    /** Search String in WebLogic ClassLoader for the application:persistence_unit name */
81
    /** Search String in WebLogic ClassLoader for the application:persistence_unit name */
98
    private static final String WLS_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_PREFIX = "annotation: ";
82
    private static final String WLS_CLASSLOADER_APPLICATION_PU_SEARCH_STRING_PREFIX = "annotation: ";
99
    
83
    
100
    /** moduleName determination is available during MBean registration only */
101
    private String moduleName = null;
102
103
    /** applicationName determination is available during MBean registration only */
104
    private String applicationName = null;
105
    
106
    /** cache the RuntimeServices MBean */
107
    private MBeanWebLogicRuntimeServices runtimeServicesMBean = null;    
108
    /**
84
    /**
109
     * INTERNAL:
85
     * INTERNAL:
110
     * Default Constructor: All behavior for the default constructor is inherited
86
     * Default Constructor: All behavior for the default constructor is inherited
111
     */
87
     */
112
    public WebLogic_10_Platform(DatabaseSession newDatabaseSession) {
88
    public WebLogic_10_Platform(DatabaseSession newDatabaseSession) {
113
        super(newDatabaseSession);
89
        super(newDatabaseSession);
90
        this.enableRuntimeServices();
114
    }
91
    }
115
92
93
    public boolean isJMXEnabled() {
94
        return true;
95
    }
96
    
116
    /**
97
    /**
117
     * INTERNAL: 
98
     * INTERNAL: 
118
     * serverSpecificRegisterMBean(): Server specific implementation of the
99
     * serverSpecificRegisterMBean(): Server specific implementation of the
Lines 124-376 Link Here
124
     * @see #disableRuntimeServices()
105
     * @see #disableRuntimeServices()
125
     * @see #registerMBean()
106
     * @see #registerMBean()
126
     */
107
     */
108
    @Override
127
    public void serverSpecificRegisterMBean() {
109
    public void serverSpecificRegisterMBean() {
110
        MBeanRuntimeServicesMBean runtimeBean = null;
111
        // No check for an existing cached MBean - we will replace it if it exists
112
        if(shouldRegisterRuntimeBean) {
113
            runtimeBean = new MBeanWebLogicRuntimeServices(getDatabaseSession());
114
        }
115
        genericRegisterMBean(runtimeBean);
128
        // get and cache module and application name during registration
116
        // get and cache module and application name during registration
129
        initializeApplicationNameAndModuleName();
117
        initializeApplicationNameAndModuleName();
130
        MBeanServer mBeanServerRuntime = null;      
131
        ObjectName name = null;      
132
        String sessionName = getMBeanSessionName();
133
        Context initialContext = null;        
134
        if (null != sessionName && (shouldRegisterDevelopmentBean || shouldRegisterRuntimeBean)) {
135
            try {
136
                initialContext = new InitialContext();
137
                mBeanServerRuntime = (MBeanServer) initialContext.lookup(JMX_JNDI_RUNTIME_REGISTER);
138
                // Attempt to register new mBean with the server
139
                if (shouldRegisterDevelopmentBean) {
140
                    try {
141
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Development-" + sessionName + ",Type=Configuration");
142
                    } catch (MalformedObjectNameException mne) {
143
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", mne);
144
                    } catch (Exception exception) {
145
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", exception);
146
                    }
147
148
                    MBeanDevelopmentServices mbean = new MBeanDevelopmentServices(getDatabaseSession());
149
                    ObjectInstance info = null;
150
                    try {
151
                        info = mBeanServerRuntime.registerMBean(mbean, name);
152
                    } catch(InstanceAlreadyExistsException iaee) {
153
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", iaee);
154
                    } catch (MBeanRegistrationException registrationProblem) {
155
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", registrationProblem);
156
                    } catch (Exception e) {
157
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", e);
158
                    }
159
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "registered_mbean", info);
160
                }
161
162
                if (shouldRegisterRuntimeBean) {
163
                    try {
164
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Session(" + sessionName + ")");                        
165
                    } catch (MalformedObjectNameException mne) {
166
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", mne);
167
                    } catch (Exception exception) {
168
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", exception);
169
                    }
170
                    
171
                    MBeanWebLogicRuntimeServices runtimeServices = new MBeanWebLogicRuntimeServices(getDatabaseSession());                    
172
                    ObjectInstance runtimeInstance = null;
173
                    try {
174
                        runtimeInstance = mBeanServerRuntime.registerMBean(runtimeServices, name);
175
                        runtimeServicesMBean = runtimeServices;
176
                    } catch(InstanceAlreadyExistsException iaee) {
177
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", iaee);
178
                    } catch (MBeanRegistrationException registrationProblem) {
179
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", registrationProblem);
180
                    } catch (Exception e) {
181
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", e);
182
                    }
183
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "registered_mbean", runtimeInstance);          
184
                }
185
            } catch (NamingException ne) {
186
                AbstractSessionLog.getLog().log(SessionLog.WARNING, "failed_to_find_mbean_server", ne);
187
            } catch (Exception exception) {
188
                AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_registering_mbean", exception);
189
            } finally {
190
                // close the context
191
                // see http://forums.bea.com/thread.jspa?threadID=600004445
192
                // see http://e-docs.bea.com/wls/docs81/jndi/jndi.html#471919
193
                // see http://e-docs.bea.com/wls/docs100/jndi/jndi.html#wp467275
194
                try {
195
                    mBeanServerRuntime = null;
196
                    if(null != initialContext) {
197
                        initialContext.close();
198
                    }
199
                } catch (NamingException ne) {
200
                    // exceptions on context close will be ignored, the context will be GC'd                   
201
                }
202
            }
203
        }
204
    }
118
    }
205
206
    /**
207
     * INTERNAL: 
208
     * serverSpecificUnregisterMBean(): Server specific implementation of the
209
     * de-registration of the JMX MBean from its server during session logout.
210
     *
211
     * @return void
212
     * @see #isRuntimeServicesEnabled()
213
     * @see #disableRuntimeServices()
214
     */
215
    public void serverSpecificUnregisterMBean() {
216
        MBeanServer mBeanServerRuntime = null;      
217
        ObjectName name = null;      
218
        String sessionName = getMBeanSessionName();
219
        Context initialContext = null;        
220
        if (null != sessionName && (shouldRegisterDevelopmentBean || shouldRegisterRuntimeBean)) {
221
            try {
222
                initialContext = new InitialContext();
223
                mBeanServerRuntime = (MBeanServer) initialContext.lookup(JMX_JNDI_RUNTIME_UNREGISTER);
224
                // Attempt to register new mBean with the server
225
                if (shouldRegisterDevelopmentBean) {
226
                    try {
227
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Development_" + sessionName + ",Type=Configuration");
228
                    } catch (MalformedObjectNameException mne) {
229
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", mne);
230
                    } catch (Exception exception) {
231
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", exception);
232
                    }
233
234
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "unregistering_mbean", name);
235
                    try {
236
                        mBeanServerRuntime.unregisterMBean(name);
237
                    } catch(InstanceNotFoundException inf) {
238
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", inf);
239
                    } catch (MBeanRegistrationException mbre) {
240
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", mbre);                        
241
                    }                                        
242
                }
243
244
                if (shouldRegisterRuntimeBean) {
245
                    try {                        
246
                        name = new ObjectName(JMX_REGISTRATION_PREFIX + "Session(" + sessionName + ")");                        
247
                    } catch (MalformedObjectNameException mne) {
248
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", mne);
249
                    } catch (Exception exception) {
250
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", exception);
251
                    }
252
253
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "unregistering_mbean", name);
254
                    try {
255
                        mBeanServerRuntime.unregisterMBean(name);
256
                    } catch(InstanceNotFoundException inf) {
257
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", inf);
258
                    } catch (MBeanRegistrationException registrationProblem) {
259
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", registrationProblem);
260
                    }                              
261
                }
262
            } catch (NamingException ne) {
263
                AbstractSessionLog.getLog().log(SessionLog.WARNING, "failed_to_find_mbean_server", ne);
264
            } catch (Exception exception) {
265
                // Trap a possible WebLogic specific [weblogic.management.NoAccessRuntimeException]
266
                AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", exception);
267
            } finally {
268
                // de reference the mbean
269
                runtimeServicesMBean = null;
270
                // close the context
271
                // see http://forums.bea.com/thread.jspa?threadID=600004445
272
                // see http://e-docs.bea.com/wls/docs81/jndi/jndi.html#471919
273
                // see http://e-docs.bea.com/wls/docs100/jndi/jndi.html#wp467275
274
                try {
275
                    mBeanServerRuntime = null;
276
                    if(null != initialContext) {
277
                        initialContext.close();
278
                    }
279
                } catch (NamingException ne) {
280
                    // exceptions on context close will be ignored, the context will be GC'd
281
                }
282
            }
283
        }
284
    }
285
286
    /**
287
     * INTERNAL: 
288
     * getModuleName(): Answer the name of the context-root of the application that this session is associated with.
289
     * Answer "unknown" if there is no module name available.
290
     * Default behavior is to return "unknown" - we override this behavior here for WebLogic.
291
     * 
292
     * There are 4 levels of implementation.
293
     * 1) use the property override weblogic.moduleName, or
294
     * 2) perform a reflective weblogic.work.executeThreadRuntime.getModuleName() call (build 10.3+), or
295
     * 3) extract the moduleName:persistence_unit from the weblogic classloader string representation (build 10.3), or
296
     * 3) defer to superclass - usually return "unknown"
297
     *
298
     * @return String moduleName
299
     */
300
    public String getModuleName() {        
301
        return this.moduleName;
302
    }
303
    
119
    
304
    /**
120
    /**
305
     * INTERNAL: 
306
     * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
307
     * Answer "unknown" if there is no application name available.
308
     * Default behavior is to return "unknown" - we override this behavior here for WebLogic.
309
     * 
310
     * There are 4 levels of implementation.
311
     * 1) use the property override weblogic.applicationName, or
312
     * 2) perform a reflective weblogic.work.executeThreadRuntime.getApplicationName() call (build 10.3+), or
313
     * 3) extract the moduleName:persistence_unit from the weblogic classloader string representation (build 10.3), or
314
     * 3) defer to superclass - usually return "unknown"
315
     *
316
     * @return String applicationName
317
     */
318
    public String getApplicationName() {
319
        return this.applicationName;
320
    }
321
    
322
    /**
323
     * INTERNAL:
121
     * INTERNAL:
324
     * Get the applicationName and moduleName from the runtime WebLogic MBean reflectively
122
     * Get the applicationName and moduleName from the runtime WebLogic MBean reflectively
325
     * @return
123
     * @return
326
     */
124
     */
327
    private void initializeApplicationNameAndModuleName() {
125
    private void initializeApplicationNameAndModuleName() {
328
        // Get property from persistence.xml or sessions.xml
126
        // Get property from persistence.xml or sessions.xml
329
        String jpaModuleName = (String)getDatabaseSession().getProperty(WEBLOGIC_MODULENAME_PROPERTY);
127
        String jpaModuleName = (String)getDatabaseSession().getProperty(SERVER_SPECIFIC_MODULENAME_PROPERTY);
330
        String jpaApplicationName = (String)getDatabaseSession().getProperty(WEBLOGIC_APPLICATIONNAME_PROPERTY);      
128
        String jpaApplicationName = (String)getDatabaseSession().getProperty(SERVER_SPECIFIC_APPLICATIONNAME_PROPERTY);      
331
        
129
        
332
        if (jpaModuleName != null) {
130
        if (jpaModuleName != null) {
333
            this.moduleName = jpaModuleName;
131
            setModuleName(jpaModuleName);
334
        } else {
132
        } else {
335
        	jpaModuleName = getNameFromWeblogic(WLS_MODULE_NAME_GET_METHOD_NAME);
133
            jpaModuleName = getModuleOrApplicationName(WLS_MODULE_NAME_GET_METHOD_NAME);
336
            
134
            
337
            // If we are running a version of WebLogic 10.3 that does not support ExecuteThreadRuntime (from 10.3+) then use the ClassLoader                    
135
            // If we are running a version of WebLogic 10.3 that does not support ExecuteThreadRuntime (from 10.3+) then use the ClassLoader                    
338
            if(null != jpaModuleName && jpaModuleName.indexOf("@") != -1) {
136
            if(null != jpaModuleName && jpaModuleName.indexOf("@") != -1) {
339
                this.moduleName = jpaModuleName.substring(jpaModuleName.indexOf("@") + 1);
137
                setModuleName(jpaModuleName.substring(jpaModuleName.indexOf("@") + 1));
340
            } else {
138
            } else {
341
                this.moduleName = jpaModuleName;
139
                setModuleName(jpaModuleName);
342
            }
140
            }
343
        }
141
        }
344
142
345
        if (jpaApplicationName != null) {
143
        if (jpaApplicationName != null) {
346
            this.applicationName = jpaApplicationName;
144
            setApplicationName(jpaApplicationName);
347
        } else {
145
        } else {
348
        	jpaApplicationName = getNameFromWeblogic(WLS_APPLICATION_NAME_GET_METHOD_NAME);
146
            jpaApplicationName = getModuleOrApplicationName(WLS_APPLICATION_NAME_GET_METHOD_NAME);
349
147
350
            // defer to the superclass implementation            
148
            // defer to the superclass implementation            
351
            if(null == jpaApplicationName) {
149
            if(null == jpaApplicationName) {
352
            	jpaApplicationName = super.getApplicationName();
150
                jpaApplicationName = super.getApplicationName();
353
             }
151
             }
354
            
152
            
355
            // If we are running a version of WebLogic 10.3 that does not support ExecuteThreadRuntime (from 10.3+) then use the ClassLoader                    
153
            // If we are running a version of WebLogic 10.3 that does not support ExecuteThreadRuntime (from 10.3+) then use the ClassLoader                    
356
            if(null != jpaApplicationName && jpaApplicationName.indexOf("@") > -1) {
154
            if(null != jpaApplicationName && jpaApplicationName.indexOf("@") > -1) {
357
                this.applicationName = jpaApplicationName.substring(jpaApplicationName.indexOf("@") + 1);
155
                setApplicationName(jpaApplicationName.substring(jpaApplicationName.indexOf("@") + 1));
358
            } else {
156
            } else {
359
                this.applicationName = jpaApplicationName;                
157
                setApplicationName(jpaApplicationName);                
360
            }            
158
            }            
361
        }
159
        }
362
        
160
        
363
        // Final check for null values
161
        // TODO: remove: Final check for null values
364
        if(null == this.applicationName) {
162
        if(null == getApplicationName()) {
365
            this.applicationName = DEFAULT_SERVER_NAME_AND_VERSION;
163
            setApplicationName(DEFAULT_SERVER_NAME_AND_VERSION);
366
        }
164
        }
367
        if(null == this.moduleName) {
165
        if(null == getModuleName()) {
368
            this.moduleName = DEFAULT_SERVER_NAME_AND_VERSION;
166
            setModuleName(DEFAULT_SERVER_NAME_AND_VERSION);
369
        }
167
        }
370
        AbstractSessionLog.getLog().log(SessionLog.FINEST, "mbean_get_application_name", 
168
        AbstractSessionLog.getLog().log(SessionLog.FINEST, "mbean_get_application_name", 
371
                getDatabaseSession().getName(), this.applicationName);
169
                getDatabaseSession().getName(), getApplicationName());
372
        AbstractSessionLog.getLog().log(SessionLog.FINEST, "mbean_get_module_name", 
170
        AbstractSessionLog.getLog().log(SessionLog.FINEST, "mbean_get_module_name", 
373
                getDatabaseSession().getName(), this.moduleName);
171
                getDatabaseSession().getName(), getModuleName());
374
    }
172
    }
375
173
376
    /**
174
    /**
Lines 387-393 Link Here
387
	 *
185
	 *
388
     * @return String module|application Name from WLS
186
     * @return String module|application Name from WLS
389
     */
187
     */
390
    private String getNameFromWeblogic(String getMethodName) {
188
    private String getModuleOrApplicationName(String getMethodName) {
391
        Object classLoaderOrString = null;//this.getDatabaseSession().getPlatform().getConversionManager().getLoader();
189
        Object classLoaderOrString = null;//this.getDatabaseSession().getPlatform().getConversionManager().getLoader();
392
        Object executeThread = getExecuteThreadFromMBean();
190
        Object executeThread = getExecuteThreadFromMBean();
393
        
191
        
Lines 434-485 Link Here
434
     * @return application name or null if the name cannot be obtained
232
     * @return application name or null if the name cannot be obtained
435
     */
233
     */
436
    private Object getExecuteThreadFromMBean() {
234
    private Object getExecuteThreadFromMBean() {
437
        // Lazy load the MBeanServer instance
438
        if (wlsMBeanServer == null) {
439
            Context initialContext = null;
440
            try {
441
                initialContext = new InitialContext();
442
                try {
443
                    // The lookup string used depends on the context from which this class is being accessed, i.e. servlet, EJB, etc.
444
                    // In this case we do not know at runtime whether we are running as a module or not - so we try both lookups
445
                    // Try java:comp/env lookup  - normally used when the app is a module
446
                    wlsMBeanServer = (MBeanServer) initialContext.lookup(WLS_MODULE_ENV_CONTEXT_LOOKUP);
447
                } catch (NamingException e) {
448
                    // Lookup failed - try java:comp - this is the case when the application is not a module
449
                    try {
450
                        wlsMBeanServer = (MBeanServer) initialContext.lookup(WLS_NON_MODULE_CONTEXT_LOOKUP);
451
                    } catch (NamingException ne) {
452
                        /*
453
                         * If the MBeanServer lookup failed, continue and use the classloader as a backup method
454
                         */
455
                        AbstractSessionLog.getLog().log(SessionLog.WARNING, "jmx_mbean_runtime_services_mbeanserver_lookup_failed", ne);
456
                    }
457
                }
458
                
459
                
460
            } catch (NamingException nex) {
461
                AbstractSessionLog.getLog().log(SessionLog.WARNING, "problem_unregistering_mbean", nex);
462
            } finally {
463
                // close the context
464
                try {
465
                    if(null != initialContext) {
466
                        initialContext.close();
467
                    }
468
                } catch (NamingException ne) {
469
                    // exceptions on context close will be ignored, the context will be garbage collected
470
                }
471
            }
472
        }
473
        // Now that we know that the MBeanServer has been initialized - we use it
474
        // Initialize the threadPoolRuntime and get the executeThreadRuntime
235
        // Initialize the threadPoolRuntime and get the executeThreadRuntime
475
        //this.getDatabaseSession().getPlatform().getConversionManager().getLoader();
236
        //this.getDatabaseSession().getPlatform().getConversionManager().getLoader();
476
        if (wlsMBeanServer != null) {
237
        if (getMBeanServer() != null) {
477
            // Lazy load the ThreadPoolRuntime instance
238
            // Lazy load the ThreadPoolRuntime instance
478
            if (wlsThreadPoolRuntime == null) {
239
            if (wlsThreadPoolRuntime == null) {
479
                try {
240
                try {
480
                    ObjectName service = new ObjectName(WLS_SERVICE_KEY);
241
                    ObjectName service = new ObjectName(WLS_SERVICE_KEY);
481
                    ObjectName serverRuntime = (ObjectName) wlsMBeanServer.getAttribute(service, WLS_SERVER_RUNTIME);
242
                    ObjectName serverRuntime = (ObjectName) getMBeanServer().getAttribute(service, WLS_SERVER_RUNTIME);
482
                    wlsThreadPoolRuntime = (ObjectName) wlsMBeanServer.getAttribute(serverRuntime, WLS_THREADPOOL_RUNTIME);
243
                    wlsThreadPoolRuntime = (ObjectName) getMBeanServer().getAttribute(serverRuntime, WLS_THREADPOOL_RUNTIME);
483
                } catch (Exception ex) {
244
                } catch (Exception ex) {
484
                    AbstractSessionLog.getLog().log(SessionLog.WARNING, "jmx_mbean_runtime_services_threadpool_initialize_failed", ex);                                        
245
                    AbstractSessionLog.getLog().log(SessionLog.WARNING, "jmx_mbean_runtime_services_threadpool_initialize_failed", ex);                                        
485
                }
246
                }
Lines 488-494 Link Here
488
            if (wlsThreadPoolRuntime != null) {
249
            if (wlsThreadPoolRuntime != null) {
489
                try {
250
                try {
490
                    // Perform a reflective getExecuteThread()
251
                    // Perform a reflective getExecuteThread()
491
                    return wlsMBeanServer.invoke(wlsThreadPoolRuntime, 
252
                    return getMBeanServer().invoke(wlsThreadPoolRuntime, 
492
                            WLS_EXECUTE_THREAD_GET_METHOD_NAME, 
253
                            WLS_EXECUTE_THREAD_GET_METHOD_NAME, 
493
                            new Object[] { Thread.currentThread().getName() }, new String[] { String.class.getName() });
254
                            new Object[] { Thread.currentThread().getName() }, new String[] { String.class.getName() });
494
                } catch (Exception ex) {
255
                } catch (Exception ex) {
Lines 505-526 Link Here
505
    }
266
    }
506
    
267
    
507
    /**
268
    /**
508
     * Remove JMX reserved characters from the session name
509
     * @param aSession
510
     * @return
511
     */
512
    private String getMBeanSessionName() {
513
        // Check for a valid session - should never occur though        
514
        if(null != getDatabaseSession() && null != getDatabaseSession().getName()) {
515
            // remove any JMX reserved characters when the session name is file:/drive:/directory
516
            return getDatabaseSession().getName().replaceAll("[=,:]", "_");
517
        } else {
518
            AbstractSessionLog.getLog().log(SessionLog.WARNING, "session_key_for_mbean_name_is_null");
519
            return null;
520
        }
521
    }
522
    
523
    /**
524
     * Return the method for the WebLogic JDBC connection wrapper vendorConnection.
269
     * Return the method for the WebLogic JDBC connection wrapper vendorConnection.
525
     * WLS 10.3.4.0 added a getVendorConnectionSafe that does not invalidate the connection,
270
     * WLS 10.3.4.0 added a getVendorConnectionSafe that does not invalidate the connection,
526
     * so use this if available.
271
     * so use this if available.
Lines 537-543 Link Here
537
                }
282
                }
538
            }
283
            }
539
        }
284
        }
540
541
        return this.vendorConnectionMethod;
285
        return this.vendorConnectionMethod;
542
    }
286
    }
543
    
287
    
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/platform/server/wls/WebLogicPlatform.java (-19 / +3 lines)
Lines 18-23 Link Here
18
18
19
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
19
import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;
20
import org.eclipse.persistence.logging.SessionLog;
20
import org.eclipse.persistence.logging.SessionLog;
21
import org.eclipse.persistence.platform.server.JMXServerPlatformBase;
21
import org.eclipse.persistence.platform.server.ServerPlatformBase;
22
import org.eclipse.persistence.platform.server.ServerPlatformBase;
22
import org.eclipse.persistence.sessions.DatabaseSession;
23
import org.eclipse.persistence.sessions.DatabaseSession;
23
import org.eclipse.persistence.transaction.wls.WebLogicTransactionController;
24
import org.eclipse.persistence.transaction.wls.WebLogicTransactionController;
Lines 36-42 Link Here
36
 * information
37
 * information
37
 * </ul>
38
 * </ul>
38
 */
39
 */
39
public class WebLogicPlatform extends ServerPlatformBase {
40
public class WebLogicPlatform extends JMXServerPlatformBase {
40
41
41
    /**
42
    /**
42
     * Cached WLS connection class used to reflectively check connections and
43
     * Cached WLS connection class used to reflectively check connections and
Lines 62-67 Link Here
62
     */
63
     */
63
    public WebLogicPlatform(DatabaseSession newDatabaseSession) {
64
    public WebLogicPlatform(DatabaseSession newDatabaseSession) {
64
        super(newDatabaseSession);
65
        super(newDatabaseSession);
66
        this.disableRuntimeServices();
65
    }
67
    }
66
68
67
    /**
69
    /**
Lines 78-101 Link Here
78
    }
80
    }
79
81
80
    /**
82
    /**
81
     * INTERNAL: 
82
     * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
83
     * Answer "unknown" if there is no application name available.
84
     * Default behavior is to return "unknown" - we override this behavior here for WebLogic.
85
     * 
86
     * There are 4 levels of implementation.
87
     * 1) use the property override weblogic.applicationName, or
88
     * 2) perform a reflective weblogic.work.executeThreadRuntime.getApplicationName() call (build 10.3+), or
89
     * 3) extract the moduleName:persistence_unit from the weblogic classloader string representation (build 10.3), or
90
     * 3) defer to superclass - usually return "unknown"
91
     *
92
     * @return String applicationName
93
     */
94
    public String getApplicationName() {
95
        return DEFAULT_SERVER_NAME_AND_VERSION;
96
    }
97
    
98
    /**
99
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of
83
     * INTERNAL: getExternalTransactionControllerClass(): Answer the class of
100
     * external transaction controller to use for WebLogic. This is read-only.
84
     * external transaction controller to use for WebLogic. This is read-only.
101
     * 
85
     * 
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/jboss/ClassSummaryDetail.java (+39 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.jboss;
18
19
import org.eclipse.persistence.services.ClassSummaryDetailBase;
20
21
/**
22
 * The class is used internally by the Portable JMX Framework to convert 
23
 * model specific classes into Open Types so that the attributes of model class can
24
 * be exposed by MBeans.
25
 */
26
public class ClassSummaryDetail extends ClassSummaryDetailBase {
27
28
    public static final String COMPOSITE_TYPE_TYPENAME = "org.eclipse.persistence.services.jboss";
29
    public static final String COMPOSITE_TYPE_DESCRIPTION = "org.eclipse.persistence.services.jboss.ClassSummaryDetail";
30
31
    /**
32
     * Construct a ClassSummaryDetail instance. The PropertyNames annotation is used 
33
     * to be able to construct a ClassSummaryDetail instance out of a CompositeData
34
     * instance. See MXBeans documentation for more details.
35
     */
36
    public ClassSummaryDetail(String className, String cacheType, String configuredSize,String currentSize , String parentClassName) {
37
        super(className, cacheType, configuredSize, currentSize , parentClassName);
38
    }
39
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/jboss/JBossRuntimeServices.java (+1216 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.jboss;
18
19
import java.util.ArrayList;
20
import java.util.Collections;
21
import java.util.Enumeration;
22
import java.util.HashMap;
23
import java.util.Hashtable;
24
import java.util.Iterator;
25
import java.util.Locale;
26
import java.util.Map;
27
import java.util.StringTokenizer;
28
import java.util.Vector;
29
import java.util.regex.PatternSyntaxException;
30
31
import javax.management.openmbean.CompositeData;
32
import javax.management.openmbean.CompositeDataSupport;
33
import javax.management.openmbean.CompositeType;
34
import javax.management.openmbean.OpenDataException;
35
import javax.management.openmbean.OpenType;
36
import javax.management.openmbean.SimpleType;
37
import javax.management.openmbean.TabularData;
38
import javax.management.openmbean.TabularDataSupport;
39
import javax.management.openmbean.TabularType;
40
41
42
import org.eclipse.persistence.descriptors.ClassDescriptor;
43
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
44
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
45
import org.eclipse.persistence.internal.helper.ClassConstants;
46
import org.eclipse.persistence.internal.helper.Helper;
47
import org.eclipse.persistence.internal.identitymaps.CacheIdentityMap;
48
import org.eclipse.persistence.internal.identitymaps.CacheKey;
49
import org.eclipse.persistence.internal.identitymaps.FullIdentityMap;
50
import org.eclipse.persistence.internal.identitymaps.HardCacheWeakIdentityMap;
51
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
52
import org.eclipse.persistence.internal.identitymaps.NoIdentityMap;
53
import org.eclipse.persistence.internal.identitymaps.SoftCacheWeakIdentityMap;
54
import org.eclipse.persistence.internal.identitymaps.SoftIdentityMap;
55
import org.eclipse.persistence.internal.identitymaps.WeakIdentityMap;
56
import org.eclipse.persistence.internal.sessions.AbstractSession;
57
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
58
import org.eclipse.persistence.logging.AbstractSessionLog;
59
import org.eclipse.persistence.logging.DefaultSessionLog;
60
import org.eclipse.persistence.logging.JavaLog;
61
import org.eclipse.persistence.logging.SessionLog;
62
import org.eclipse.persistence.platform.server.jboss.JBossPlatform;
63
import org.eclipse.persistence.platform.server.wls.WebLogicPlatform;
64
import org.eclipse.persistence.services.RuntimeServices;
65
import org.eclipse.persistence.sessions.DatabaseLogin;
66
import org.eclipse.persistence.sessions.DefaultConnector;
67
import org.eclipse.persistence.sessions.server.ConnectionPool;
68
import org.eclipse.persistence.sessions.server.ServerSession;
69
import org.eclipse.persistence.tools.profiler.PerformanceProfiler;
70
71
/**
72
 * <p>
73
 * <b>Purpose</b>: Provide a dynamic interface into the EclipseLink Session.
74
 * <p>
75
 * <b>Description</b>: This class is meant to provide facilities for managing an EclipseLink session external
76
 * to EclipseLink over JMX.
77
 */
78
public class JBossRuntimeServices extends RuntimeServices {
79
80
    /**
81
     * PUBLIC:
82
     *  Default Constructor
83
     */
84
    public JBossRuntimeServices() {
85
        super();
86
    }
87
88
    /**
89
     *  PUBLIC:
90
     *  Create an instance of WebLogicRuntimeServices to be associated with the provided session
91
     *
92
     *  @param session The session to be used with these RuntimeServices
93
     *  @param String myBaseObjectName: "weblogic:....." (The JMX object name before it's wrapped in a ObjectName)
94
     */
95
    public JBossRuntimeServices(AbstractSession session) {
96
        super();
97
        this.session = session;
98
        this.updateDeploymentTimeData();
99
    }
100
101
    /**
102
     *  Create an instance of WebLogicRuntimeServices to be associated with the provided locale
103
     *
104
     *  The user must call setSession(Session) afterwards to define the session.
105
     */
106
    public JBossRuntimeServices(Locale locale) {
107
    }
108
109
    /**
110
     *  INTERNAL:
111
     *  Define the session that this instance is providing runtime services for
112
     *
113
     *  @param Session session The session to be used with these RuntimeServices
114
     */
115
    protected void setSession(AbstractSession newSession) {
116
        this.session = newSession;
117
        this.updateDeploymentTimeData();
118
    }
119
120
    /**
121
     * Answer the name of the EclipseLink session this MBean represents.
122
     */
123
    public String getSessionName() {
124
        return getSession().getName();
125
    }
126
127
    /**
128
     * Answer the type of the EclipseLink session this MBean represents.
129
     * Types include: "ServerSession", "DatabaseSession", "SessionBroker"
130
     */
131
    public String getSessionType() {
132
        return Helper.getShortClassName(getSession().getClass());
133
    }
134
135
    /**
136
     * Provide an instance of 2 Dimensional Array simulating tabular format information about all
137
     * classes in the session whose class names match the provided filter.
138
     *
139
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
140
     * represents EclipseLink class details info with respect to below attributes:  
141
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
142
     *
143
     */
144
    public Object[][] getClassSummaryDetailsUsingFilter(String filter){
145
        try{
146
           return  tabularDataTo2DArray(buildClassSummaryDetailsUsingFilter(filter),new String[] {
147
               "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" });
148
        } catch (Exception exception) {
149
           AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception); 
150
        }
151
        return null;
152
    }
153
    
154
    /**
155
     * Provide a list of instance of ClassSummaryDetail containing information about the
156
     * classes in the session whose class names match the provided filter.
157
     *
158
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
159
     * convert class attribute to JMX required open type, it has:-
160
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
161
     *    2. convert methods.  
162
     *
163
     * @param filter A comma separated list of strings to match against.
164
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
165
     */
166
    public ArrayList <ClassSummaryDetail>  getClassSummaryDetailsUsingFilterArray(String filter) {
167
        // if the filter is null, return all the details
168
        if (filter == null) {
169
            return getClassSummaryDetailsArray();
170
        }
171
172
        try {
173
            Vector mappedClassNames = getMappedClassNamesUsingFilter(filter);
174
            String mappedClassName;
175
            ArrayList classSummaryDetails = new ArrayList<ClassSummaryDetail>();
176
            // Check if there aren't any classes mapped
177
            if (mappedClassNames.size() == 0) {
178
                return null;
179
            }
180
181
            // get details for each class, and add the details to the summary
182
            for (int index = 0; index < mappedClassNames.size(); index++) {
183
                mappedClassName = (String)mappedClassNames.elementAt(index);
184
                classSummaryDetails.add(buildLowlevelDetailsFor(mappedClassName));
185
            }
186
            return classSummaryDetails;
187
        } catch (Exception openTypeException) {
188
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", openTypeException);            
189
            openTypeException.printStackTrace();
190
        }
191
192
        // wait to get requirements from EM
193
        return null;
194
    }
195
196
    /**
197
     * Provide a list of instance of ClassSummaryDetail containing information about all
198
     * classes in the session.
199
     *
200
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
201
     * convert class attribute to JMX required open type, it has:-
202
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
203
     *    2. convert methods.  
204
     *
205
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
206
     */
207
    public ArrayList <ClassSummaryDetail> getClassSummaryDetailsArray() {
208
        try {            
209
            Vector mappedClassNames = getMappedClassNames();
210
            ArrayList classSummaryDetails = new ArrayList<ClassSummaryDetail>();            
211
            // Check if there aren't any classes mapped
212
            if (mappedClassNames.size() == 0) {
213
                return null;
214
            }
215
216
            // get details for each class, and add the details to the summary
217
            for (int index = 0; index < mappedClassNames.size(); index++) {
218
                String mappedClassName = (String)mappedClassNames.elementAt(index);
219
                classSummaryDetails.add(buildLowlevelDetailsFor(mappedClassName));
220
            }
221
222
            return classSummaryDetails;
223
        } catch (Exception openTypeException) {
224
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", openTypeException);
225
            openTypeException.printStackTrace();
226
        }
227
228
        // wait to get requirements from EM
229
        return null;
230
    }
231
    
232
    /**
233
     * PUBLIC: Provide an instance of 2 Dimensional Array simulating tabular format information about all
234
     * classes in the session.
235
     *
236
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
237
     * represents EclipseLink class details info with respect to below attributes:  
238
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
239
     *
240
     */
241
    public Object[][] getClassSummaryDetails() {
242
        try{
243
           return tabularDataTo2DArray(buildClassSummaryDetails(),new String[] {
244
               "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" });
245
        } catch (Exception exception){
246
           AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception);
247
        }
248
        return null;
249
    }
250
    
251
    /**
252
     * INTERNAL:
253
     * Provide an instance of TabularData containing information about the
254
     * classes in the session whose class names match the provided filter.
255
     *
256
     * The TabularData contains rowData with values being CompositeData(s)
257
     *
258
     * CompositeData has:
259
     *    CompositeType: column names are ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
260
     *
261
     *  Each CompositeData can have get(myColumnName) sent to it.
262
     *
263
     *
264
     * @param filter A comma separated list of strings to match against.
265
     * @return A TabularData of information for the class names that match the filter.
266
     */
267
    private TabularData buildClassSummaryDetailsUsingFilter(String filter) {
268
        // if the filter is null, return all the details
269
        if (filter == null) {
270
            return buildClassSummaryDetails();
271
        }
272
273
        try {
274
            Vector mappedClassNames = getMappedClassNamesUsingFilter(filter);
275
            String mappedClassName;
276
            TabularDataSupport rowData = new TabularDataSupport(buildTabularTypeForClassSummaryDetails());
277
            // Check if there aren't any classes mapped
278
            if (mappedClassNames.size() == 0) {
279
                return null;
280
            }
281
282
            // get details for each class, and add the details to the summary
283
            for (int index = 0; index < mappedClassNames.size(); index++) {
284
                mappedClassName = (String)mappedClassNames.elementAt(index);
285
                String[] key = new String[] { mappedClassName };
286
                rowData.put(key, buildDetailsFor(mappedClassName, rowData.getTabularType().getRowType()));
287
            }
288
            return rowData;
289
        } catch (Exception exception) {
290
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception);
291
        }
292
293
        // wait to get requirements from EM
294
        return null;
295
    }
296
297
    /**
298
     * INTERNAL: 
299
     * Provide an instance of TabularData containing information about all
300
     * classes in the session.
301
     *
302
     * The TabularData contains rowData with values being CompositeData(s)
303
     *
304
     * CompositeData has:
305
     *    CompositeType: column names are ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
306
     *
307
     *  Each CompositeData can have get(myColumnName) sent to it.
308
     *
309
     */
310
    private TabularData buildClassSummaryDetails() {
311
        try {
312
            Vector mappedClassNames = getMappedClassNames();
313
            String mappedClassName;
314
            TabularDataSupport rowData = new TabularDataSupport(buildTabularTypeForClassSummaryDetails());
315
            // Check if there aren't any classes mapped
316
            if (mappedClassNames.size() == 0) {
317
                return null;
318
            }
319
320
            // get details for each class, and add the details to the summary
321
            for (int index = 0; index < mappedClassNames.size(); index++) {
322
                mappedClassName = (String)mappedClassNames.elementAt(index);
323
                String[] key = new String[] { mappedClassName };
324
                rowData.put(key, buildDetailsFor(mappedClassName, rowData.getTabularType().getRowType()));
325
            }
326
327
            return rowData;
328
        } catch (Exception exception) {
329
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception);
330
        }
331
332
        // wait to get requirements from EM
333
        return null;
334
    }
335
336
    /**
337
     * INTERNAL:
338
     * Answer the fully qualified names of the classes mapped in the session.
339
     * This uses the mappedClass from the CMPPolicy.
340
     *
341
     * @return java.util.Vector
342
     */
343
    
344
    private Vector getMappedClassNames() {
345
        Hashtable alreadyAdded = new Hashtable();
346
        Vector mappedClassNames = new Vector();
347
        String mappedClassName = null;
348
349
        Iterator descriptorsIterator = getSession().getProject().getDescriptors()
350
                .values().iterator();
351
        while (descriptorsIterator.hasNext()) {
352
            ClassDescriptor nextDescriptor = (ClassDescriptor) descriptorsIterator.next();
353
354
            // differentiate between a generated class and not, by comparing the descriptor's Java class
355
            if (nextDescriptor.getCMPPolicy() != null) {
356
                if (nextDescriptor.getCMPPolicy().getMappedClass() != null) {
357
                    mappedClassName = nextDescriptor.getCMPPolicy().getMappedClass().getName();
358
                }
359
            }
360
361
            if (mappedClassName == null) {
362
                mappedClassName = nextDescriptor.getJavaClassName();
363
            }
364
            if (alreadyAdded.get(mappedClassName) == null) {
365
                alreadyAdded.put(mappedClassName, Boolean.TRUE);
366
                mappedClassNames.addElement(mappedClassName);
367
            }
368
            mappedClassName = null;
369
        }
370
        return mappedClassNames;
371
    }
372
373
    /**
374
    *  INTERNAL:
375
    *  This method traverses the EclipseLink descriptors and returns a Vector of the descriptor's
376
    *   reference class names that match the provided filter. The filter is a comma separated
377
    *   list of strings to match against.
378
    *
379
    *   @param filter A comma separated list of strings to match against.
380
    *   @return A Vector of class names that match the filter.
381
    */
382
    public Vector getMappedClassNamesUsingFilter(String filter) {
383
        //Output Vector
384
        Vector outputVector = new Vector();
385
386
        //Input mapped class names
387
        Vector mappedClassNames = getMappedClassNames();
388
389
        //Input filter values
390
        ArrayList filters = new ArrayList();
391
        StringTokenizer lineTokens = new StringTokenizer(filter, ",");
392
        while (lineTokens.hasMoreTokens()) {
393
            filters.add(lineTokens.nextToken());
394
        }
395
        for (int i = 0; i < mappedClassNames.size(); i++) {
396
            String className = (String)mappedClassNames.get(i);
397
            String classNameLowerCase = ((String)mappedClassNames.get(i)).toLowerCase();
398
            for (int j = 0; j < filters.size(); j++) {
399
                String filterValue = (Helper.rightTrimString((String)filters.get(j)).trim()).toLowerCase();
400
                if (filterValue.indexOf('*') == 0) {
401
                    filterValue = filterValue.substring(1);
402
                }
403
                try {
404
                    //Note: String.matches(String regex) since jdk1.4
405
                    if (classNameLowerCase.matches(new StringBuffer().append("^.*").append(filterValue).append(".*$").toString())) {
406
                        if (!outputVector.contains(className)) {
407
                            outputVector.add(className);
408
                        }
409
                    }
410
                } catch (PatternSyntaxException exception) {
411
                    //regular expression syntax error
412
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "pattern_syntax_error", exception);
413
                }
414
            }
415
        }
416
        Collections.sort(outputVector);
417
        return outputVector;
418
    }
419
420
    /**
421
     * INTERNAL:
422
     * Answer the TabularType describing the TabularData that we return from
423
     * getCacheSummaryDetails() and getCacheSummaryDetails(String filter)
424
     *
425
     * This is mostly for the client side to see what kind of information is returned.
426
     *
427
     * @return javax.management.openmbean.TabularType
428
     */
429
    private TabularType buildTabularTypeForClassSummaryDetails() throws OpenDataException {
430
        return new TabularType(getSessionName(), "Session description", buildCompositeTypeForClassSummaryDetails(),
431
                new String[] { "Class Name" });
432
    }
433
434
    /**
435
     * INTERNAL:
436
     * Answer the CompositeType describing the CompositeData that we return for
437
     * each IdentityMap (or subclass).
438
     *
439
     * This is mostly for the client side to see what kind of information is returned.
440
     * @return javax.management.openmbean.CompositeType
441
     */
442
    private CompositeType buildCompositeTypeForClassSummaryDetails() throws OpenDataException {
443
        return new CompositeType("Class Details", "Details of class for Class Summary", new String[] { 
444
                "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" }, new String[] { 
445
                "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" }, new OpenType[] { 
446
                SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING });
447
    }
448
449
    /**
450
     * INTERNAL:
451
     * Answer the CompositeData containing the cache details for the given mappedClassName
452
     * This uses a CompositeDataSupport, which implements CompositeData
453
     *
454
     * @param String mappedClassName: fullyQualified class name of the class
455
     * @param CompositeType detailsType: describes the format of the returned CompositeData
456
457
     * @return javax.management.openmbean.CompositeData
458
     */
459
    private CompositeData buildDetailsFor(String mappedClassName, CompositeType detailsType) throws Exception {
460
        return new CompositeDataSupport(detailsType, buildLowlevelDetailsFor(mappedClassName));
461
    }
462
463
    /**
464
     * INTERNAL:
465
     * Helper to build a HashMap to help in the construction of a CompositeData
466
     *
467
     * @param String mappedClassName: fullyQualified class name of the class
468
469
     * @return HashMap
470
     */
471
    private HashMap buildLowlevelDetailsFor(String mappedClassName) {
472
        Class mappedClass = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(mappedClassName, ClassConstants.CLASS);
473
        IdentityMap identityMap = getSession().getIdentityMapAccessorInstance().getIdentityMap(mappedClass);
474
        ClassDescriptor descriptor = getSession().getProject().getDescriptor(mappedClass);
475
476
        String cacheType = getCacheTypeFor(identityMap.getClass());
477
        String configuredSize = "" + identityMap.getMaxSize();
478
        String currentSize = "";
479
480
        //show the current size, including subclasses 
481
        currentSize = "" + identityMap.getSize(mappedClass, true);
482
483
        String parentClassName = "";
484
485
        boolean isChildDescriptor = descriptor.isChildDescriptor();
486
487
        HashMap details = new HashMap();
488
489
        details.put("Class Name", mappedClassName);
490
        details.put("Cache Type", (isChildDescriptor ? "" : cacheType));
491
        details.put("Configured Size", (isChildDescriptor ? "" : configuredSize));
492
        details.put("Current Size", currentSize);
493
        //If I have a parent class name, get it. Otherwise, leave blank
494
        if (descriptor.hasInheritance()) {
495
            if (descriptor.getInheritancePolicy().getParentDescriptor() != null) {
496
                parentClassName = descriptor.getInheritancePolicy().getParentClassName();
497
            }
498
        }
499
        details.put("Parent Class Name", parentClassName);
500
501
        return details;
502
    }
503
504
    /**
505
     * INTERNAL:
506
     * Helper to build a HashMap to help in the construction of a CompositeData
507
     *
508
     * @param String mappedClassName: fullyQualified class name of the class
509
510
     * @return HashMap
511
     */
512
    private ClassSummaryDetail buildLowlevelDetailsForNew(String mappedClassName) {
513
        Class mappedClass = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(mappedClassName, ClassConstants.CLASS);
514
        IdentityMap identityMap = getSession().getIdentityMapAccessorInstance().getIdentityMap(mappedClass);
515
        ClassDescriptor descriptor = getSession().getProject().getDescriptor(mappedClass);
516
517
        String cacheType = getCacheTypeFor(identityMap.getClass());
518
        String configuredSize = "" + identityMap.getMaxSize();
519
        String currentSize = "";
520
521
        //show the current size, including subclasses 
522
        currentSize = "" + identityMap.getSize(mappedClass, true);
523
524
        String parentClassName = "";
525
526
        boolean isChildDescriptor = descriptor.isChildDescriptor();
527
528
        ClassSummaryDetail details = new ClassSummaryDetail(
529
                mappedClassName,
530
                (isChildDescriptor ? "" : cacheType),
531
                (isChildDescriptor ? "" : configuredSize),
532
                currentSize,
533
                parentClassName);
534
535
        return details;
536
    }
537
    
538
    /**
539
     * INTERNAL:
540
     * getCacheTypeFor: Give a more UI-friendly version of the cache type
541
     */
542
    private String getCacheTypeFor(Class identityMapClass) {
543
        if (identityMapClass == CacheIdentityMap.class) {
544
            return "Cache";
545
        } else if (identityMapClass == FullIdentityMap.class) {
546
            return "Full";
547
        } else if (identityMapClass == HardCacheWeakIdentityMap.class) {
548
            return "HardWeak";
549
        } else if (identityMapClass == NoIdentityMap.class) {
550
            return "None";
551
        } else if (identityMapClass == SoftCacheWeakIdentityMap.class) {
552
            return "SoftWeak";
553
        } else if (identityMapClass == WeakIdentityMap.class) {
554
            return "Weak";
555
        } else if (identityMapClass == SoftIdentityMap.class) {
556
            return "Soft";
557
        }
558
        return "N/A";
559
    }
560
561
    /**
562
     * getModuleName(): Answer the name of the context-root of the application that this session is associated with.
563
     * Answer "unknown" if there is no module name available.
564
     * Default behavior is to return "unknown"
565
     */
566
    public String getModuleName() {
567
        return ((DatabaseSessionImpl)getSession())
568
            .getServerPlatform().getModuleName();
569
    }
570
571
    
572
    /**
573
     * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
574
     * Answer "unknown" if there is no application name available.
575
     * Default behavior is to return "unknown"
576
     */
577
    public String getApplicationName() {
578
        return ((JBossPlatform)((DatabaseSessionImpl)getSession())
579
                .getServerPlatform()).getApplicationName();
580
    }
581
    
582
    /**
583
     * PUBLIC: Answer the EclipseLink log level at deployment time. This is read-only.
584
     */
585
    public String getDeployedEclipseLinkLogLevel() {
586
        return getNameForLogLevel(getDeployedSessionLog().getLevel());
587
    }
588
589
    /**
590
     * PUBLIC: Answer the EclipseLink log level that is changeable.
591
     * This does not affect the log level in the project (i.e. The next
592
     * time the application is deployed, changes are forgotten)
593
     */
594
    public String getCurrentEclipseLinkLogLevel() {
595
        return getNameForLogLevel(this.getSession().getSessionLog().getLevel());
596
    }
597
598
    /**
599
     * PUBLIC: Set the EclipseLink log level to be used at runtime.
600
     *
601
     * This does not affect the log level in the project (i.e. The next
602
     * time the application is deployed, changes are forgotten)
603
     *
604
     * @param String newLevel: new log level
605
     */
606
    public synchronized void setCurrentEclipseLinkLogLevel(String newLevel) {
607
        this.getSession().setLogLevel(this.getLogLevelForName(newLevel));
608
    }
609
610
    /**
611
     * INTERNAL: Answer the name for the log level given.
612
     *
613
     * @return String (one of OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL)
614
     */
615
    private String getNameForLogLevel(int logLevel) {
616
        switch (logLevel) {
617
        case SessionLog.ALL:
618
            return SessionLog.ALL_LABEL;
619
        case SessionLog.SEVERE:
620
            return SessionLog.SEVERE_LABEL;
621
        case SessionLog.WARNING:
622
            return SessionLog.WARNING_LABEL;
623
        case SessionLog.INFO:
624
            return SessionLog.INFO_LABEL;
625
        case SessionLog.CONFIG:
626
            return SessionLog.CONFIG_LABEL;
627
        case SessionLog.FINE:
628
            return SessionLog.FINE_LABEL;
629
        case SessionLog.FINER:
630
            return SessionLog.FINER_LABEL;
631
        case SessionLog.FINEST:
632
            return SessionLog.FINEST_LABEL;
633
        case SessionLog.OFF:
634
            return SessionLog.OFF_LABEL;
635
        }
636
        return "N/A";
637
    }
638
639
    /**
640
     * INTERNAL: Answer the log level for the given name.
641
     *
642
     * @return int for OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
643
     */
644
    private int getLogLevelForName(String levelName) {
645
        if (levelName.equals(SessionLog.ALL_LABEL)) {
646
            return SessionLog.ALL;
647
        }
648
        if (levelName.equals(SessionLog.SEVERE_LABEL)) {
649
            return SessionLog.SEVERE;
650
        }
651
        if (levelName.equals(SessionLog.WARNING_LABEL)) {
652
            return SessionLog.WARNING;
653
        }
654
        if (levelName.equals(SessionLog.INFO_LABEL)) {
655
            return SessionLog.INFO;
656
        }
657
        if (levelName.equals(SessionLog.CONFIG_LABEL)) {
658
            return SessionLog.CONFIG;
659
        }
660
        if (levelName.equals(SessionLog.FINE_LABEL)) {
661
            return SessionLog.FINE;
662
        }
663
        if (levelName.equals(SessionLog.FINER_LABEL)) {
664
            return SessionLog.FINER;
665
        }
666
        if (levelName.equals(SessionLog.FINEST_LABEL)) {
667
            return SessionLog.FINEST;
668
        }
669
        return SessionLog.OFF;
670
    }
671
672
    /**
673
     *     Method returns if all Parameters should be bound or not
674
     */
675
    public Boolean getShouldBindAllParameters() {
676
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
677
            return Boolean.FALSE;
678
        }
679
        return Boolean.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).shouldBindAllParameters());
680
    }
681
682
    /**
683
      *     Return the size of strings after which will be bound into the statement
684
      *     If we are not using a DatabaseLogin, or we're not using string binding,
685
      *     answer 0 (zero).
686
      */
687
    public Integer getStringBindingSize() {
688
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
689
            return Integer.valueOf(0);
690
        }
691
        if (!((DatabaseLogin)getSession().getDatasourceLogin()).getPlatform().usesStringBinding()) {
692
            return Integer.valueOf(0);
693
        }
694
        return Integer.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).getStringBindingSize());
695
    }
696
697
    /**
698
      *        This method will return if batchWriting is in use or not.
699
      */
700
    public Boolean getUsesBatchWriting() {
701
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesBatchWriting());
702
    }
703
704
    /**
705
      *        This method will return a long indicating the exact time in Milliseconds that the
706
      *   session connected to the database.
707
      */
708
    public Long getTimeConnectionEstablished() {
709
        return Long.valueOf(((DatabaseSessionImpl)getSession()).getConnectedTime());
710
    }
711
712
    /**
713
      *        This method will return if batchWriting is in use or not.
714
      */
715
    public Boolean getUsesJDBCBatchWriting() {
716
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesJDBCBatchWriting());
717
    }
718
719
    /**
720
      *     Shows if Byte Array Binding is turned on or not
721
      */
722
    public Boolean getUsesByteArrayBinding() {
723
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesByteArrayBinding());
724
    }
725
726
    /**
727
      *     Shows if native SQL is being used
728
      */
729
    public Boolean getUsesNativeSQL() {
730
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesNativeSQL());
731
    }
732
733
    /**
734
      *     This method indicates if streams are being used for binding
735
      */
736
    public Boolean getUsesStreamsForBinding() {
737
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesStreamsForBinding());
738
    }
739
740
    /**
741
      *     This method indicates if Strings are being bound
742
      */
743
    public Boolean getUsesStringBinding() {
744
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
745
            return Boolean.FALSE;
746
        }
747
        return Boolean.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).getPlatform().usesStringBinding());
748
    }
749
750
    /**
751
    *     Returns if statements should be cached or not
752
    */
753
    public boolean getShouldCacheAllStatements() {
754
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
755
            return Boolean.FALSE;
756
        }
757
        return Boolean.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).shouldCacheAllStatements());
758
    }
759
760
    /**
761
    *        Returns the statement cache size.  Only valid if statements are being cached
762
    */
763
    public int getStatementCacheSize() {
764
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
765
            return 0;
766
        }
767
        return Integer.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).getStatementCacheSize());
768
    }
769
770
    /**
771
    *     Used to clear the statement cache. Only valid if statements are being cached
772
    */
773
    public synchronized void clearStatementCache() {
774
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
775
            return;
776
        }
777
        ((DatabaseAccessor)getSession().getAccessor()).clearStatementCache(getSession());
778
        ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_statement_cache_cleared");        
779
        
780
    }
781
782
    /**
783
    *        Method returns the value of the Sequence Preallocation size
784
    */
785
    public int getSequencePreallocationSize() {
786
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
787
            return 0;
788
        }
789
        return ((DatasourcePlatform)getSession().getDatasourcePlatform()).getSequencePreallocationSize();        
790
    }
791
792
    /**
793
    *     This method will print the available Connection pools to the SessionLog.
794
    * @return void
795
    */
796
    public void printAvailableConnectionPools() {
797
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
798
            Map pools = ((ServerSession)getSession()).getConnectionPools();
799
            Iterator poolNames = pools.keySet().iterator();
800
            while (poolNames.hasNext()) {
801
                String poolName = poolNames.next().toString();
802
                ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_pool_name", poolName);
803
            }
804
        } else {
805
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_connection_pools_available");            
806
            
807
        }
808
    }
809
810
    /**
811
    *     This method will retrieve the max size of a particular connection pool
812
    * @param poolName the name of the pool to get the max size for
813
    * @return Integer for the max size of the pool. Return -1 if pool doesn't exist.
814
    */
815
    public Integer getMaxSizeForPool(String poolName) {
816
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
817
            ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
818
            if (connectionPool != null) {
819
                return Integer.valueOf(connectionPool.getMaxNumberOfConnections());
820
            }
821
        }
822
        return Integer.valueOf(-1);
823
    }
824
825
    /**
826
    *     This method will retrieve the min size of a particular connection pool
827
    * @param poolName the name of the pool to get the min size for
828
    * @return Integer for the min size of the pool. Return -1 if pool doesn't exist.
829
    */
830
    public Integer getMinSizeForPool(String poolName) {
831
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
832
            ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
833
            if (connectionPool != null) {
834
                return Integer.valueOf(connectionPool.getMinNumberOfConnections());
835
            }
836
        }
837
        return Integer.valueOf(-1);
838
    }
839
840
    /**
841
    * This method is used to reset connections from the session to the database.  Please
842
    * Note that this will not work with a SessionBroker at this time
843
    */
844
    public synchronized void resetAllConnections() {
845
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
846
            Iterator enumtr = ((ServerSession)getSession()).getConnectionPools().values().iterator();
847
            while (enumtr.hasNext()) {
848
                ConnectionPool pool = (ConnectionPool)enumtr.next();
849
                pool.shutDown();
850
                pool.startUp();
851
            }
852
        } else if (ClassConstants.PublicInterfaceDatabaseSession_Class.isAssignableFrom(getSession().getClass())) {
853
            getSession().getAccessor().reestablishConnection(getSession());
854
        }
855
    }
856
857
    /**
858
    *        This method is used to output those Class Names that have identity Maps in the Session.
859
    * Please note that SubClasses and aggregates will be missing from this list as they do not have
860
    * separate identity maps.
861
    * @return void
862
    */
863
    public void printClassesInSession() {
864
        Vector classes = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
865
        int index;
866
        if (classes.isEmpty()) {
867
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_classes_in_session");            
868
            return;
869
        }
870
871
        for (index = 0; index < classes.size(); index++) {
872
            getSession().getSessionLog().log(SessionLog.FINEST, (String)classes.elementAt(index));
873
        }
874
    }
875
876
    /**
877
    *        This method will log the objects in the Identity Map.
878
    * There is no particular order to these objects.
879
    * @param className the fully qualified classname identifying the identity map
880
    * @exception  thrown then the IdentityMap for that class name could not be found
881
    */
882
    public void printObjectsInIdentityMap(String className) throws ClassNotFoundException {
883
        Class classWithMap = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
884
        IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(classWithMap);
885
886
        //check if the identity map exists
887
        if (null == map) {
888
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_non_existent", className);
889
            return;
890
        }
891
892
        //check if there are any objects in the identity map. Print if so.
893
        Enumeration objects = map.keys();
894
        if (!objects.hasMoreElements()) {
895
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_empty", className);
896
        }
897
898
        CacheKey cacheKey;
899
        while (objects.hasMoreElements()) {
900
            cacheKey = (CacheKey)objects.nextElement();
901
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_print_cache_key_value", 
902
                    cacheKey.getKey().toString(), cacheKey.getObject().toString());
903
        }
904
    }
905
906
    /**
907
    *        This method will log the types of Identity Maps in the session.
908
    */
909
    public void printAllIdentityMapTypes() {
910
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
911
        String registeredClassName;
912
        Class registeredClass;
913
914
        //Check if there aren't any classes registered
915
        if (classesRegistered.size() == 0) {
916
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
917
            return;
918
        }
919
920
        //get each identity map, and log the type
921
        for (int index = 0; index < classesRegistered.size(); index++) {
922
            registeredClassName = (String)classesRegistered.elementAt(index);
923
            registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(registeredClassName, ClassConstants.CLASS);
924
            IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(registeredClass);
925
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_class", 
926
                    registeredClassName, map.getClass());
927
        }
928
    }
929
930
    /**
931
    *        This method will log all objects in all Identity Maps in the session.
932
    */
933
    public void printObjectsInIdentityMaps() {
934
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
935
        String registeredClassName;
936
937
        //Check if there aren't any classes registered
938
        if (classesRegistered.size() == 0) {
939
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
940
            return;
941
        }
942
943
        //get each identity map, and log the type
944
        for (int index = 0; index < classesRegistered.size(); index++) {
945
            registeredClassName = (String)classesRegistered.elementAt(index);
946
            try {
947
                this.printObjectsInIdentityMap(registeredClassName);
948
            } catch (ClassNotFoundException classNotFound) {
949
                //we are enumerating registered classes, so this shouldn't happen. Print anyway
950
                classNotFound.printStackTrace();
951
                AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", classNotFound);
952
            }
953
        }
954
    }
955
956
    /**
957
    *        This method is used to return the number of objects in a particular Identity Map
958
    * @param className the fully qualified name of the class to get number of instances of.
959
    * @exception  thrown then the IdentityMap for that class name could not be found
960
    */
961
    public Integer getNumberOfObjectsInIdentityMap(String className) throws ClassNotFoundException {
962
        //BUG 3982060: Always use the root class in combination with the identity map's getSize(class, true) to get an accurate count
963
        Class classWithIdentityMap = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
964
        Class rootClass = null;
965
966
        ClassDescriptor descriptor = getSession().getDescriptor(classWithIdentityMap);
967
        ClassDescriptor rootDescriptor;
968
969
        if (descriptor.hasInheritance()) {
970
            rootDescriptor = descriptor.getInheritancePolicy().getRootParentDescriptor();
971
        } else {
972
            rootDescriptor = descriptor;
973
        }
974
        if (rootDescriptor.getCMPPolicy() != null) {
975
            if (rootDescriptor.getCMPPolicy().getMappedClass() != null) {
976
                rootClass = rootDescriptor.getCMPPolicy().getMappedClass();
977
            }
978
        }
979
980
        if (rootClass == null) {
981
            rootClass = rootDescriptor.getJavaClass();
982
        }
983
984
        return Integer.valueOf(getSession().getIdentityMapAccessorInstance().getIdentityMap(rootClass).getSize(rootClass, true));
985
    }
986
987
    /**
988
    *        This method will SUM and return the number of objects in all Identity Maps in the session.
989
    */
990
    public Integer getNumberOfObjectsInAllIdentityMaps() {
991
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
992
        String registeredClassName;
993
        int sum = 0;
994
995
        //Check if there aren't any classes registered
996
        if (classesRegistered.size() == 0) {
997
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
998
            return Integer.valueOf(0);
999
        }
1000
1001
        //get each identity map, and log the size
1002
        for (int index = 0; index < classesRegistered.size(); index++) {
1003
            registeredClassName = (String)classesRegistered.elementAt(index);
1004
            try {
1005
                sum += this.getNumberOfObjectsInIdentityMap(registeredClassName).intValue();
1006
            } catch (ClassNotFoundException classNotFound) {
1007
                //we are enumerating registered classes, so this shouldn't happen. Print anyway
1008
                classNotFound.printStackTrace();
1009
                AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", classNotFound);
1010
            }
1011
        }
1012
1013
        return Integer.valueOf(sum);
1014
    }
1015
1016
    /**
1017
     * This method will answer the number of persistent classes contained in the session.
1018
     * This does not include aggregates.
1019
     */
1020
    public Integer getNumberOfPersistentClasses() {
1021
        Hashtable classesTable = new Hashtable();
1022
        ClassDescriptor currentDescriptor;
1023
1024
        //use a table to eliminate duplicate classes. Ignore Aggregates
1025
        Iterator descriptors = getSession().getProject().getDescriptors().values().iterator();
1026
        while (descriptors.hasNext()) {
1027
            currentDescriptor = (ClassDescriptor)descriptors.next();
1028
            if (!currentDescriptor.isAggregateDescriptor()) {
1029
                classesTable.put(currentDescriptor.getJavaClassName(), Boolean.TRUE);
1030
            }
1031
        }
1032
1033
        return Integer.valueOf(classesTable.size());
1034
    }
1035
1036
1037
    /**
1038
    * Return the log type, either "EclipseLink",  "Java" or the simple name of the logging class used.  
1039
    *
1040
    * @return the log type
1041
    */
1042
    public String getLogType() {
1043
        if (this.getSession().getSessionLog().getClass() == JavaLog.class) {
1044
            return "Java";
1045
        } else if (this.getSession().getSessionLog().getClass() == DefaultSessionLog.class) {
1046
            return EclipseLink_Product_Name;
1047
        } else {
1048
            return this.getSession().getSessionLog().getClass().getSimpleName();
1049
        }
1050
    }
1051
1052
    /**
1053
    * Return the database platform used by the DatabaseSession.
1054
    *
1055
    * @return String databasePlatform
1056
    */
1057
    public String getDatabasePlatform() {
1058
        return getSession().getDatasourcePlatform().getClass().getName();
1059
    }
1060
1061
    /**
1062
    *        Return JDBCConnection detail information. This includes URL and datasource information.
1063
    */
1064
    public synchronized String getJdbcConnectionDetails() {
1065
        return getSession().getLogin().getConnector().getConnectionDetails();
1066
    }
1067
1068
    /**
1069
    *        Return connection pool type. Values include: "Internal", "External" and "N/A".
1070
    */
1071
    public synchronized String getConnectionPoolType() {
1072
        if (getSession().getLogin().shouldUseExternalConnectionPooling()) {
1073
            return "External";
1074
        } else {
1075
            return "N/A";
1076
        }
1077
    }
1078
1079
    /**
1080
    *        Return db driver class name. This only applies to DefaultConnector. Return "N/A" otherwise.
1081
    */
1082
    public synchronized String getDriver() {
1083
        if (getSession().getLogin().getConnector() instanceof DefaultConnector) {
1084
            return getSession().getLogin().getDriverClassName();
1085
        }
1086
        return "N/A";
1087
    }
1088
1089
    /**
1090
    * Return the log filename. This returns the fully qualified path of the log file when
1091
    * EclipseLink DefaultSessionLog instance is used. Null is returned otherwise.
1092
    *
1093
    * @return String logFilename
1094
    */
1095
    public String getLogFilename() {
1096
        // returns String or null.
1097
        if ( session.getSessionLog() instanceof DefaultSessionLog) {
1098
                return ((DefaultSessionLog)session.getSessionLog()).getWriterFilename();
1099
        } else {
1100
            return null;
1101
        }
1102
    }
1103
1104
    /**
1105
    *    This method is used to initialize the identity maps in the session.
1106
    */
1107
    public synchronized void initializeAllIdentityMaps() {
1108
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
1109
    }
1110
1111
    /**
1112
    *    This method is used to initialize the identity maps specified by the Vector of classNames.
1113
    *
1114
    * @param classNames String[] of fully qualified classnames identifying the identity maps to initialize
1115
    */
1116
    public synchronized void initializeIdentityMaps(String[] classNames) throws ClassNotFoundException {
1117
        for (int index = 0; index < classNames.length; index++) {
1118
            initializeIdentityMap(classNames[index]);
1119
        }
1120
    }
1121
1122
    /**
1123
    *    This method is used to invalidate the identity maps in the session.
1124
    */
1125
    public synchronized void invalidateAllIdentityMaps() {
1126
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
1127
        String registeredClassName;
1128
        Class registeredClass;
1129
1130
        if (classesRegistered.isEmpty()) {
1131
            getSession().getSessionLog().info("There are no Identity Maps in this session");
1132
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");            
1133
        }
1134
1135
        //get each identity map, and invalidate
1136
        for (int index = 0; index < classesRegistered.size(); index++) {
1137
            registeredClassName = (String)classesRegistered.elementAt(index);
1138
            registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
1139
                .convertObject(registeredClassName, ClassConstants.CLASS);
1140
            getSession().getIdentityMapAccessor().invalidateClass(registeredClass);
1141
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_invalidated", registeredClassName);
1142
        }
1143
    }
1144
1145
    /**
1146
    *    This method is used to invalidate the identity maps specified by the String[] of classNames.
1147
    *
1148
    * @param classNames String[] of fully qualified classnames identifying the identity maps to invalidate
1149
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
1150
    */
1151
    public synchronized void invalidateIdentityMaps(String[] classNamesParam, Boolean recurse) throws ClassNotFoundException {
1152
        String[] classNames = classNamesParam;
1153
        for (int index = 0; index < classNames.length; index++) {
1154
            invalidateIdentityMap(classNames[index], recurse);
1155
        }
1156
    }
1157
1158
    /**
1159
    *    This method is used to invalidate the identity maps specified by className. This does not
1160
    * invalidate the children identity maps
1161
    *
1162
    * @param className the fully qualified classname identifying the identity map to invalidate
1163
    */
1164
    public synchronized void invalidateIdentityMap(String className) throws ClassNotFoundException {
1165
        this.invalidateIdentityMap(className, Boolean.FALSE);
1166
    }
1167
1168
    /**
1169
    *    This method is used to invalidate the identity maps specified by className.
1170
    *
1171
    * @param className the fully qualified classname identifying the identity map to invalidate
1172
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
1173
    */
1174
    public synchronized void invalidateIdentityMap(String className, Boolean recurse) throws ClassNotFoundException {
1175
        Class registeredClass;
1176
1177
        //get identity map, and invalidate
1178
        registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
1179
            .convertObject(className, ClassConstants.CLASS);
1180
        getSession().getIdentityMapAccessor().invalidateClass(registeredClass);
1181
        ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_invalidated", className);
1182
    }
1183
1184
    /**
1185
     * 
1186
    * INTERNAL:
1187
     * Convert the TabularData to a two-dimensional array
1188
     * @param tdata the TabularData to be converted
1189
     * @param names the order of the columns
1190
     * @return a two-dimensional array
1191
     * @throws Exception
1192
     */
1193
    private Object[][] tabularDataTo2DArray(TabularData tdata, String[] names) throws Exception {
1194
        if(tdata==null){
1195
            return null;
1196
        }
1197
        Object[] rows = tdata.values().toArray();
1198
        Object[][] data = new Object[rows.length][];
1199
1200
        for (int i=0; i<rows.length; i++) {
1201
            data[i] = ((CompositeData) rows[i]).getAll(names);
1202
        }
1203
        return data;
1204
    }
1205
    
1206
    
1207
    /**
1208
     * Return whether this session is an EclipseLink JPA session.
1209
     * The absence of this function or a value of false will signify that the session
1210
     * belongs to a provider other than EclipseLink.  
1211
     * @return
1212
     */
1213
    public boolean isJPASession() {
1214
        return true;
1215
    }
1216
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/jboss/MBeanJBossRuntimeServices.java (+34 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.jboss;
18
19
import org.eclipse.persistence.internal.sessions.AbstractSession;
20
import org.eclipse.persistence.sessions.Session;
21
22
/**
23
 * <p>
24
 * <b>Purpose</b>: Provide a dynamic interface into the EclipseLink Session.
25
 * <p>
26
 * <b>Description</b>: This class is meant to provide a framework for gaining access to configuration
27
 * of the EclipseLink Session during runtime.  It will provide the basis for development
28
 * of a JMX service and possibly other frameworks.
29
 */
30
public class MBeanJBossRuntimeServices extends JBossRuntimeServices implements MBeanJBossRuntimeServicesMBean {
31
    public MBeanJBossRuntimeServices(Session session) {
32
        super((AbstractSession)session);
33
    }
34
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/jboss/MBeanJBossRuntimeServicesMBean.java (+384 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.jboss;
18
19
import java.util.ArrayList;
20
import java.util.Vector;
21
22
import org.eclipse.persistence.services.mbean.MBeanRuntimeServicesMBean;
23
24
/**
25
 * <p>
26
 * <b>Purpose</b>: Provide a dynamic interface into the EclipseLink Session.
27
 * <p>
28
 * <b>Description</b>: This class is meant to provide facilities for managing an EclipseLink session external
29
 * to EclipseLink over JMX.
30
 */
31
public interface MBeanJBossRuntimeServicesMBean extends MBeanRuntimeServicesMBean {
32
    /**
33
     *  Answer the name of the EclipseLink session this MBean represents.
34
     */
35
    public String getSessionName();
36
37
    /**
38
     *  Answer the type of the EclipseLink session this MBean represents.
39
     * Types include: "ServerSession", "DatabaseSession", "SessionBroker"
40
     */
41
    public String getSessionType();
42
43
    /**
44
     *  Provide an instance of 2 Dimensional Array simulating tabular format information about all
45
     * classes in the session whose class names match the provided filter.
46
     *
47
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
48
     * represents EclipseLink class details info with respect to below attributes:  
49
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
50
     *
51
     */
52
    public Object[][] getClassSummaryDetailsUsingFilter(String filter);
53
    
54
    /**
55
     *  Provide an instance of 2 Dimensional Array simulating tabular format information about all
56
     * classes in the session.
57
     *
58
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
59
     * represents EclipseLink class details info with respect to below attributes:  
60
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
61
     *
62
     */
63
    public Object[][] getClassSummaryDetails();
64
    
65
    /**
66
     *  Provide a list of instance of ClassSummaryDetail containing information about the
67
     * classes in the session whose class names match the provided filter.
68
     *
69
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
70
     * convert class attribute to JMX required open type, it has:-
71
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
72
     *    2. convert methods.  
73
     *
74
     * @param filter A comma separated list of strings to match against.
75
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
76
     */
77
    public ArrayList <ClassSummaryDetail>  getClassSummaryDetailsUsingFilterArray(String filter);
78
    
79
    /**
80
     *  Provide a list of instance of ClassSummaryDetail containing information about all
81
     * classes in the session.
82
     *
83
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
84
     * convert class attribute to JMX required open type, it has:-
85
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
86
     *    2. convert methods.  
87
     *
88
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
89
     */
90
    public ArrayList <ClassSummaryDetail>  getClassSummaryDetailsArray();
91
92
    /**
93
    *  INTERNAL:
94
    *  This method traverses the EclipseLink descriptors and returns a Vector of the descriptor's
95
    *   reference class names that match the provided filter. The filter is a comma separated
96
    *   list of strings to match against.
97
    *
98
    *   @param filter A comma separated list of strings to match against.
99
    *   @return A Vector of class names that match the filter.
100
    */
101
    public Vector getMappedClassNamesUsingFilter(String filter);
102
103
    /**
104
     * getModuleName(): Answer the name of the context-root of the application that this session is associated with.
105
     * Answer "unknown" if there is no module name available.
106
     * Default behavior is to return "unknown" 
107
     */
108
    public String getModuleName();
109
    
110
    /**
111
     * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
112
     * Answer "unknown" if there is no application name available.
113
     * Default behavior is to return "unknown"
114
     */
115
    public String getApplicationName();
116
117
    /**
118
     *  Answer the EclipseLink log level at deployment time. This is read-only.
119
     */
120
    public String getDeployedEclipseLinkLogLevel();
121
122
    /**
123
     *  Answer the EclipseLink log level that is changeable.
124
     * This does not affect the log level in the project (i.e. The next
125
     * time the application is deployed, changes are forgotten)
126
     */
127
    public String getCurrentEclipseLinkLogLevel();
128
129
    /**
130
     *  Set the EclipseLink log level to be used at runtime.
131
     *
132
     * This does not affect the log level in the project (i.e. The next
133
     * time the application is deployed, changes are forgotten)
134
     *
135
     * @param String newLevel: new log level
136
     */
137
    public  void setCurrentEclipseLinkLogLevel(String newLevel);
138
139
    /**
140
    *        This method is used to get the type of profiling.
141
    *   Possible values are: "EclipseLink" or "None".
142
    */
143
    public  String getProfilingType();
144
145
    /**
146
    *        This method is used to select the type of profiling.
147
    *   Valid values are: "EclipseLink" or "None". These values are not case sensitive.
148
    *   null is considered  to be "None".
149
    */
150
    public  void setProfilingType(String profileType);
151
152
    /**
153
    *        This method is used to turn on EclipseLink Performance Profiling
154
    */
155
    public void setUseEclipseLinkProfiling();
156
157
    /**
158
    *        This method answers true if EclipseLink Performance Profiling is on.
159
    */
160
    public Boolean getUsesEclipseLinkProfiling();
161
162
    /**
163
    *        This method is used to turn off all Performance Profiling, DMS or EclipseLink.
164
    */
165
    public void setUseNoProfiling();
166
167
    /**
168
      *     Return the size of strings after which will be bound into the statement
169
      *     If we are not using a DatabaseLogin, or we're not using string binding,
170
      *     answer 0 (zero).
171
      */
172
    public Integer getStringBindingSize();
173
174
    /**
175
      *        This method will return a long indicating the exact time in Milliseconds that the
176
      *   session connected to the database.
177
      */
178
    public Long getTimeConnectionEstablished();
179
180
    /**
181
      *        This method will return if batchWriting is in use or not.
182
      */
183
    public Boolean getUsesJDBCBatchWriting();
184
185
    /**
186
      *     Shows if Byte Array Binding is turned on or not
187
      */
188
    public Boolean getUsesByteArrayBinding();
189
190
    /**
191
      *     Shows if native SQL is being used
192
      */
193
    public Boolean getUsesNativeSQL();
194
195
    /**
196
      *     This method indicates if streams are being used for binding
197
      */
198
    public Boolean getUsesStreamsForBinding();
199
200
    /**
201
      *     This method indicates if Strings are being bound
202
      */
203
    public Boolean getUsesStringBinding();
204
205
    /**
206
    *     Used to clear the statement cache. Only valid if statements are being cached
207
    */
208
    public  void clearStatementCache();
209
210
    /**
211
    *     This method will print the available Connection pools to the SessionLog.
212
    * @return void
213
    */
214
    public void printAvailableConnectionPools();
215
216
    /**
217
    *     This method will retrieve the max size of a particular connection pool
218
    * @param poolName the name of the pool to get the max size for
219
    * @return Integer for the max size of the pool. Return -1 if pool doesn't exist.
220
    */
221
    public Integer getMaxSizeForPool(String poolName);
222
223
    /**
224
    *     This method will retrieve the min size of a particular connection pool
225
    * @param poolName the name of the pool to get the min size for
226
    * @return Integer for the min size of the pool. Return -1 if pool doesn't exist.
227
    */
228
    public Integer getMinSizeForPool(String poolName);
229
230
    /**
231
    *        This method is used to output those Class Names that have identity Maps in the Session.
232
    * Please note that SubClasses and aggregates will be missing form this list as they do not have
233
    * separate identity maps.
234
    * @return void
235
    */
236
    public void printClassesInSession();
237
238
    /**
239
    *        This method will log the objects in the Identity Map.
240
    * There is no particular order to these objects.
241
    * @param className the fully qualified classname identifying the identity map
242
    * @exception  thrown then the IdentityMap for that class name could not be found
243
    */
244
    public void printObjectsInIdentityMap(String className) throws ClassNotFoundException;
245
246
    /**
247
    *        This method will log the types of Identity Maps in the session.
248
    */
249
    public void printAllIdentityMapTypes();
250
251
    /**
252
    *        This method will log all objects in all Identity Maps in the session.
253
    */
254
    public void printObjectsInIdentityMaps();
255
256
    /**
257
    *        This method will SUM and return the number of objects in all Identity Maps in the session.
258
    */
259
    public Integer getNumberOfObjectsInAllIdentityMaps();
260
261
    /**
262
    *        This method will answer the number of persistent classes contained in the session.
263
    *   This does not include aggregates.
264
    */
265
    public Integer getNumberOfPersistentClasses();
266
267
    /**
268
    *        This method will log the instance level locks in all Identity Maps in the session.
269
    */
270
    public void printIdentityMapLocks();
271
272
    /**
273
    *        This method will log the instance level locks in the Identity Map for the given class in the session.
274
    */
275
    public void printIdentityMapLocks(String registeredClassName);
276
277
    /**
278
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
279
    *        This will log at the INFO level a summary of all elements in the profile.
280
    */
281
    public void printProfileSummary();
282
283
    /**
284
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
285
    *        This will log at the INFO level a summary of all elements in the profile, categorized
286
    *        by Class.
287
    */
288
    public void printProfileSummaryByClass();
289
290
    /**
291
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
292
    *        This will log at the INFO level a summary of all elements in the profile, categorized
293
    *        by Query.
294
    */
295
    public void printProfileSummaryByQuery();
296
297
    /**
298
    * Return the log type, either "EclipseLink",  "Java" or the simple name of the logging class used.  
299
    * @return the log type
300
    */
301
    public String getLogType();
302
303
    /**
304
    * Return the database platform used by the DatabaseSession.
305
    * @return String databasePlatform
306
    */
307
    public String getDatabasePlatform();
308
309
    /**
310
    * Return JDBCConnection detail information. This includes URL and datasource information.
311
    */
312
    public  String getJdbcConnectionDetails();
313
314
    /**
315
    * Return connection pool type. Values include: "Internal", "External" and "N/A".
316
    */
317
    public  String getConnectionPoolType();
318
319
    /**
320
    * Return db driver class name. This only applies to DefaultConnector. Return "N/A" otherwise.
321
    */
322
    public  String getDriver();
323
324
    /**
325
    * Return the log filename. This returns the fully qualified path of the log file when
326
    * EclipseLink logging is enabled. Null is returned otherwise.
327
    *
328
    * @return String logFilename
329
    */
330
    public String getLogFilename();
331
332
    /**
333
    *    This method is used to initialize the identity maps in the session.
334
    */
335
    public void initializeAllIdentityMaps();
336
337
    /**
338
    *    This method is used to initialize the identity maps specified by the Vector of classNames.
339
    *
340
    * @param classNames String[] of fully qualified classnames identifying the identity maps to initialize
341
    */
342
    public void initializeIdentityMaps(String[] classNames) throws ClassNotFoundException;
343
344
    /**
345
    *    This method is used to initialize the identity maps specified by className.
346
    * @param className the fully qualified classnames identifying the identity map to initialize
347
    */
348
    public void initializeIdentityMap(String className) throws ClassNotFoundException;
349
350
    /**
351
    *    This method is used to invalidate the identity maps in the session.
352
    */
353
    public void invalidateAllIdentityMaps();
354
355
    /**
356
    *    This method is used to invalidate the identity maps specified by the String[] of classNames.
357
    * @param classNames String[] of fully qualified classnames identifying the identity maps to invalidate
358
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
359
    */
360
    public void invalidateIdentityMaps(String[] classNamesParam, Boolean recurse) throws ClassNotFoundException;
361
362
    /**
363
    *    This method is used to invalidate the identity maps specified by className. This does not
364
    * invalidate the children identity maps
365
    * @param className the fully qualified classname identifying the identity map to invalidate
366
    */
367
    public void invalidateIdentityMap(String className) throws ClassNotFoundException;
368
369
    /**
370
    *    This method is used to invalidate the identity maps specified by className.
371
    * @param className the fully qualified classname identifying the identity map to invalidate
372
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
373
    */
374
    public void invalidateIdentityMap(String className, Boolean recurse) throws ClassNotFoundException;
375
376
    /**
377
     * Return whether this session is an EclipseLink JPA session.
378
     * The absence of this function or a value of false will signify that the session
379
     * belongs to a provider other than EclipseLink.  
380
     * @return
381
     */
382
    public boolean isJPASession();
383
    
384
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/RuntimeServices.java (+176 lines)
Lines 27-32 Link Here
27
import org.eclipse.persistence.internal.identitymaps.HardCacheWeakIdentityMap;
27
import org.eclipse.persistence.internal.identitymaps.HardCacheWeakIdentityMap;
28
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
28
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
29
import org.eclipse.persistence.internal.sessions.AbstractSession;
29
import org.eclipse.persistence.internal.sessions.AbstractSession;
30
import org.eclipse.persistence.logging.AbstractSessionLog;
31
import org.eclipse.persistence.logging.SessionLog;
30
import org.eclipse.persistence.sessions.DatabaseLogin;
32
import org.eclipse.persistence.sessions.DatabaseLogin;
31
import org.eclipse.persistence.sessions.Session;
33
import org.eclipse.persistence.sessions.Session;
32
import org.eclipse.persistence.sessions.server.ConnectionPool;
34
import org.eclipse.persistence.sessions.server.ConnectionPool;
Lines 48-53 Link Here
48
    /** stores access to the session object that we are controlling */
50
    /** stores access to the session object that we are controlling */
49
    protected Session session;
51
    protected Session session;
50
52
53
    /** This is the profile weight at server startup time. This is read-only */
54
    private int deployedSessionProfileWeight;
55
56
    /** This contains the session log from server startup time. This is read-only. */
57
    private SessionLog deployedSessionLog;
58
59
    public String objectName;
60
    
61
    protected static final String EclipseLink_Product_Name = "EclipseLink";
62
        
51
    /**
63
    /**
52
     *  Default Constructor
64
     *  Default Constructor
53
     */
65
     */
Lines 406-409 Link Here
406
            getSession().getProfiler().setProfileWeight(weight);
418
            getSession().getProfiler().setProfileWeight(weight);
407
        }
419
        }
408
    }
420
    }
421
    
422
    /**
423
     *    This method is used to initialize the identity maps specified by className.
424
     * @param className the fully qualified classnames identifying the identity map to initialize
425
     */
426
     public synchronized void initializeIdentityMap(String className) throws ClassNotFoundException {
427
         Class registeredClass;
428
429
         //get identity map, and initialize
430
         registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
431
             .convertObject(className, ClassConstants.CLASS);
432
         getSession().getIdentityMapAccessor().initializeIdentityMap(registeredClass);
433
         ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_initialized", className);
434
     }
435
436
     /**
437
      *        This method will log the instance level locks in all Identity Maps in the session.
438
      */
439
      public void printIdentityMapLocks() {
440
          getSession().getIdentityMapAccessorInstance().getIdentityMapManager().printLocks();
441
      }
442
443
      /**
444
      *        This method will log the instance level locks in the Identity Map for the given class in the session.
445
      */
446
      public void printIdentityMapLocks(String registeredClassName) {
447
          Class registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
448
              .convertObject(registeredClassName, ClassConstants.CLASS);
449
          getSession().getIdentityMapAccessorInstance().getIdentityMapManager().printLocks(registeredClass);
450
      }
451
452
      /**
453
       *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
454
       *        This will log at the INFO level a summary of all elements in the profile.
455
       */
456
       public void printProfileSummary() {
457
           if (!this.getUsesEclipseLinkProfiling().booleanValue()) {
458
               return;
459
           }
460
           PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
461
           getSession().getSessionLog().info(performanceProfiler.buildProfileSummary().toString());
462
       }
463
464
       /**
465
        * INTERNAL:
466
        * utility method to get rid of leading and trailing {}'s
467
        */
468
       private String trimProfileString(String originalProfileString) {
469
           String trimmedString;
470
471
           if (originalProfileString.length() > 1) {
472
               trimmedString = originalProfileString.substring(0, originalProfileString.length());
473
               if ((trimmedString.charAt(0) == '{') && (trimmedString.charAt(trimmedString.length() - 1) == '}')) {
474
                   trimmedString = trimmedString.substring(1, trimmedString.length() - 1);
475
               }
476
               return trimmedString;
477
           } else {
478
               return originalProfileString;
479
           }
480
       }
481
482
       /**
483
       *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
484
       *        This will log at the INFO level a summary of all elements in the profile, categorized
485
       *        by Class.
486
       */
487
       public void printProfileSummaryByClass() {
488
           if (!this.getUsesEclipseLinkProfiling().booleanValue()) {
489
               return;
490
           }
491
           PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
492
           //trim the { and } from the beginning at end, because they cause problems for the logger
493
           getSession().getSessionLog().info(trimProfileString(performanceProfiler.buildProfileSummaryByClass().toString()));
494
       }
495
496
       /**
497
       *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
498
       *        This will log at the INFO level a summary of all elements in the profile, categorized
499
       *        by Query.
500
       */
501
       public void printProfileSummaryByQuery() {
502
           if (!this.getUsesEclipseLinkProfiling().booleanValue()) {
503
               return;
504
           }
505
           PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
506
           getSession().getSessionLog().info(trimProfileString(performanceProfiler.buildProfileSummaryByQuery().toString()));
507
       }
508
509
       /**
510
        *        This method is used to get the type of profiling.
511
        *   Possible values are: "EclipseLink" or "None".
512
        */
513
        public synchronized String getProfilingType() {
514
            if (getUsesEclipseLinkProfiling().booleanValue()) {
515
                return EclipseLink_Product_Name;
516
            } else {
517
                return "None";
518
            }
519
        }
520
521
        /**
522
        *        This method is used to select the type of profiling.
523
        *   Valid values are: "EclipseLink" or "None". These values are not case sensitive.
524
        *   null is considered  to be "None".
525
        */
526
        public synchronized void setProfilingType(String profileType) {
527
            if ((profileType == null) || (profileType.compareToIgnoreCase("None") == 0)) {
528
                this.setUseNoProfiling();
529
            } else if (profileType.compareToIgnoreCase(EclipseLink_Product_Name) == 0) {
530
                this.setUseEclipseLinkProfiling();
531
            }
532
        }
533
534
        /**
535
        *        This method is used to turn on EclipseLink Performance Profiling
536
        */
537
        public void setUseEclipseLinkProfiling() {
538
            if (getUsesEclipseLinkProfiling().booleanValue()) {
539
                return;
540
            }
541
            getSession().setProfiler(new PerformanceProfiler());
542
        }
543
544
545
        /**
546
        *        This method is used to turn off all Performance Profiling, DMS or EclipseLink.
547
        */
548
        public void setUseNoProfiling() {
549
            getSession().setProfiler(null);
550
        }
551
       
552
       /**
553
        *        This method answers true if EclipseLink Performance Profiling is on.
554
        */
555
        public Boolean getUsesEclipseLinkProfiling() {
556
            return Boolean.valueOf(getSession().getProfiler() instanceof PerformanceProfiler);
557
        }
558
       
559
     /**
560
      *  INTERNAL:
561
      *  Define the deployment time data associated with logging and profiling
562
      *
563
      */
564
     protected void updateDeploymentTimeData() {
565
         this.deployedSessionLog = (SessionLog)((AbstractSessionLog)session.getSessionLog()).clone();
566
         if (session.getProfiler() == null) {
567
             this.deployedSessionProfileWeight = -1;//there is no profiler
568
         } else {
569
             this.deployedSessionProfileWeight = session.getProfiler().getProfileWeight();
570
         }
571
     }
572
     
573
     public int getDeployedSessionProfileWeight() {
574
         return deployedSessionProfileWeight;
575
     }
576
577
     public SessionLog getDeployedSessionLog() {
578
         return deployedSessionLog;
579
     }
580
581
     public String getObjectName() {
582
         return objectName;
583
     }
584
     
409
}
585
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/weblogic/ClassSummaryDetail.java (-146 / +7 lines)
Lines 17-179 Link Here
17
 ******************************************************************************/  
17
 ******************************************************************************/  
18
package org.eclipse.persistence.services.weblogic;
18
package org.eclipse.persistence.services.weblogic;
19
19
20
import org.eclipse.persistence.services.ClassSummaryDetailBase;
20
21
21
import javax.management.openmbean.CompositeType;
22
import javax.management.openmbean.SimpleType;
23
import javax.management.openmbean.OpenType;
24
import javax.management.openmbean.CompositeData;
25
import javax.management.openmbean.CompositeDataSupport;
26
import javax.management.openmbean.OpenDataException;
27
28
/**
22
/**
29
 * The class is used internally by the Portable JMX Framework to convert 
23
 * The class is used internally by the Portable JMX Framework to convert 
30
 * model specific classes into Open Types so that the attributes of model class can
24
 * model specific classes into Open Types so that the attributes of model class can
31
 * be exposed by MBeans.
25
 * be exposed by MBeans.
32
 */
26
 */
33
public class ClassSummaryDetail {
27
public class ClassSummaryDetail extends ClassSummaryDetailBase {
28
29
    public static final String COMPOSITE_TYPE_TYPENAME = "org.eclipse.persistence.services.weblogic";
30
    public static final String COMPOSITE_TYPE_DESCRIPTION = "org.eclipse.persistence.services.weblogic.ClassSummaryDetail";
31
    
34
    /**
32
    /**
35
     * Construct a ClassSummaryDetail instance. The PropertyNames annotation is used 
33
     * Construct a ClassSummaryDetail instance. The PropertyNames annotation is used 
36
     * to be able to construct a ClassSummaryDetail instance out of a CompositeData
34
     * to be able to construct a ClassSummaryDetail instance out of a CompositeData
37
     * instance. See MXBeans documentation for more details.
35
     * instance. See MXBeans documentation for more details.
38
     */
36
     */
39
    public ClassSummaryDetail(String className, String cacheType, String configuredSize,String currentSize , String parentClassName) {
37
    public ClassSummaryDetail(String className, String cacheType, String configuredSize,String currentSize , String parentClassName) {
40
        this.className = className;
38
        super(className, cacheType, configuredSize, currentSize , parentClassName);
41
        this.cacheType = cacheType;
42
        this.configuredSize = configuredSize;
43
        this.currentSize = currentSize;
44
        this.parentClassName = parentClassName;
45
    }
39
    }
46
    
47
    private String className;
48
    private String cacheType;
49
    private String configuredSize;
50
    private String currentSize;
51
    private String parentClassName;
52
    
53
    // The corresponding CompositeType for this class
54
    private static CompositeType cType_= null;
55
56
    private static final String[] itemNames_= 
57
        {"Class Name", "Cache Type", "Configured Size",
58
         "Current Size","Parent Class Name"}; 
59
60
    static {
61
        try {
62
            OpenType[] itemTypes = {
63
                    SimpleType.STRING,
64
                    SimpleType.STRING,
65
                    SimpleType.STRING,
66
                    SimpleType.STRING,
67
                    SimpleType.STRING};
68
            cType_ = new CompositeType("org.eclipse.persistence.services.weblogic",
69
                                       // this should be a localized description
70
                                       // but isn't really required since the attribute
71
                                       // or parameter description should suffice
72
                                       // however this value cannot be null or empty
73
                                       "org.eclipse.persistence.services.weblogic.ClassSummaryDetail",
74
                                       itemNames_,
75
                                       // this should be a localized description
76
                                       // but isn't really required since the attribute
77
                                       // or parameter description should suffice
78
                                       // however this value cannot be null or empty
79
                                       itemNames_,
80
                                       itemTypes);
81
        }  catch(OpenDataException ode) {
82
            // this won't happen, but in case it does we should log
83
            throw new RuntimeException(ode);
84
        }
85
    }
86
87
    /**
88
     * Returns the CompositeType that describes this model
89
     * specific class
90
     */
91
    public static CompositeType toCompositeType() {
92
        return cType_;
93
    } 
94
    
95
    /**
96
     * Convert an instance of this model specific type to 
97
     * a CompositeData. This ensure that clients that do not
98
     * have access to the model specific class can still
99
     * use the MBean. The MXBean framework can perform this
100
     * conversion automatically.  
101
     * 
102
     * @param ct - This parameter is for JDK 1.6 compatibility reasons
103
     */
104
    public CompositeData toCompositeData(CompositeType ct) {
105
        Object[] itemValues = {
106
                this.className,
107
                this.cacheType,
108
                this.configuredSize,
109
                this.currentSize,
110
                this.parentClassName};
111
112
        CompositeData cData= null;
113
        try {
114
            cData= new CompositeDataSupport(cType_, itemNames_, itemValues);
115
        } catch( OpenDataException ode) {
116
            // this won't happen, but in case it does we should log
117
            throw new RuntimeException(ode);
118
        }
119
        return cData;
120
    }
121
    
122
    /**
123
     * Create an instance of the model specific class out of
124
     * an associated CompositeData instance
125
     */
126
    public static ClassSummaryDetail from(CompositeData cd) {   
127
        if (cd==null) { 
128
            return null;
129
        }
130
131
        return new ClassSummaryDetail( 
132
                (String)cd.get("Class Name"),
133
                (String)cd.get("Cache Type"),
134
                (String)cd.get("Current Size"),
135
                (String)cd.get("Parent Class Name"),
136
                (String)cd.get("Configured Size")
137
                );
138
    }
139
140
    public String getClassName() {
141
        return className;
142
    }
143
144
    public String getCacheType() {
145
        return cacheType;
146
    }
147
148
    public String getConfiguredSize() {
149
        return configuredSize;
150
    }
151
152
    public String getCurrentSize() {
153
        return currentSize;
154
    }
155
156
    public String getParentClassName() {
157
        return parentClassName;
158
    }
159
    
160
    public void setClassName(String className) {
161
        this.className = className;
162
    }
163
    
164
    public void setCacheType(String cacheType) {
165
        this.cacheType = cacheType;
166
    }
167
168
    public void setConfiguredSize(String configuredSize) {
169
        this.configuredSize = configuredSize;
170
    }
171
172
    public void setCurrentSize(String currentSize) {
173
        this.currentSize = currentSize;
174
    }
175
176
    public void setParentClassName(String parentClassName) {
177
        this.parentClassName = parentClassName;
178
    }
179
}
40
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/weblogic/WebLogicRuntimeServices.java (-161 / +1 lines)
Lines 83-98 Link Here
83
 */
83
 */
84
public class WebLogicRuntimeServices extends RuntimeServices {
84
public class WebLogicRuntimeServices extends RuntimeServices {
85
85
86
    /** This is the profile weight at server startup time. This is read-only */
87
    private int deployedSessionProfileWeight;
88
89
    /** This contains the session log from server startup time. This is read-only. */
90
    private SessionLog deployedSessionLog;
91
92
    public String objectName;
93
94
    private static final String EclipseLink_Product_Name = "EclipseLink";
95
    
96
    /**
86
    /**
97
     * PUBLIC:
87
     * PUBLIC:
98
     *  Default Constructor
88
     *  Default Constructor
Lines 106-112 Link Here
106
     *  Create an instance of WebLogicRuntimeServices to be associated with the provided session
96
     *  Create an instance of WebLogicRuntimeServices to be associated with the provided session
107
     *
97
     *
108
     *  @param session The session to be used with these RuntimeServices
98
     *  @param session The session to be used with these RuntimeServices
109
     *  @param String myBaseObjectName: "weblogic:....." (The JMX object name before it's wrapped in a ObjectName)
110
     */
99
     */
111
    public WebLogicRuntimeServices(AbstractSession session) {
100
    public WebLogicRuntimeServices(AbstractSession session) {
112
        super();
101
        super();
Lines 133-151 Link Here
133
        this.updateDeploymentTimeData();
122
        this.updateDeploymentTimeData();
134
    }
123
    }
135
124
136
    /**
137
     *  INTERNAL:
138
     *  Define the deployment time data associated with logging and profiling
139
     *
140
     */
141
    protected void updateDeploymentTimeData() {
142
        this.deployedSessionLog = (SessionLog)((AbstractSessionLog)session.getSessionLog()).clone();
143
        if (session.getProfiler() == null) {
144
            this.deployedSessionProfileWeight = -1;//there is no profiler
145
        } else {
146
            this.deployedSessionProfileWeight = session.getProfiler().getProfileWeight();
147
        }
148
    }
149
125
150
    /**
126
    /**
151
     * Answer the name of the EclipseLink session this MBean represents.
127
     * Answer the name of the EclipseLink session this MBean represents.
Lines 613-619 Link Here
613
     * PUBLIC: Answer the EclipseLink log level at deployment time. This is read-only.
589
     * PUBLIC: Answer the EclipseLink log level at deployment time. This is read-only.
614
     */
590
     */
615
    public String getDeployedEclipseLinkLogLevel() {
591
    public String getDeployedEclipseLinkLogLevel() {
616
        return getNameForLogLevel(this.deployedSessionLog.getLevel());
592
        return getNameForLogLevel(getDeployedSessionLog().getLevel());
617
    }
593
    }
618
594
619
    /**
595
    /**
Lines 700-754 Link Here
700
    }
676
    }
701
677
702
    /**
678
    /**
703
    *        This method is used to get the type of profiling.
704
    *   Possible values are: "EclipseLink" or "None".
705
    */
706
    public synchronized String getProfilingType() {
707
        if (getUsesEclipseLinkProfiling().booleanValue()) {
708
            return EclipseLink_Product_Name;
709
        } else {
710
            return "None";
711
        }
712
    }
713
714
    /**
715
    *        This method is used to select the type of profiling.
716
    *   Valid values are: "EclipseLink" or "None". These values are not case sensitive.
717
    *   null is considered  to be "None".
718
    */
719
    public synchronized void setProfilingType(String profileType) {
720
        if ((profileType == null) || (profileType.compareToIgnoreCase("None") == 0)) {
721
            this.setUseNoProfiling();
722
        } else if (profileType.compareToIgnoreCase(EclipseLink_Product_Name) == 0) {
723
            this.setUseEclipseLinkProfiling();
724
        }
725
    }
726
727
    /**
728
    *        This method is used to turn on EclipseLink Performance Profiling
729
    */
730
    public void setUseEclipseLinkProfiling() {
731
        if (getUsesEclipseLinkProfiling().booleanValue()) {
732
            return;
733
        }
734
        getSession().setProfiler(new PerformanceProfiler());
735
    }
736
737
    /**
738
    *        This method answers true if EclipseLink Performance Profiling is on.
739
    */
740
    public Boolean getUsesEclipseLinkProfiling() {
741
        return Boolean.valueOf(getSession().getProfiler() instanceof PerformanceProfiler);
742
    }
743
744
    /**
745
    *        This method is used to turn off all Performance Profiling, DMS or EclipseLink.
746
    */
747
    public void setUseNoProfiling() {
748
        getSession().setProfiler(null);
749
    }
750
751
    /**
752
     *     Method returns if all Parameters should be bound or not
679
     *     Method returns if all Parameters should be bound or not
753
     */
680
     */
754
    public Boolean getShouldBindAllParameters() {
681
    public Boolean getShouldBindAllParameters() {
Lines 1113-1191 Link Here
1113
    }
1040
    }
1114
1041
1115
    /**
1042
    /**
1116
    *        This method will log the instance level locks in all Identity Maps in the session.
1117
    */
1118
    public void printIdentityMapLocks() {
1119
        getSession().getIdentityMapAccessorInstance().getIdentityMapManager().printLocks();
1120
    }
1121
1122
    /**
1123
    *        This method will log the instance level locks in the Identity Map for the given class in the session.
1124
    */
1125
    public void printIdentityMapLocks(String registeredClassName) {
1126
        Class registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
1127
            .convertObject(registeredClassName, ClassConstants.CLASS);
1128
        getSession().getIdentityMapAccessorInstance().getIdentityMapManager().printLocks(registeredClass);
1129
    }
1130
1131
    /**
1132
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
1133
    *        This will log at the INFO level a summary of all elements in the profile.
1134
    */
1135
    public void printProfileSummary() {
1136
        if (!this.getUsesEclipseLinkProfiling().booleanValue()) {
1137
            return;
1138
        }
1139
        PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
1140
        getSession().getSessionLog().info(performanceProfiler.buildProfileSummary().toString());
1141
    }
1142
1143
    /**
1144
     * INTERNAL:
1145
     * utility method to get rid of leading and trailing {}'s
1146
     */
1147
    private String trimProfileString(String originalProfileString) {
1148
        String trimmedString;
1149
1150
        if (originalProfileString.length() > 1) {
1151
            trimmedString = originalProfileString.substring(0, originalProfileString.length());
1152
            if ((trimmedString.charAt(0) == '{') && (trimmedString.charAt(trimmedString.length() - 1) == '}')) {
1153
                trimmedString = trimmedString.substring(1, trimmedString.length() - 1);
1154
            }
1155
            return trimmedString;
1156
        } else {
1157
            return originalProfileString;
1158
        }
1159
    }
1160
1161
    /**
1162
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
1163
    *        This will log at the INFO level a summary of all elements in the profile, categorized
1164
    *        by Class.
1165
    */
1166
    public void printProfileSummaryByClass() {
1167
        if (!this.getUsesEclipseLinkProfiling().booleanValue()) {
1168
            return;
1169
        }
1170
        PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
1171
        //trim the { and } from the beginning at end, because they cause problems for the logger
1172
        getSession().getSessionLog().info(trimProfileString(performanceProfiler.buildProfileSummaryByClass().toString()));
1173
    }
1174
1175
    /**
1176
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
1177
    *        This will log at the INFO level a summary of all elements in the profile, categorized
1178
    *        by Query.
1179
    */
1180
    public void printProfileSummaryByQuery() {
1181
        if (!this.getUsesEclipseLinkProfiling().booleanValue()) {
1182
            return;
1183
        }
1184
        PerformanceProfiler performanceProfiler = (PerformanceProfiler)getSession().getProfiler();
1185
        getSession().getSessionLog().info(trimProfileString(performanceProfiler.buildProfileSummaryByQuery().toString()));
1186
    }
1187
1188
    /**
1189
    * Return the log type, either "EclipseLink",  "Java" or the simple name of the logging class used.  
1043
    * Return the log type, either "EclipseLink",  "Java" or the simple name of the logging class used.  
1190
    *
1044
    *
1191
    * @return the log type
1045
    * @return the log type
Lines 1271-1290 Link Here
1271
    }
1125
    }
1272
1126
1273
    /**
1127
    /**
1274
    *    This method is used to initialize the identity maps specified by className.
1275
    * @param className the fully qualified classnames identifying the identity map to initialize
1276
    */
1277
    public synchronized void initializeIdentityMap(String className) throws ClassNotFoundException {
1278
        Class registeredClass;
1279
1280
        //get identity map, and initialize
1281
        registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
1282
            .convertObject(className, ClassConstants.CLASS);
1283
        getSession().getIdentityMapAccessor().initializeIdentityMap(registeredClass);
1284
        ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_initialized", className);
1285
    }
1286
1287
    /**
1288
    *    This method is used to invalidate the identity maps in the session.
1128
    *    This method is used to invalidate the identity maps in the session.
1289
    */
1129
    */
1290
    public synchronized void invalidateAllIdentityMaps() {
1130
    public synchronized void invalidateAllIdentityMaps() {
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/websphere/ClassSummaryDetail.java (+39 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.websphere;
18
19
import org.eclipse.persistence.services.ClassSummaryDetailBase;
20
21
/**
22
 * The class is used internally by the Portable JMX Framework to convert 
23
 * model specific classes into Open Types so that the attributes of model class can
24
 * be exposed by MBeans.
25
 */
26
public class ClassSummaryDetail extends ClassSummaryDetailBase {
27
28
    public static final String COMPOSITE_TYPE_TYPENAME = "org.eclipse.persistence.services.websphere";
29
    public static final String COMPOSITE_TYPE_DESCRIPTION = "org.eclipse.persistence.services.websphere.ClassSummaryDetail";
30
31
    /**
32
     * Construct a ClassSummaryDetail instance. The PropertyNames annotation is used 
33
     * to be able to construct a ClassSummaryDetail instance out of a CompositeData
34
     * instance. See MXBeans documentation for more details.
35
     */
36
    public ClassSummaryDetail(String className, String cacheType, String configuredSize,String currentSize , String parentClassName) {
37
        super(className, cacheType, configuredSize, currentSize , parentClassName);
38
    }
39
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/websphere/MBeanWebSphereRuntimeServices.java (+34 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.websphere;
18
19
import org.eclipse.persistence.internal.sessions.AbstractSession;
20
import org.eclipse.persistence.sessions.Session;
21
22
/**
23
 * <p>
24
 * <b>Purpose</b>: Provide a dynamic interface into the EclipseLink Session.
25
 * <p>
26
 * <b>Description</b>: This class is meant to provide a framework for gaining access to configuration
27
 * of the EclipseLink Session during runtime.  It will provide the basis for development
28
 * of a JMX service and possibly other frameworks.
29
 */
30
public class MBeanWebSphereRuntimeServices extends WebSphereRuntimeServices implements MBeanWebSphereRuntimeServicesMBean {
31
    public MBeanWebSphereRuntimeServices(Session session) {
32
        super((AbstractSession)session);
33
    }
34
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/websphere/MBeanWebSphereRuntimeServicesMBean.java (+384 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.websphere;
18
19
import java.util.ArrayList;
20
import java.util.Vector;
21
22
import org.eclipse.persistence.services.mbean.MBeanRuntimeServicesMBean;
23
24
/**
25
 * <p>
26
 * <b>Purpose</b>: Provide a dynamic interface into the EclipseLink Session.
27
 * <p>
28
 * <b>Description</b>: This class is meant to provide facilities for managing an EclipseLink session external
29
 * to EclipseLink over JMX.
30
 */
31
public interface MBeanWebSphereRuntimeServicesMBean extends MBeanRuntimeServicesMBean {
32
    /**
33
     *  Answer the name of the EclipseLink session this MBean represents.
34
     */
35
    public String getSessionName();
36
37
    /**
38
     *  Answer the type of the EclipseLink session this MBean represents.
39
     * Types include: "ServerSession", "DatabaseSession", "SessionBroker"
40
     */
41
    public String getSessionType();
42
43
    /**
44
     *  Provide an instance of 2 Dimensional Array simulating tabular format information about all
45
     * classes in the session whose class names match the provided filter.
46
     *
47
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
48
     * represents EclipseLink class details info with respect to below attributes:  
49
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
50
     *
51
     */
52
    public Object[][] getClassSummaryDetailsUsingFilter(String filter);
53
    
54
    /**
55
     *  Provide an instance of 2 Dimensional Array simulating tabular format information about all
56
     * classes in the session.
57
     *
58
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
59
     * represents EclipseLink class details info with respect to below attributes:  
60
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
61
     *
62
     */
63
    public Object[][] getClassSummaryDetails();
64
    
65
    /**
66
     *  Provide a list of instance of ClassSummaryDetail containing information about the
67
     * classes in the session whose class names match the provided filter.
68
     *
69
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
70
     * convert class attribute to JMX required open type, it has:-
71
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
72
     *    2. convert methods.  
73
     *
74
     * @param filter A comma separated list of strings to match against.
75
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
76
     */
77
    public ArrayList <ClassSummaryDetail>  getClassSummaryDetailsUsingFilterArray(String filter);
78
    
79
    /**
80
     *  Provide a list of instance of ClassSummaryDetail containing information about all
81
     * classes in the session.
82
     *
83
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
84
     * convert class attribute to JMX required open type, it has:-
85
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
86
     *    2. convert methods.  
87
     *
88
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
89
     */
90
    public ArrayList <ClassSummaryDetail>  getClassSummaryDetailsArray();
91
92
    /**
93
    *  INTERNAL:
94
    *  This method traverses the EclipseLink descriptors and returns a Vector of the descriptor's
95
    *   reference class names that match the provided filter. The filter is a comma separated
96
    *   list of strings to match against.
97
    *
98
    *   @param filter A comma separated list of strings to match against.
99
    *   @return A Vector of class names that match the filter.
100
    */
101
    public Vector getMappedClassNamesUsingFilter(String filter);
102
103
    /**
104
     * getModuleName(): Answer the name of the context-root of the application that this session is associated with.
105
     * Answer "unknown" if there is no module name available.
106
     * Default behavior is to return "unknown"
107
     */
108
    public String getModuleName();
109
    
110
    /**
111
     * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
112
     * Answer "unknown" if there is no application name available.
113
     * Default behavior is to return "unknown"
114
     */
115
    public String getApplicationName();
116
117
    /**
118
     *  Answer the EclipseLink log level at deployment time. This is read-only.
119
     */
120
    public String getDeployedEclipseLinkLogLevel();
121
122
    /**
123
     *  Answer the EclipseLink log level that is changeable.
124
     * This does not affect the log level in the project (i.e. The next
125
     * time the application is deployed, changes are forgotten)
126
     */
127
    public String getCurrentEclipseLinkLogLevel();
128
129
    /**
130
     *  Set the EclipseLink log level to be used at runtime.
131
     *
132
     * This does not affect the log level in the project (i.e. The next
133
     * time the application is deployed, changes are forgotten)
134
     *
135
     * @param String newLevel: new log level
136
     */
137
    public  void setCurrentEclipseLinkLogLevel(String newLevel);
138
139
    /**
140
    *        This method is used to get the type of profiling.
141
    *   Possible values are: "EclipseLink" or "None".
142
    */
143
    public  String getProfilingType();
144
145
    /**
146
    *        This method is used to select the type of profiling.
147
    *   Valid values are: "EclipseLink" or "None". These values are not case sensitive.
148
    *   null is considered  to be "None".
149
    */
150
    public  void setProfilingType(String profileType);
151
152
    /**
153
    *        This method is used to turn on EclipseLink Performance Profiling
154
    */
155
    public void setUseEclipseLinkProfiling();
156
157
    /**
158
    *        This method answers true if EclipseLink Performance Profiling is on.
159
    */
160
    public Boolean getUsesEclipseLinkProfiling();
161
162
    /**
163
    *        This method is used to turn off all Performance Profiling, DMS or EclipseLink.
164
    */
165
    public void setUseNoProfiling();
166
167
    /**
168
      *     Return the size of strings after which will be bound into the statement
169
      *     If we are not using a DatabaseLogin, or we're not using string binding,
170
      *     answer 0 (zero).
171
      */
172
    public Integer getStringBindingSize();
173
174
    /**
175
      *        This method will return a long indicating the exact time in Milliseconds that the
176
      *   session connected to the database.
177
      */
178
    public Long getTimeConnectionEstablished();
179
180
    /**
181
      *        This method will return if batchWriting is in use or not.
182
      */
183
    public Boolean getUsesJDBCBatchWriting();
184
185
    /**
186
      *     Shows if Byte Array Binding is turned on or not
187
      */
188
    public Boolean getUsesByteArrayBinding();
189
190
    /**
191
      *     Shows if native SQL is being used
192
      */
193
    public Boolean getUsesNativeSQL();
194
195
    /**
196
      *     This method indicates if streams are being used for binding
197
      */
198
    public Boolean getUsesStreamsForBinding();
199
200
    /**
201
      *     This method indicates if Strings are being bound
202
      */
203
    public Boolean getUsesStringBinding();
204
205
    /**
206
    *     Used to clear the statement cache. Only valid if statements are being cached
207
    */
208
    public  void clearStatementCache();
209
210
    /**
211
    *     This method will print the available Connection pools to the SessionLog.
212
    * @return void
213
    */
214
    public void printAvailableConnectionPools();
215
216
    /**
217
    *     This method will retrieve the max size of a particular connection pool
218
    * @param poolName the name of the pool to get the max size for
219
    * @return Integer for the max size of the pool. Return -1 if pool doesn't exist.
220
    */
221
    public Integer getMaxSizeForPool(String poolName);
222
223
    /**
224
    *     This method will retrieve the min size of a particular connection pool
225
    * @param poolName the name of the pool to get the min size for
226
    * @return Integer for the min size of the pool. Return -1 if pool doesn't exist.
227
    */
228
    public Integer getMinSizeForPool(String poolName);
229
230
    /**
231
    *        This method is used to output those Class Names that have identity Maps in the Session.
232
    * Please note that SubClasses and aggregates will be missing form this list as they do not have
233
    * separate identity maps.
234
    * @return void
235
    */
236
    public void printClassesInSession();
237
238
    /**
239
    *        This method will log the objects in the Identity Map.
240
    * There is no particular order to these objects.
241
    * @param className the fully qualified classname identifying the identity map
242
    * @exception  thrown then the IdentityMap for that class name could not be found
243
    */
244
    public void printObjectsInIdentityMap(String className) throws ClassNotFoundException;
245
246
    /**
247
    *        This method will log the types of Identity Maps in the session.
248
    */
249
    public void printAllIdentityMapTypes();
250
251
    /**
252
    *        This method will log all objects in all Identity Maps in the session.
253
    */
254
    public void printObjectsInIdentityMaps();
255
256
    /**
257
    *        This method will SUM and return the number of objects in all Identity Maps in the session.
258
    */
259
    public Integer getNumberOfObjectsInAllIdentityMaps();
260
261
    /**
262
    *        This method will answer the number of persistent classes contained in the session.
263
    *   This does not include aggregates.
264
    */
265
    public Integer getNumberOfPersistentClasses();
266
267
    /**
268
    *        This method will log the instance level locks in all Identity Maps in the session.
269
    */
270
    public void printIdentityMapLocks();
271
272
    /**
273
    *        This method will log the instance level locks in the Identity Map for the given class in the session.
274
    */
275
    public void printIdentityMapLocks(String registeredClassName);
276
277
    /**
278
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
279
    *        This will log at the INFO level a summary of all elements in the profile.
280
    */
281
    public void printProfileSummary();
282
283
    /**
284
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
285
    *        This will log at the INFO level a summary of all elements in the profile, categorized
286
    *        by Class.
287
    */
288
    public void printProfileSummaryByClass();
289
290
    /**
291
    *        This method assumes EclipseLink Profiling (as opposed to Java profiling).
292
    *        This will log at the INFO level a summary of all elements in the profile, categorized
293
    *        by Query.
294
    */
295
    public void printProfileSummaryByQuery();
296
297
    /**
298
    * Return the log type, either "EclipseLink",  "Java" or the simple name of the logging class used.  
299
    * @return the log type
300
    */
301
    public String getLogType();
302
303
    /**
304
    * Return the database platform used by the DatabaseSession.
305
    * @return String databasePlatform
306
    */
307
    public String getDatabasePlatform();
308
309
    /**
310
    * Return JDBCConnection detail information. This includes URL and datasource information.
311
    */
312
    public  String getJdbcConnectionDetails();
313
314
    /**
315
    * Return connection pool type. Values include: "Internal", "External" and "N/A".
316
    */
317
    public  String getConnectionPoolType();
318
319
    /**
320
    * Return db driver class name. This only applies to DefaultConnector. Return "N/A" otherwise.
321
    */
322
    public  String getDriver();
323
324
    /**
325
    * Return the log filename. This returns the fully qualified path of the log file when
326
    * EclipseLink logging is enabled. Null is returned otherwise.
327
    *
328
    * @return String logFilename
329
    */
330
    public String getLogFilename();
331
332
    /**
333
    *    This method is used to initialize the identity maps in the session.
334
    */
335
    public void initializeAllIdentityMaps();
336
337
    /**
338
    *    This method is used to initialize the identity maps specified by the Vector of classNames.
339
    *
340
    * @param classNames String[] of fully qualified classnames identifying the identity maps to initialize
341
    */
342
    public void initializeIdentityMaps(String[] classNames) throws ClassNotFoundException;
343
344
    /**
345
    *    This method is used to initialize the identity maps specified by className.
346
    * @param className the fully qualified classnames identifying the identity map to initialize
347
    */
348
    public void initializeIdentityMap(String className) throws ClassNotFoundException;
349
350
    /**
351
    *    This method is used to invalidate the identity maps in the session.
352
    */
353
    public void invalidateAllIdentityMaps();
354
355
    /**
356
    *    This method is used to invalidate the identity maps specified by the String[] of classNames.
357
    * @param classNames String[] of fully qualified classnames identifying the identity maps to invalidate
358
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
359
    */
360
    public void invalidateIdentityMaps(String[] classNamesParam, Boolean recurse) throws ClassNotFoundException;
361
362
    /**
363
    *    This method is used to invalidate the identity maps specified by className. This does not
364
    * invalidate the children identity maps
365
    * @param className the fully qualified classname identifying the identity map to invalidate
366
    */
367
    public void invalidateIdentityMap(String className) throws ClassNotFoundException;
368
369
    /**
370
    *    This method is used to invalidate the identity maps specified by className.
371
    * @param className the fully qualified classname identifying the identity map to invalidate
372
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
373
    */
374
    public void invalidateIdentityMap(String className, Boolean recurse) throws ClassNotFoundException;
375
376
    /**
377
     * Return whether this session is an EclipseLink JPA session.
378
     * The absence of this function or a value of false will signify that the session
379
     * belongs to a provider other than EclipseLink.  
380
     * @return
381
     */
382
    public boolean isJPASession();
383
    
384
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/services/websphere/WebSphereRuntimeServices.java (+1213 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     @author  mobrien
12
 *     @since   EclipseLink 2.2 enh# 316511
13
 *     06/22/2010-2.2 Michael O'Brien 
14
 *       - 316511: Add JBoss specific JMX MBean attributes and functions
15
 *       see <link>http://wiki.eclipse.org/EclipseLink/DesignDocs/316513</link>
16
 ******************************************************************************/  
17
package org.eclipse.persistence.services.websphere;
18
19
import java.util.ArrayList;
20
import java.util.Collections;
21
import java.util.Enumeration;
22
import java.util.HashMap;
23
import java.util.Hashtable;
24
import java.util.Iterator;
25
import java.util.Locale;
26
import java.util.Map;
27
import java.util.StringTokenizer;
28
import java.util.Vector;
29
import java.util.regex.PatternSyntaxException;
30
31
import javax.management.openmbean.CompositeData;
32
import javax.management.openmbean.CompositeDataSupport;
33
import javax.management.openmbean.CompositeType;
34
import javax.management.openmbean.OpenDataException;
35
import javax.management.openmbean.OpenType;
36
import javax.management.openmbean.SimpleType;
37
import javax.management.openmbean.TabularData;
38
import javax.management.openmbean.TabularDataSupport;
39
import javax.management.openmbean.TabularType;
40
41
42
import org.eclipse.persistence.descriptors.ClassDescriptor;
43
import org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor;
44
import org.eclipse.persistence.internal.databaseaccess.DatasourcePlatform;
45
import org.eclipse.persistence.internal.helper.ClassConstants;
46
import org.eclipse.persistence.internal.helper.Helper;
47
import org.eclipse.persistence.internal.identitymaps.CacheIdentityMap;
48
import org.eclipse.persistence.internal.identitymaps.CacheKey;
49
import org.eclipse.persistence.internal.identitymaps.FullIdentityMap;
50
import org.eclipse.persistence.internal.identitymaps.HardCacheWeakIdentityMap;
51
import org.eclipse.persistence.internal.identitymaps.IdentityMap;
52
import org.eclipse.persistence.internal.identitymaps.NoIdentityMap;
53
import org.eclipse.persistence.internal.identitymaps.SoftCacheWeakIdentityMap;
54
import org.eclipse.persistence.internal.identitymaps.SoftIdentityMap;
55
import org.eclipse.persistence.internal.identitymaps.WeakIdentityMap;
56
import org.eclipse.persistence.internal.sessions.AbstractSession;
57
import org.eclipse.persistence.internal.sessions.DatabaseSessionImpl;
58
import org.eclipse.persistence.logging.AbstractSessionLog;
59
import org.eclipse.persistence.logging.DefaultSessionLog;
60
import org.eclipse.persistence.logging.JavaLog;
61
import org.eclipse.persistence.logging.SessionLog;
62
import org.eclipse.persistence.platform.server.was.WebSphere_7_Platform;
63
import org.eclipse.persistence.services.RuntimeServices;
64
import org.eclipse.persistence.sessions.DatabaseLogin;
65
import org.eclipse.persistence.sessions.DefaultConnector;
66
import org.eclipse.persistence.sessions.server.ConnectionPool;
67
import org.eclipse.persistence.sessions.server.ServerSession;
68
import org.eclipse.persistence.tools.profiler.PerformanceProfiler;
69
70
/**
71
 * <p>
72
 * <b>Purpose</b>: Provide a dynamic interface into the EclipseLink Session.
73
 * <p>
74
 * <b>Description</b>: This class is meant to provide facilities for managing an EclipseLink session external
75
 * to EclipseLink over JMX.
76
 */
77
public class WebSphereRuntimeServices extends RuntimeServices {
78
79
    /**
80
     * PUBLIC:
81
     *  Default Constructor
82
     */
83
    public WebSphereRuntimeServices() {
84
        super();
85
    }
86
87
    /**
88
     *  PUBLIC:
89
     *  Create an instance of WebSphereRuntimeServices to be associated with the provided session
90
     *
91
     *  @param session The session to be used with these RuntimeServices
92
     */
93
    public WebSphereRuntimeServices(AbstractSession session) {
94
        super();
95
        this.session = session;
96
        this.updateDeploymentTimeData();
97
    }
98
99
    /**
100
     *  Create an instance of WebSphereRuntimeServices to be associated with the provided locale
101
     *
102
     *  The user must call setSession(Session) afterwards to define the session.
103
     */
104
    public WebSphereRuntimeServices(Locale locale) {
105
    }
106
107
    /**
108
     *  INTERNAL:
109
     *  Define the session that this instance is providing runtime services for
110
     *
111
     *  @param Session session The session to be used with these RuntimeServices
112
     */
113
    protected void setSession(AbstractSession newSession) {
114
        this.session = newSession;
115
        this.updateDeploymentTimeData();
116
    }
117
118
    /**
119
     * Answer the name of the EclipseLink session this MBean represents.
120
     */
121
    public String getSessionName() {
122
        return getSession().getName();
123
    }
124
125
    /**
126
     * Answer the type of the EclipseLink session this MBean represents.
127
     * Types include: "ServerSession", "DatabaseSession", "SessionBroker"
128
     */
129
    public String getSessionType() {
130
        return Helper.getShortClassName(getSession().getClass());
131
    }
132
133
    /**
134
     * Provide an instance of 2 Dimensional Array simulating tabular format information about all
135
     * classes in the session whose class names match the provided filter.
136
     *
137
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
138
     * represents EclipseLink class details info with respect to below attributes:  
139
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
140
     *
141
     */
142
    public Object[][] getClassSummaryDetailsUsingFilter(String filter){
143
        try{
144
           return  tabularDataTo2DArray(buildClassSummaryDetailsUsingFilter(filter),new String[] {
145
               "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" });
146
        } catch (Exception exception) {
147
           AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception); 
148
        }
149
        return null;
150
    }
151
    
152
    /**
153
     * Provide a list of instance of ClassSummaryDetail containing information about the
154
     * classes in the session whose class names match the provided filter.
155
     *
156
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
157
     * convert class attribute to JMX required open type, it has:-
158
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
159
     *    2. convert methods.  
160
     *
161
     * @param filter A comma separated list of strings to match against.
162
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
163
     */
164
    public ArrayList <ClassSummaryDetail>  getClassSummaryDetailsUsingFilterArray(String filter) {
165
        // if the filter is null, return all the details
166
        if (filter == null) {
167
            return getClassSummaryDetailsArray();
168
        }
169
170
        try {
171
            Vector mappedClassNames = getMappedClassNamesUsingFilter(filter);
172
            String mappedClassName;
173
            ArrayList classSummaryDetails = new ArrayList<ClassSummaryDetail>();
174
            // Check if there aren't any classes mapped
175
            if (mappedClassNames.size() == 0) {
176
                return null;
177
            }
178
179
            // get details for each class, and add the details to the summary
180
            for (int index = 0; index < mappedClassNames.size(); index++) {
181
                mappedClassName = (String)mappedClassNames.elementAt(index);
182
                classSummaryDetails.add(buildLowlevelDetailsFor(mappedClassName));
183
            }
184
            return classSummaryDetails;
185
        } catch (Exception openTypeException) {
186
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", openTypeException);            
187
            openTypeException.printStackTrace();
188
        }
189
190
        // wait to get requirements from EM
191
        return null;
192
    }
193
194
    /**
195
     * Provide a list of instance of ClassSummaryDetail containing information about all
196
     * classes in the session.
197
     *
198
     * ClassSummaryDetail is a model specific class that can be used internally by the Portable JMX Framework to
199
     * convert class attribute to JMX required open type, it has:-
200
     *    1. model specific type that needs to be converted : ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
201
     *    2. convert methods.  
202
     *
203
     * @return A ArrayList of instance of ClassSummaryDetail containing class information for the class names that match the filter.
204
     */
205
    public ArrayList <ClassSummaryDetail> getClassSummaryDetailsArray() {
206
        try {            
207
            Vector mappedClassNames = getMappedClassNames();
208
            ArrayList classSummaryDetails = new ArrayList<ClassSummaryDetail>();            
209
            // Check if there aren't any classes mapped
210
            if (mappedClassNames.size() == 0) {
211
                return null;
212
            }
213
214
            // get details for each class, and add the details to the summary
215
            for (int index = 0; index < mappedClassNames.size(); index++) {
216
                String mappedClassName = (String)mappedClassNames.elementAt(index);
217
                classSummaryDetails.add(buildLowlevelDetailsFor(mappedClassName));
218
            }
219
220
            return classSummaryDetails;
221
        } catch (Exception openTypeException) {
222
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", openTypeException);
223
            openTypeException.printStackTrace();
224
        }
225
226
        // wait to get requirements from EM
227
        return null;
228
    }
229
    
230
    /**
231
     * PUBLIC: Provide an instance of 2 Dimensional Array simulating tabular format information about all
232
     * classes in the session.
233
     *
234
     * The 2 Dimensional array contains each item with values being row object array. Each row object array 
235
     * represents EclipseLink class details info with respect to below attributes:  
236
     * ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
237
     *
238
     */
239
    public Object[][] getClassSummaryDetails() {
240
        try{
241
           return tabularDataTo2DArray(buildClassSummaryDetails(),new String[] {
242
               "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" });
243
        } catch (Exception exception){
244
           AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception);
245
        }
246
        return null;
247
    }
248
    
249
    /**
250
     * INTERNAL:
251
     * Provide an instance of TabularData containing information about the
252
     * classes in the session whose class names match the provided filter.
253
     *
254
     * The TabularData contains rowData with values being CompositeData(s)
255
     *
256
     * CompositeData has:
257
     *    CompositeType: column names are ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
258
     *
259
     *  Each CompositeData can have get(myColumnName) sent to it.
260
     *
261
     *
262
     * @param filter A comma separated list of strings to match against.
263
     * @return A TabularData of information for the class names that match the filter.
264
     */
265
    private TabularData buildClassSummaryDetailsUsingFilter(String filter) {
266
        // if the filter is null, return all the details
267
        if (filter == null) {
268
            return buildClassSummaryDetails();
269
        }
270
271
        try {
272
            Vector mappedClassNames = getMappedClassNamesUsingFilter(filter);
273
            String mappedClassName;
274
            TabularDataSupport rowData = new TabularDataSupport(buildTabularTypeForClassSummaryDetails());
275
            // Check if there aren't any classes mapped
276
            if (mappedClassNames.size() == 0) {
277
                return null;
278
            }
279
280
            // get details for each class, and add the details to the summary
281
            for (int index = 0; index < mappedClassNames.size(); index++) {
282
                mappedClassName = (String)mappedClassNames.elementAt(index);
283
                String[] key = new String[] { mappedClassName };
284
                rowData.put(key, buildDetailsFor(mappedClassName, rowData.getTabularType().getRowType()));
285
            }
286
            return rowData;
287
        } catch (Exception exception) {
288
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception);
289
        }
290
291
        // wait to get requirements from EM
292
        return null;
293
    }
294
295
    /**
296
     * INTERNAL: 
297
     * Provide an instance of TabularData containing information about all
298
     * classes in the session.
299
     *
300
     * The TabularData contains rowData with values being CompositeData(s)
301
     *
302
     * CompositeData has:
303
     *    CompositeType: column names are ["Class Name", "Parent Class Name",  "Cache Type", "Configured Size", "Current Size"]
304
     *
305
     *  Each CompositeData can have get(myColumnName) sent to it.
306
     *
307
     */
308
    private TabularData buildClassSummaryDetails() {
309
        try {
310
            Vector mappedClassNames = getMappedClassNames();
311
            String mappedClassName;
312
            TabularDataSupport rowData = new TabularDataSupport(buildTabularTypeForClassSummaryDetails());
313
            // Check if there aren't any classes mapped
314
            if (mappedClassNames.size() == 0) {
315
                return null;
316
            }
317
318
            // get details for each class, and add the details to the summary
319
            for (int index = 0; index < mappedClassNames.size(); index++) {
320
                mappedClassName = (String)mappedClassNames.elementAt(index);
321
                String[] key = new String[] { mappedClassName };
322
                rowData.put(key, buildDetailsFor(mappedClassName, rowData.getTabularType().getRowType()));
323
            }
324
325
            return rowData;
326
        } catch (Exception exception) {
327
            AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", exception);
328
        }
329
330
        // wait to get requirements from EM
331
        return null;
332
    }
333
334
    /**
335
     * INTERNAL:
336
     * Answer the fully qualified names of the classes mapped in the session.
337
     * This uses the mappedClass from the CMPPolicy.
338
     *
339
     * @return java.util.Vector
340
     */
341
    
342
    private Vector getMappedClassNames() {
343
        Hashtable alreadyAdded = new Hashtable();
344
        Vector mappedClassNames = new Vector();
345
        String mappedClassName = null;
346
347
        Iterator descriptorsIterator = getSession().getProject().getDescriptors()
348
                .values().iterator();
349
        while (descriptorsIterator.hasNext()) {
350
            ClassDescriptor nextDescriptor = (ClassDescriptor) descriptorsIterator.next();
351
352
            // differentiate between a generated class and not, by comparing the descriptor's Java class
353
            if (nextDescriptor.getCMPPolicy() != null) {
354
                if (nextDescriptor.getCMPPolicy().getMappedClass() != null) {
355
                    mappedClassName = nextDescriptor.getCMPPolicy().getMappedClass().getName();
356
                }
357
            }
358
359
            if (mappedClassName == null) {
360
                mappedClassName = nextDescriptor.getJavaClassName();
361
            }
362
            if (alreadyAdded.get(mappedClassName) == null) {
363
                alreadyAdded.put(mappedClassName, Boolean.TRUE);
364
                mappedClassNames.addElement(mappedClassName);
365
            }
366
            mappedClassName = null;
367
        }
368
        return mappedClassNames;
369
    }
370
371
    /**
372
    *  INTERNAL:
373
    *  This method traverses the EclipseLink descriptors and returns a Vector of the descriptor's
374
    *   reference class names that match the provided filter. The filter is a comma separated
375
    *   list of strings to match against.
376
    *
377
    *   @param filter A comma separated list of strings to match against.
378
    *   @return A Vector of class names that match the filter.
379
    */
380
    public Vector getMappedClassNamesUsingFilter(String filter) {
381
        //Output Vector
382
        Vector outputVector = new Vector();
383
384
        //Input mapped class names
385
        Vector mappedClassNames = getMappedClassNames();
386
387
        //Input filter values
388
        ArrayList filters = new ArrayList();
389
        StringTokenizer lineTokens = new StringTokenizer(filter, ",");
390
        while (lineTokens.hasMoreTokens()) {
391
            filters.add(lineTokens.nextToken());
392
        }
393
        for (int i = 0; i < mappedClassNames.size(); i++) {
394
            String className = (String)mappedClassNames.get(i);
395
            String classNameLowerCase = ((String)mappedClassNames.get(i)).toLowerCase();
396
            for (int j = 0; j < filters.size(); j++) {
397
                String filterValue = (Helper.rightTrimString((String)filters.get(j)).trim()).toLowerCase();
398
                if (filterValue.indexOf('*') == 0) {
399
                    filterValue = filterValue.substring(1);
400
                }
401
                try {
402
                    //Note: String.matches(String regex) since jdk1.4
403
                    if (classNameLowerCase.matches(new StringBuffer().append("^.*").append(filterValue).append(".*$").toString())) {
404
                        if (!outputVector.contains(className)) {
405
                            outputVector.add(className);
406
                        }
407
                    }
408
                } catch (PatternSyntaxException exception) {
409
                    //regular expression syntax error
410
                    AbstractSessionLog.getLog().log(SessionLog.FINEST, "pattern_syntax_error", exception);
411
                }
412
            }
413
        }
414
        Collections.sort(outputVector);
415
        return outputVector;
416
    }
417
418
    /**
419
     * INTERNAL:
420
     * Answer the TabularType describing the TabularData that we return from
421
     * getCacheSummaryDetails() and getCacheSummaryDetails(String filter)
422
     *
423
     * This is mostly for the client side to see what kind of information is returned.
424
     *
425
     * @return javax.management.openmbean.TabularType
426
     */
427
    private TabularType buildTabularTypeForClassSummaryDetails() throws OpenDataException {
428
        return new TabularType(getSessionName(), "Session description", buildCompositeTypeForClassSummaryDetails(),
429
                new String[] { "Class Name" });
430
    }
431
432
    /**
433
     * INTERNAL:
434
     * Answer the CompositeType describing the CompositeData that we return for
435
     * each IdentityMap (or subclass).
436
     *
437
     * This is mostly for the client side to see what kind of information is returned.
438
     * @return javax.management.openmbean.CompositeType
439
     */
440
    private CompositeType buildCompositeTypeForClassSummaryDetails() throws OpenDataException {
441
        return new CompositeType("Class Details", "Details of class for Class Summary", new String[] { 
442
                "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" }, new String[] { 
443
                "Class Name", "Parent Class Name", "Cache Type", "Configured Size", "Current Size" }, new OpenType[] { 
444
                SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING, SimpleType.STRING });
445
    }
446
447
    /**
448
     * INTERNAL:
449
     * Answer the CompositeData containing the cache details for the given mappedClassName
450
     * This uses a CompositeDataSupport, which implements CompositeData
451
     *
452
     * @param String mappedClassName: fullyQualified class name of the class
453
     * @param CompositeType detailsType: describes the format of the returned CompositeData
454
455
     * @return javax.management.openmbean.CompositeData
456
     */
457
    private CompositeData buildDetailsFor(String mappedClassName, CompositeType detailsType) throws Exception {
458
        return new CompositeDataSupport(detailsType, buildLowlevelDetailsFor(mappedClassName));
459
    }
460
461
    /**
462
     * INTERNAL:
463
     * Helper to build a HashMap to help in the construction of a CompositeData
464
     *
465
     * @param String mappedClassName: fullyQualified class name of the class
466
467
     * @return HashMap
468
     */
469
    private HashMap buildLowlevelDetailsFor(String mappedClassName) {
470
        Class mappedClass = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(mappedClassName, ClassConstants.CLASS);
471
        IdentityMap identityMap = getSession().getIdentityMapAccessorInstance().getIdentityMap(mappedClass);
472
        ClassDescriptor descriptor = getSession().getProject().getDescriptor(mappedClass);
473
474
        String cacheType = getCacheTypeFor(identityMap.getClass());
475
        String configuredSize = "" + identityMap.getMaxSize();
476
        String currentSize = "";
477
478
        //show the current size, including subclasses 
479
        currentSize = "" + identityMap.getSize(mappedClass, true);
480
481
        String parentClassName = "";
482
483
        boolean isChildDescriptor = descriptor.isChildDescriptor();
484
485
        HashMap details = new HashMap();
486
487
        details.put("Class Name", mappedClassName);
488
        details.put("Cache Type", (isChildDescriptor ? "" : cacheType));
489
        details.put("Configured Size", (isChildDescriptor ? "" : configuredSize));
490
        details.put("Current Size", currentSize);
491
        //If I have a parent class name, get it. Otherwise, leave blank
492
        if (descriptor.hasInheritance()) {
493
            if (descriptor.getInheritancePolicy().getParentDescriptor() != null) {
494
                parentClassName = descriptor.getInheritancePolicy().getParentClassName();
495
            }
496
        }
497
        details.put("Parent Class Name", parentClassName);
498
499
        return details;
500
    }
501
502
    /**
503
     * INTERNAL:
504
     * Helper to build a HashMap to help in the construction of a CompositeData
505
     *
506
     * @param String mappedClassName: fullyQualified class name of the class
507
508
     * @return HashMap
509
     */
510
    private ClassSummaryDetail buildLowlevelDetailsForNew(String mappedClassName) {
511
        Class mappedClass = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(mappedClassName, ClassConstants.CLASS);
512
        IdentityMap identityMap = getSession().getIdentityMapAccessorInstance().getIdentityMap(mappedClass);
513
        ClassDescriptor descriptor = getSession().getProject().getDescriptor(mappedClass);
514
515
        String cacheType = getCacheTypeFor(identityMap.getClass());
516
        String configuredSize = "" + identityMap.getMaxSize();
517
        String currentSize = "";
518
519
        //show the current size, including subclasses 
520
        currentSize = "" + identityMap.getSize(mappedClass, true);
521
522
        String parentClassName = "";
523
524
        boolean isChildDescriptor = descriptor.isChildDescriptor();
525
526
        ClassSummaryDetail details = new ClassSummaryDetail(
527
                mappedClassName,
528
                (isChildDescriptor ? "" : cacheType),
529
                (isChildDescriptor ? "" : configuredSize),
530
                currentSize,
531
                parentClassName);
532
533
        return details;
534
    }
535
    
536
    /**
537
     * INTERNAL:
538
     * getCacheTypeFor: Give a more UI-friendly version of the cache type
539
     */
540
    private String getCacheTypeFor(Class identityMapClass) {
541
        if (identityMapClass == CacheIdentityMap.class) {
542
            return "Cache";
543
        } else if (identityMapClass == FullIdentityMap.class) {
544
            return "Full";
545
        } else if (identityMapClass == HardCacheWeakIdentityMap.class) {
546
            return "HardWeak";
547
        } else if (identityMapClass == NoIdentityMap.class) {
548
            return "None";
549
        } else if (identityMapClass == SoftCacheWeakIdentityMap.class) {
550
            return "SoftWeak";
551
        } else if (identityMapClass == WeakIdentityMap.class) {
552
            return "Weak";
553
        } else if (identityMapClass == SoftIdentityMap.class) {
554
            return "Soft";
555
        }
556
        return "N/A";
557
    }
558
559
    /**
560
     * getModuleName(): Answer the name of the context-root of the application that this session is associated with.
561
     * Answer "unknown" if there is no module name available.
562
     * Default behavior is to return "unknown"
563
     */
564
    public String getModuleName() {
565
        return ((DatabaseSessionImpl)getSession())
566
            .getServerPlatform().getModuleName();
567
    }
568
569
    
570
    /**
571
     * getApplicationName(): Answer the name of the module (EAR name) that this session is associated with.
572
     * Answer "unknown" if there is no application name available.
573
     * Default behavior is to return "unknown"
574
     */
575
    public String getApplicationName() {
576
        return ((WebSphere_7_Platform)((DatabaseSessionImpl)getSession())
577
                .getServerPlatform()).getApplicationName();
578
    }
579
    
580
    /**
581
     * PUBLIC: Answer the EclipseLink log level at deployment time. This is read-only.
582
     */
583
    public String getDeployedEclipseLinkLogLevel() {
584
        return getNameForLogLevel(getDeployedSessionLog().getLevel());
585
    }
586
587
    /**
588
     * PUBLIC: Answer the EclipseLink log level that is changeable.
589
     * This does not affect the log level in the project (i.e. The next
590
     * time the application is deployed, changes are forgotten)
591
     */
592
    public String getCurrentEclipseLinkLogLevel() {
593
        return getNameForLogLevel(this.getSession().getSessionLog().getLevel());
594
    }
595
596
    /**
597
     * PUBLIC: Set the EclipseLink log level to be used at runtime.
598
     *
599
     * This does not affect the log level in the project (i.e. The next
600
     * time the application is deployed, changes are forgotten)
601
     *
602
     * @param String newLevel: new log level
603
     */
604
    public synchronized void setCurrentEclipseLinkLogLevel(String newLevel) {
605
        this.getSession().setLogLevel(this.getLogLevelForName(newLevel));
606
    }
607
608
    /**
609
     * INTERNAL: Answer the name for the log level given.
610
     *
611
     * @return String (one of OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL)
612
     */
613
    private String getNameForLogLevel(int logLevel) {
614
        switch (logLevel) {
615
        case SessionLog.ALL:
616
            return SessionLog.ALL_LABEL;
617
        case SessionLog.SEVERE:
618
            return SessionLog.SEVERE_LABEL;
619
        case SessionLog.WARNING:
620
            return SessionLog.WARNING_LABEL;
621
        case SessionLog.INFO:
622
            return SessionLog.INFO_LABEL;
623
        case SessionLog.CONFIG:
624
            return SessionLog.CONFIG_LABEL;
625
        case SessionLog.FINE:
626
            return SessionLog.FINE_LABEL;
627
        case SessionLog.FINER:
628
            return SessionLog.FINER_LABEL;
629
        case SessionLog.FINEST:
630
            return SessionLog.FINEST_LABEL;
631
        case SessionLog.OFF:
632
            return SessionLog.OFF_LABEL;
633
        }
634
        return "N/A";
635
    }
636
637
    /**
638
     * INTERNAL: Answer the log level for the given name.
639
     *
640
     * @return int for OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
641
     */
642
    private int getLogLevelForName(String levelName) {
643
        if (levelName.equals(SessionLog.ALL_LABEL)) {
644
            return SessionLog.ALL;
645
        }
646
        if (levelName.equals(SessionLog.SEVERE_LABEL)) {
647
            return SessionLog.SEVERE;
648
        }
649
        if (levelName.equals(SessionLog.WARNING_LABEL)) {
650
            return SessionLog.WARNING;
651
        }
652
        if (levelName.equals(SessionLog.INFO_LABEL)) {
653
            return SessionLog.INFO;
654
        }
655
        if (levelName.equals(SessionLog.CONFIG_LABEL)) {
656
            return SessionLog.CONFIG;
657
        }
658
        if (levelName.equals(SessionLog.FINE_LABEL)) {
659
            return SessionLog.FINE;
660
        }
661
        if (levelName.equals(SessionLog.FINER_LABEL)) {
662
            return SessionLog.FINER;
663
        }
664
        if (levelName.equals(SessionLog.FINEST_LABEL)) {
665
            return SessionLog.FINEST;
666
        }
667
        return SessionLog.OFF;
668
    }
669
670
    /**
671
     *     Method returns if all Parameters should be bound or not
672
     */
673
    public Boolean getShouldBindAllParameters() {
674
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
675
            return Boolean.FALSE;
676
        }
677
        return Boolean.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).shouldBindAllParameters());
678
    }
679
680
    /**
681
      *     Return the size of strings after which will be bound into the statement
682
      *     If we are not using a DatabaseLogin, or we're not using string binding,
683
      *     answer 0 (zero).
684
      */
685
    public Integer getStringBindingSize() {
686
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
687
            return Integer.valueOf(0);
688
        }
689
        if (!((DatabaseLogin)getSession().getDatasourceLogin()).getPlatform().usesStringBinding()) {
690
            return Integer.valueOf(0);
691
        }
692
        return Integer.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).getStringBindingSize());
693
    }
694
695
    /**
696
      *        This method will return if batchWriting is in use or not.
697
      */
698
    public Boolean getUsesBatchWriting() {
699
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesBatchWriting());
700
    }
701
702
    /**
703
      *        This method will return a long indicating the exact time in Milliseconds that the
704
      *   session connected to the database.
705
      */
706
    public Long getTimeConnectionEstablished() {
707
        return Long.valueOf(((DatabaseSessionImpl)getSession()).getConnectedTime());
708
    }
709
710
    /**
711
      *        This method will return if batchWriting is in use or not.
712
      */
713
    public Boolean getUsesJDBCBatchWriting() {
714
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesJDBCBatchWriting());
715
    }
716
717
    /**
718
      *     Shows if Byte Array Binding is turned on or not
719
      */
720
    public Boolean getUsesByteArrayBinding() {
721
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesByteArrayBinding());
722
    }
723
724
    /**
725
      *     Shows if native SQL is being used
726
      */
727
    public Boolean getUsesNativeSQL() {
728
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesNativeSQL());
729
    }
730
731
    /**
732
      *     This method indicates if streams are being used for binding
733
      */
734
    public Boolean getUsesStreamsForBinding() {
735
        return Boolean.valueOf(getSession().getDatasourceLogin().getPlatform().usesStreamsForBinding());
736
    }
737
738
    /**
739
      *     This method indicates if Strings are being bound
740
      */
741
    public Boolean getUsesStringBinding() {
742
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
743
            return Boolean.FALSE;
744
        }
745
        return Boolean.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).getPlatform().usesStringBinding());
746
    }
747
748
    /**
749
    *     Returns if statements should be cached or not
750
    */
751
    public boolean getShouldCacheAllStatements() {
752
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
753
            return Boolean.FALSE;
754
        }
755
        return Boolean.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).shouldCacheAllStatements());
756
    }
757
758
    /**
759
    *        Returns the statement cache size.  Only valid if statements are being cached
760
    */
761
    public int getStatementCacheSize() {
762
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
763
            return 0;
764
        }
765
        return Integer.valueOf(((DatabaseLogin)getSession().getDatasourceLogin()).getStatementCacheSize());
766
    }
767
768
    /**
769
    *     Used to clear the statement cache. Only valid if statements are being cached
770
    */
771
    public synchronized void clearStatementCache() {
772
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
773
            return;
774
        }
775
        ((DatabaseAccessor)getSession().getAccessor()).clearStatementCache(getSession());
776
        ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_statement_cache_cleared");        
777
        
778
    }
779
780
    /**
781
    *        Method returns the value of the Sequence Preallocation size
782
    */
783
    public int getSequencePreallocationSize() {
784
        if (!(getSession().getDatasourceLogin() instanceof DatabaseLogin)) {
785
            return 0;
786
        }
787
        return ((DatasourcePlatform)getSession().getDatasourcePlatform()).getSequencePreallocationSize();        
788
    }
789
790
    /**
791
    *     This method will print the available Connection pools to the SessionLog.
792
    * @return void
793
    */
794
    public void printAvailableConnectionPools() {
795
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
796
            Map pools = ((ServerSession)getSession()).getConnectionPools();
797
            Iterator poolNames = pools.keySet().iterator();
798
            while (poolNames.hasNext()) {
799
                String poolName = poolNames.next().toString();
800
                ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_pool_name", poolName);
801
            }
802
        } else {
803
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_connection_pools_available");            
804
            
805
        }
806
    }
807
808
    /**
809
    *     This method will retrieve the max size of a particular connection pool
810
    * @param poolName the name of the pool to get the max size for
811
    * @return Integer for the max size of the pool. Return -1 if pool doesn't exist.
812
    */
813
    public Integer getMaxSizeForPool(String poolName) {
814
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
815
            ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
816
            if (connectionPool != null) {
817
                return Integer.valueOf(connectionPool.getMaxNumberOfConnections());
818
            }
819
        }
820
        return Integer.valueOf(-1);
821
    }
822
823
    /**
824
    *     This method will retrieve the min size of a particular connection pool
825
    * @param poolName the name of the pool to get the min size for
826
    * @return Integer for the min size of the pool. Return -1 if pool doesn't exist.
827
    */
828
    public Integer getMinSizeForPool(String poolName) {
829
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
830
            ConnectionPool connectionPool = ((ServerSession)getSession()).getConnectionPool(poolName);
831
            if (connectionPool != null) {
832
                return Integer.valueOf(connectionPool.getMinNumberOfConnections());
833
            }
834
        }
835
        return Integer.valueOf(-1);
836
    }
837
838
    /**
839
    * This method is used to reset connections from the session to the database.  Please
840
    * Note that this will not work with a SessionBroker at this time
841
    */
842
    public synchronized void resetAllConnections() {
843
        if (ClassConstants.ServerSession_Class.isAssignableFrom(getSession().getClass())) {
844
            Iterator enumtr = ((ServerSession)getSession()).getConnectionPools().values().iterator();
845
            while (enumtr.hasNext()) {
846
                ConnectionPool pool = (ConnectionPool)enumtr.next();
847
                pool.shutDown();
848
                pool.startUp();
849
            }
850
        } else if (ClassConstants.PublicInterfaceDatabaseSession_Class.isAssignableFrom(getSession().getClass())) {
851
            getSession().getAccessor().reestablishConnection(getSession());
852
        }
853
    }
854
855
    /**
856
    *        This method is used to output those Class Names that have identity Maps in the Session.
857
    * Please note that SubClasses and aggregates will be missing from this list as they do not have
858
    * separate identity maps.
859
    * @return void
860
    */
861
    public void printClassesInSession() {
862
        Vector classes = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
863
        int index;
864
        if (classes.isEmpty()) {
865
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_classes_in_session");            
866
            return;
867
        }
868
869
        for (index = 0; index < classes.size(); index++) {
870
            getSession().getSessionLog().log(SessionLog.FINEST, (String)classes.elementAt(index));
871
        }
872
    }
873
874
    /**
875
    *        This method will log the objects in the Identity Map.
876
    * There is no particular order to these objects.
877
    * @param className the fully qualified classname identifying the identity map
878
    * @exception  thrown then the IdentityMap for that class name could not be found
879
    */
880
    public void printObjectsInIdentityMap(String className) throws ClassNotFoundException {
881
        Class classWithMap = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
882
        IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(classWithMap);
883
884
        //check if the identity map exists
885
        if (null == map) {
886
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_non_existent", className);
887
            return;
888
        }
889
890
        //check if there are any objects in the identity map. Print if so.
891
        Enumeration objects = map.keys();
892
        if (!objects.hasMoreElements()) {
893
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_empty", className);
894
        }
895
896
        CacheKey cacheKey;
897
        while (objects.hasMoreElements()) {
898
            cacheKey = (CacheKey)objects.nextElement();
899
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_print_cache_key_value", 
900
                    cacheKey.getKey().toString(), cacheKey.getObject().toString());
901
        }
902
    }
903
904
    /**
905
    *        This method will log the types of Identity Maps in the session.
906
    */
907
    public void printAllIdentityMapTypes() {
908
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
909
        String registeredClassName;
910
        Class registeredClass;
911
912
        //Check if there aren't any classes registered
913
        if (classesRegistered.size() == 0) {
914
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
915
            return;
916
        }
917
918
        //get each identity map, and log the type
919
        for (int index = 0; index < classesRegistered.size(); index++) {
920
            registeredClassName = (String)classesRegistered.elementAt(index);
921
            registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(registeredClassName, ClassConstants.CLASS);
922
            IdentityMap map = getSession().getIdentityMapAccessorInstance().getIdentityMap(registeredClass);
923
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_class", 
924
                    registeredClassName, map.getClass());
925
        }
926
    }
927
928
    /**
929
    *        This method will log all objects in all Identity Maps in the session.
930
    */
931
    public void printObjectsInIdentityMaps() {
932
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
933
        String registeredClassName;
934
935
        //Check if there aren't any classes registered
936
        if (classesRegistered.size() == 0) {
937
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
938
            return;
939
        }
940
941
        //get each identity map, and log the type
942
        for (int index = 0; index < classesRegistered.size(); index++) {
943
            registeredClassName = (String)classesRegistered.elementAt(index);
944
            try {
945
                this.printObjectsInIdentityMap(registeredClassName);
946
            } catch (ClassNotFoundException classNotFound) {
947
                //we are enumerating registered classes, so this shouldn't happen. Print anyway
948
                classNotFound.printStackTrace();
949
                AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", classNotFound);
950
            }
951
        }
952
    }
953
954
    /**
955
    *        This method is used to return the number of objects in a particular Identity Map
956
    * @param className the fully qualified name of the class to get number of instances of.
957
    * @exception  thrown then the IdentityMap for that class name could not be found
958
    */
959
    public Integer getNumberOfObjectsInIdentityMap(String className) throws ClassNotFoundException {
960
        //BUG 3982060: Always use the root class in combination with the identity map's getSize(class, true) to get an accurate count
961
        Class classWithIdentityMap = (Class)getSession().getDatasourcePlatform().getConversionManager().convertObject(className, ClassConstants.CLASS);
962
        Class rootClass = null;
963
964
        ClassDescriptor descriptor = getSession().getDescriptor(classWithIdentityMap);
965
        ClassDescriptor rootDescriptor;
966
967
        if (descriptor.hasInheritance()) {
968
            rootDescriptor = descriptor.getInheritancePolicy().getRootParentDescriptor();
969
        } else {
970
            rootDescriptor = descriptor;
971
        }
972
        if (rootDescriptor.getCMPPolicy() != null) {
973
            if (rootDescriptor.getCMPPolicy().getMappedClass() != null) {
974
                rootClass = rootDescriptor.getCMPPolicy().getMappedClass();
975
            }
976
        }
977
978
        if (rootClass == null) {
979
            rootClass = rootDescriptor.getJavaClass();
980
        }
981
982
        return Integer.valueOf(getSession().getIdentityMapAccessorInstance().getIdentityMap(rootClass).getSize(rootClass, true));
983
    }
984
985
    /**
986
    *        This method will SUM and return the number of objects in all Identity Maps in the session.
987
    */
988
    public Integer getNumberOfObjectsInAllIdentityMaps() {
989
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
990
        String registeredClassName;
991
        int sum = 0;
992
993
        //Check if there aren't any classes registered
994
        if (classesRegistered.size() == 0) {
995
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");
996
            return Integer.valueOf(0);
997
        }
998
999
        //get each identity map, and log the size
1000
        for (int index = 0; index < classesRegistered.size(); index++) {
1001
            registeredClassName = (String)classesRegistered.elementAt(index);
1002
            try {
1003
                sum += this.getNumberOfObjectsInIdentityMap(registeredClassName).intValue();
1004
            } catch (ClassNotFoundException classNotFound) {
1005
                //we are enumerating registered classes, so this shouldn't happen. Print anyway
1006
                classNotFound.printStackTrace();
1007
                AbstractSessionLog.getLog().log(SessionLog.SEVERE, "weblogic_mbean_runtime_exception", classNotFound);
1008
            }
1009
        }
1010
1011
        return Integer.valueOf(sum);
1012
    }
1013
1014
    /**
1015
     * This method will answer the number of persistent classes contained in the session.
1016
     * This does not include aggregates.
1017
     */
1018
    public Integer getNumberOfPersistentClasses() {
1019
        Hashtable classesTable = new Hashtable();
1020
        ClassDescriptor currentDescriptor;
1021
1022
        //use a table to eliminate duplicate classes. Ignore Aggregates
1023
        Iterator descriptors = getSession().getProject().getDescriptors().values().iterator();
1024
        while (descriptors.hasNext()) {
1025
            currentDescriptor = (ClassDescriptor)descriptors.next();
1026
            if (!currentDescriptor.isAggregateDescriptor()) {
1027
                classesTable.put(currentDescriptor.getJavaClassName(), Boolean.TRUE);
1028
            }
1029
        }
1030
1031
        return Integer.valueOf(classesTable.size());
1032
    }
1033
1034
    /**
1035
    * Return the log type, either "EclipseLink",  "Java" or the simple name of the logging class used.  
1036
    *
1037
    * @return the log type
1038
    */
1039
    public String getLogType() {
1040
        if (this.getSession().getSessionLog().getClass() == JavaLog.class) {
1041
            return "Java";
1042
        } else if (this.getSession().getSessionLog().getClass() == DefaultSessionLog.class) {
1043
            return EclipseLink_Product_Name;
1044
        } else {
1045
            return this.getSession().getSessionLog().getClass().getSimpleName();
1046
        }
1047
    }
1048
1049
    /**
1050
    * Return the database platform used by the DatabaseSession.
1051
    *
1052
    * @return String databasePlatform
1053
    */
1054
    public String getDatabasePlatform() {
1055
        return getSession().getDatasourcePlatform().getClass().getName();
1056
    }
1057
1058
    /**
1059
    *        Return JDBCConnection detail information. This includes URL and datasource information.
1060
    */
1061
    public synchronized String getJdbcConnectionDetails() {
1062
        return getSession().getLogin().getConnector().getConnectionDetails();
1063
    }
1064
1065
    /**
1066
    *        Return connection pool type. Values include: "Internal", "External" and "N/A".
1067
    */
1068
    public synchronized String getConnectionPoolType() {
1069
        if (getSession().getLogin().shouldUseExternalConnectionPooling()) {
1070
            return "External";
1071
        } else {
1072
            return "N/A";
1073
        }
1074
    }
1075
1076
    /**
1077
    *        Return db driver class name. This only applies to DefaultConnector. Return "N/A" otherwise.
1078
    */
1079
    public synchronized String getDriver() {
1080
        if (getSession().getLogin().getConnector() instanceof DefaultConnector) {
1081
            return getSession().getLogin().getDriverClassName();
1082
        }
1083
        return "N/A";
1084
    }
1085
1086
    /**
1087
    * Return the log filename. This returns the fully qualified path of the log file when
1088
    * EclipseLink DefaultSessionLog instance is used. Null is returned otherwise.
1089
    *
1090
    * @return String logFilename
1091
    */
1092
    public String getLogFilename() {
1093
        // returns String or null.
1094
        if ( session.getSessionLog() instanceof DefaultSessionLog) {
1095
                return ((DefaultSessionLog)session.getSessionLog()).getWriterFilename();
1096
        } else {
1097
            return null;
1098
        }
1099
    }
1100
1101
    /**
1102
    *    This method is used to initialize the identity maps in the session.
1103
    */
1104
    public synchronized void initializeAllIdentityMaps() {
1105
        getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
1106
    }
1107
1108
    /**
1109
    *    This method is used to initialize the identity maps specified by the Vector of classNames.
1110
    *
1111
    * @param classNames String[] of fully qualified classnames identifying the identity maps to initialize
1112
    */
1113
    public synchronized void initializeIdentityMaps(String[] classNames) throws ClassNotFoundException {
1114
        for (int index = 0; index < classNames.length; index++) {
1115
            initializeIdentityMap(classNames[index]);
1116
        }
1117
    }
1118
1119
    /**
1120
    *    This method is used to invalidate the identity maps in the session.
1121
    */
1122
    public synchronized void invalidateAllIdentityMaps() {
1123
        Vector classesRegistered = getSession().getIdentityMapAccessorInstance().getIdentityMapManager().getClassesRegistered();
1124
        String registeredClassName;
1125
        Class registeredClass;
1126
1127
        if (classesRegistered.isEmpty()) {
1128
            getSession().getSessionLog().info("There are no Identity Maps in this session");
1129
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_no_identity_maps_in_session");            
1130
        }
1131
1132
        //get each identity map, and invalidate
1133
        for (int index = 0; index < classesRegistered.size(); index++) {
1134
            registeredClassName = (String)classesRegistered.elementAt(index);
1135
            registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
1136
                .convertObject(registeredClassName, ClassConstants.CLASS);
1137
            getSession().getIdentityMapAccessor().invalidateClass(registeredClass);
1138
            ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_invalidated", registeredClassName);
1139
        }
1140
    }
1141
1142
    /**
1143
    *    This method is used to invalidate the identity maps specified by the String[] of classNames.
1144
    *
1145
    * @param classNames String[] of fully qualified classnames identifying the identity maps to invalidate
1146
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
1147
    */
1148
    public synchronized void invalidateIdentityMaps(String[] classNamesParam, Boolean recurse) throws ClassNotFoundException {
1149
        String[] classNames = classNamesParam;
1150
        for (int index = 0; index < classNames.length; index++) {
1151
            invalidateIdentityMap(classNames[index], recurse);
1152
        }
1153
    }
1154
1155
    /**
1156
    *    This method is used to invalidate the identity maps specified by className. This does not
1157
    * invalidate the children identity maps
1158
    *
1159
    * @param className the fully qualified classname identifying the identity map to invalidate
1160
    */
1161
    public synchronized void invalidateIdentityMap(String className) throws ClassNotFoundException {
1162
        this.invalidateIdentityMap(className, Boolean.FALSE);
1163
    }
1164
1165
    /**
1166
    *    This method is used to invalidate the identity maps specified by className.
1167
    *
1168
    * @param className the fully qualified classname identifying the identity map to invalidate
1169
    * @param recurse    Boolean indicating if we want to invalidate the children identity maps too
1170
    */
1171
    public synchronized void invalidateIdentityMap(String className, Boolean recurse) throws ClassNotFoundException {
1172
        Class registeredClass;
1173
1174
        //get identity map, and invalidate
1175
        registeredClass = (Class)getSession().getDatasourcePlatform().getConversionManager()
1176
            .convertObject(className, ClassConstants.CLASS);
1177
        getSession().getIdentityMapAccessor().invalidateClass(registeredClass);
1178
        ((AbstractSession)session).log(SessionLog.INFO, SessionLog.SERVER, "jmx_mbean_runtime_services_identity_map_invalidated", className);
1179
    }
1180
1181
    /**
1182
     * 
1183
    * INTERNAL:
1184
     * Convert the TabularData to a two-dimensional array
1185
     * @param tdata the TabularData to be converted
1186
     * @param names the order of the columns
1187
     * @return a two-dimensional array
1188
     * @throws Exception
1189
     */
1190
    private Object[][] tabularDataTo2DArray(TabularData tdata, String[] names) throws Exception {
1191
        if(tdata==null){
1192
            return null;
1193
        }
1194
        Object[] rows = tdata.values().toArray();
1195
        Object[][] data = new Object[rows.length][];
1196
1197
        for (int i=0; i<rows.length; i++) {
1198
            data[i] = ((CompositeData) rows[i]).getAll(names);
1199
        }
1200
        return data;
1201
    }
1202
    
1203
    
1204
    /**
1205
     * Return whether this session is an EclipseLink JPA session.
1206
     * The absence of this function or a value of false will signify that the session
1207
     * belongs to a provider other than EclipseLink.  
1208
     * @return
1209
     */
1210
    public boolean isJPASession() {
1211
        return true;
1212
    }
1213
}

Return to bug 316513