com.sun.enterprise.admin.monitor.stats.GenericStatsImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of stats77 Show documentation
Show all versions of stats77 Show documentation
Interim replacement for JSR 77 Stats and Statistics
The newest version!
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package com.sun.enterprise.admin.monitor.stats;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import org.glassfish.j2ee.statistics.Stats;
import org.glassfish.j2ee.statistics.Statistic;
/**
* Provides for generic implementation of any Stats interface. This class facilitates
* composition over inheritance for all the classes that implement their
* specific Stats interfaces. None of them has to implement the methods defined
* by the {@link org.glassfish.j2ee.statistics.Stats} interface. This class
* implements the same interface and does that job. All that implementing classes
* have to do is implement the specific accessing methods in their Stats interfaces
* and delegate the rest to this class. This class invokes all these methods in
* implementing class through introspection.
*
* @author Kedar Mhaswade
* @since S1AS8.0
* @version $Version$
*/
public class GenericStatsImpl implements Stats {
private final Class statsInterface;
private final Object statsProvider;
/** A map with binding of a String XXX to a method with name getXXX */
private final Map getters;
/**
*/
public GenericStatsImpl(String statsInterfaceName, Object statsProvider)
throws ClassNotFoundException {
this(statsInterfaceName, GenericStatsImpl.class.getClassLoader(), statsProvider);
}
/**
*/
public GenericStatsImpl(String statsInterfaceName, ClassLoader loader,
Object statsProvider) throws ClassNotFoundException {
this(Class.forName(statsInterfaceName, true, loader), statsProvider);
}
/** Constructs a new instance of this class for a given interface and its implementation.
* It is mandatory that following contract is satisfied to call this satisfactorily:
*
* - None of the parameters are null.
* - Given statsProvider implements the given statsInterface.
* - Given statsInterface has to extend the @{link Stats} interface.
*
* Note that it is expected (though not mandatory) to have a getXXX method that
* does not return an instance of {@link Statistic} interface.
* @throws NullPointerException if any of the given parameters are null
* @throws IllegalArgumentException if the contract is not satisfied by given parameters
*/
public GenericStatsImpl(Class statsInterface, Object statsProvider) {
if (! implementsInterface(statsInterface, statsProvider) ||
! extendsStatsInterface(statsInterface)) {
throw new IllegalArgumentException("Contract violation: invalid interface-implementation pair");
}
this.statsProvider = statsProvider;
this.statsInterface = statsInterface;
this.getters = new HashMap();
populateGetterMap();
}
@Override
public Statistic getStatistic(String statisticName) {
final Method getter = (Method) getters.get(statisticName);
assert (getter != null) : ("Getter not initialized properly: " + statisticName);
Object result = null;
try {
result = getter.invoke(statsProvider);
}
catch(Exception e) {
final RuntimeException oe = new IllegalStateException();
oe.initCause(e);
throw oe;
}
return ( (Statistic)result );
}
@Override
public String[] getStatisticNames() {
/* The return array is fixed at the construction time */
final String[] names = new String[getters.size()];
return ( (String[])getters.keySet().toArray(names) ); //TODOOOOOOO
}
@Override
public Statistic[] getStatistics() {
return ( getStatisticsOneByOne() ); //invokes sequentially
}
private Statistic[] getStatisticsOneByOne() {
final Iterator iter = getters.keySet().iterator();
final Statistic[] stats = new Statistic[getters.keySet().size()];
int i = 0;
while (iter.hasNext()) {
final String sn = (String) iter.next();
stats[i++] = this.getStatistic(sn);
}
assert (stats.length == i);
return ( stats );
}
private boolean implementsInterface(Class c, Object o) {
boolean impls = false;
final Class[] interfaces = o.getClass().getInterfaces();
for (Class element : interfaces) {
if (element.equals(c)){
impls = true;
break;
}
}
return ( impls );
}
private boolean extendsStatsInterface(Class i) {
final Class statsInterface = org.glassfish.j2ee.statistics.Stats.class;
return ( statsInterface.isAssignableFrom(i) );
}
private void populateGetterMap() {
// Fix for Bugs 5045435, 6172088
//final Method[] apis = statsInterface.getDeclaredMethods(); //all of these should be PUBLIC.
final Method[] m = statsInterface.getMethods();
// exclude methods that belong to the javax.management.j2ee.Stats
final Method[] apis = filterStatsMethods(m);
final Method[] methods = getGetters(apis);
final String[] names = methods2Statistics(methods);
assert (names.length == methods.length) : ("Statistic names array is not having same length as that of array of getters");
int i;
for (i = 0 ; i < names.length ; i++) {
getters.put(names[i], methods[i]);
}
assert (getters.size() == i) : ("Getters map is incorrect, names.length = " + names.length + " methods.length = " + methods.length);
}
private Method[] getGetters(Method[] all) {
final ArrayList l = new ArrayList();
for (final Method am : all) {
if (isValidGetter(am)) {
l.add(am);
}
}
final Method[] m = new Method[l.size()];
return ( (Method[])l.toArray(m) );
}
private boolean isValidGetter(Method m) {
final boolean startsWithGet = m.getName().startsWith("get");
final boolean hasNoParams = m.getParameterTypes().length == 0;
final boolean returnsStatistic = Statistic.class.isAssignableFrom(m.getReturnType());
return ( startsWithGet && hasNoParams && returnsStatistic );
}
private String[] methods2Statistics(Method[] methods) {
final String[] names = new String[methods.length];
for (int i = 0 ; i < methods.length ; i++) {
final String m = methods[i].getName();
final int s = "get".length();
names[i] = m.substring(s);
}
return ( names );
}
private boolean isStatsInterfaceMethod(String name) {
final Method[] methods = org.glassfish.j2ee.statistics.Stats.class.getMethods();
boolean isInterfaceMethod = false;
for (Method method : methods) {
if (method.getName().equals(name)) {
isInterfaceMethod = true;
break;
}
}
return ( isInterfaceMethod );
}
private Method[] filterStatsMethods(Method[] m) {
ArrayList methodList = new ArrayList();
for (Method element : m) {
if(! isStatsInterfaceMethod(element.getName())) {
methodList.add(element);
}
}
final Method[] methods = new Method[methodList.size()];
return (Method[])methodList.toArray(methods);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy