/*
* 2012-3 Red Hat Inc. and/or its affiliates and other contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.overlord.rtgov.active.collection.jmx;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import org.mvel2.MVEL;
import org.overlord.rtgov.active.collection.AbstractActiveChangeListener;
/**
* This class provides an active change listener for reporting
* changes as JMX notifications.
*
*/
public class JMXNotifier extends AbstractActiveChangeListener
implements JMXNotifierMBean, javax.management.NotificationEmitter {
private static final Logger LOG=Logger.getLogger(JMXNotifier.class.getName());
private String _objectName=null;
private String _insertType=null;
private String _updateType=null;
private String _removeType=null;
private int _sequenceNumber=1;
private java.util.List<NotificationDetails> _notificationDetails=
new java.util.ArrayList<NotificationDetails>();
private String _descriptionScript=null;
private java.io.Serializable _descriptionScriptExpression=null;
private String _insertTypeScript=null;
private java.io.Serializable _insertTypeScriptExpression=null;
private String _updateTypeScript=null;
private java.io.Serializable _updateTypeScriptExpression=null;
private String _removeTypeScript=null;
private java.io.Serializable _removeTypeScriptExpression=null;
private boolean _preinitialized=false;
/**
* This method sets the object name for the JMX MBean.
*
* @param name The object name
*/
public void setObjectName(String name) {
_objectName = name;
}
/**
* This method gets the object name for the JMX MBean.
*
* @return The object name
*/
public String getObjectName() {
return (_objectName);
}
/**
* This method sets the description script for the JMX MBean.
*
* @param script The description script
*/
public void setDescriptionScript(String script) {
_descriptionScript = script;
}
/**
* This method gets the description script for the JMX MBean.
*
* @return The description script
*/
public String getDescriptionScript() {
return (_descriptionScript);
}
/**
* This method sets the insert type for the JMX MBean.
*
* @param type The insert type
*/
public void setInsertType(String type) {
_insertType = type;
}
/**
* This method gets the insert type for the JMX MBean.
*
* @return The insert type
*/
public String getInsertType() {
return (_insertType);
}
/**
* This method sets the insert type script for the JMX MBean.
*
* @param script The insert type script
*/
public void setInsertTypeScript(String script) {
_insertTypeScript = script;
}
/**
* This method gets the insert type script for the JMX MBean.
*
* @return The insert type script
*/
public String getInsertTypeScript() {
return (_insertTypeScript);
}
/**
* This method sets the update type for the JMX MBean.
*
* @param type The update type
*/
public void setUpdateType(String type) {
_updateType = type;
}
/**
* This method gets the update type for the JMX MBean.
*
* @return The update type
*/
public String getUpdateType() {
return (_updateType);
}
/**
* This method sets the update type script for the JMX MBean.
*
* @param script The update type script
*/
public void setUpdateTypeScript(String script) {
_updateTypeScript = script;
}
/**
* This method gets the update type script for the JMX MBean.
*
* @return The update type script
*/
public String getUpdateTypeScript() {
return (_updateTypeScript);
}
/**
* This method sets the remove type for the JMX MBean.
*
* @param type The remove type
*/
public void setRemoveType(String type) {
_removeType = type;
}
/**
* This method gets the remove type for the JMX MBean.
*
* @return The remove type
*/
public String getRemoveType() {
return (_removeType);
}
/**
* This method sets the remove type script for the JMX MBean.
*
* @param script The remove type script
*/
public void setRemoveTypeScript(String script) {
_removeTypeScript = script;
}
/**
* This method gets the remove type script for the JMX MBean.
*
* @return The remove type script
*/
public String getRemoveTypeScript() {
return (_removeTypeScript);
}
/**
* {@inheritDoc}
*/
protected void preInit() throws Exception {
super.preInit();
if (!_preinitialized) {
_preinitialized = true;
// Only initialize if the script is specified, but not yet compiled
if (_descriptionScript != null && _descriptionScriptExpression == null) {
java.io.InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream(_descriptionScript);
if (is == null) {
LOG.severe(MessageFormat.format(
java.util.PropertyResourceBundle.getBundle(
"active-collection.Messages").getString("ACTIVE-COLLECTION-1"),
_descriptionScript));
} else {
byte[] b=new byte[is.available()];
is.read(b);
is.close();
// Compile expression
_descriptionScriptExpression = MVEL.compileExpression(new String(b));
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Pre-Initialized description script="+_descriptionScript
+" compiled="+_descriptionScriptExpression);
}
}
}
// Only initialize if the script is specified, but not yet compiled
if (_insertTypeScript != null && _insertTypeScriptExpression == null) {
java.io.InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream(_insertTypeScript);
if (is == null) {
LOG.severe(MessageFormat.format(
java.util.PropertyResourceBundle.getBundle(
"active-collection.Messages").getString("ACTIVE-COLLECTION-1"),
_insertTypeScript));
} else {
byte[] b=new byte[is.available()];
is.read(b);
is.close();
// Compile expression
_insertTypeScriptExpression = MVEL.compileExpression(new String(b));
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Pre-Initialized insert type script="+_insertTypeScript
+" compiled="+_insertTypeScriptExpression);
}
}
}
// Only initialize if the script is specified, but not yet compiled
if (_updateTypeScript != null && _updateTypeScriptExpression == null) {
java.io.InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream(_updateTypeScript);
if (is == null) {
LOG.severe(MessageFormat.format(
java.util.PropertyResourceBundle.getBundle(
"active-collection.Messages").getString("ACTIVE-COLLECTION-1"),
_updateTypeScript));
} else {
byte[] b=new byte[is.available()];
is.read(b);
is.close();
// Compile expression
_updateTypeScriptExpression = MVEL.compileExpression(new String(b));
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Pre-Initialized update type script="+_updateTypeScript
+" compiled="+_updateTypeScriptExpression);
}
}
}
// Only initialize if the script is specified, but not yet compiled
if (_removeTypeScript != null && _removeTypeScriptExpression == null) {
java.io.InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream(_removeTypeScript);
if (is == null) {
LOG.severe(MessageFormat.format(
java.util.PropertyResourceBundle.getBundle(
"active-collection.Messages").getString("ACTIVE-COLLECTION-1"),
_removeTypeScript));
} else {
byte[] b=new byte[is.available()];
is.read(b);
is.close();
// Compile expression
_removeTypeScriptExpression = MVEL.compileExpression(new String(b));
if (LOG.isLoggable(Level.FINE)) {
LOG.fine("Pre-Initialized remove type script="+_removeTypeScript
+" compiled="+_removeTypeScriptExpression);
}
}
}
}
}
/**
* This method returns the description associated with the
* supplied value.
*
* @param value The value
* @return The description
*/
protected String getDescription(Object value) {
String description=value.toString();
if (_descriptionScriptExpression != null) {
description = (String)MVEL.executeExpression(_descriptionScriptExpression, value);
}
return (description);
}
/**
* This method returns the type associated with the value.
*
* @param value The value
* @return The insert type
*/
protected String getInsertType(Object value) {
String type=_insertType;
if (type == null && _insertTypeScriptExpression != null) {
type = (String)MVEL.executeExpression(_insertTypeScriptExpression, value);
}
return (type);
}
/**
* {@inheritDoc}
*/
public void inserted(Object key, Object value) {
String type=getInsertType(value);
if (type != null) {
Notification notification=new Notification(type, this,
_sequenceNumber++, getDescription(value));
for (NotificationDetails n : _notificationDetails) {
n.getListener().handleNotification(notification, n.getHandback());
}
}
}
/**
* This method returns the type associated with the value.
*
* @param value The value
* @return The update type
*/
protected String getUpdateType(Object value) {
String type=_updateType;
if (type == null && _updateTypeScriptExpression != null) {
type = (String)MVEL.executeExpression(_updateTypeScriptExpression, value);
}
return (type);
}
/**
* {@inheritDoc}
*/
public void updated(Object key, Object value) {
String type=getUpdateType(value);
if (type != null) {
Notification notification=new Notification(type, this,
_sequenceNumber++, getDescription(value));
for (NotificationDetails n : _notificationDetails) {
n.getListener().handleNotification(notification, n.getHandback());
}
}
}
/**
* This method returns the type associated with the value.
*
* @param value The value
* @return The remove type
*/
protected String getRemoveType(Object value) {
String type=_removeType;
if (type == null && _removeTypeScriptExpression != null) {
type = (String)MVEL.executeExpression(_removeTypeScriptExpression, value);
}
return (type);
}
/**
* {@inheritDoc}
*/
public void removed(Object key, Object value) {
String type=getRemoveType(value);
if (type != null) {
Notification notification=new Notification(type, this,
_sequenceNumber++, getDescription(value));
for (NotificationDetails n : _notificationDetails) {
n.getListener().handleNotification(notification, n.getHandback());
}
}
}
/**
* {@inheritDoc}
*/
public void addNotificationListener(NotificationListener l,
NotificationFilter filter, Object handback)
throws IllegalArgumentException {
_notificationDetails.add(new NotificationDetails(l, filter, handback));
}
/**
* {@inheritDoc}
*/
public MBeanNotificationInfo[] getNotificationInfo() {
return new MBeanNotificationInfo[0];
}
/**
* {@inheritDoc}
*/
public void removeNotificationListener(NotificationListener l)
throws ListenerNotFoundException {
boolean f_found=false;
for (int i=_notificationDetails.size()-1; i >= 0; i--) {
NotificationDetails n=_notificationDetails.get(i);
if (n.getListener() == l) {
_notificationDetails.remove(i);
f_found = true;
}
}
if (!f_found) {
throw new ListenerNotFoundException();
}
}
/**
* {@inheritDoc}
*/
public void removeNotificationListener(NotificationListener l,
NotificationFilter filter, Object handback)
throws ListenerNotFoundException {
boolean f_found=false;
for (int i=_notificationDetails.size()-1; i >= 0; i--) {
NotificationDetails n=_notificationDetails.get(i);
if (n.getListener() == l && n.getFilter() == filter
&& n.getHandback() == handback) {
_notificationDetails.remove(i);
f_found = true;
break;
}
}
if (!f_found) {
throw new ListenerNotFoundException();
}
}
/**
* This class provides a container for the listener details.
*
*/
protected class NotificationDetails {
private NotificationListener _listener=null;
private NotificationFilter _filter=null;
private Object _handback=null;
/**
* This is the constructor.
*
* @param listener The listener
* @param filter The filter
* @param handback The handback
*/
public NotificationDetails(NotificationListener listener,
NotificationFilter filter, Object handback) {
_listener = listener;
_filter = filter;
_handback = handback;
}
/**
* The listener.
*
* @return The listener
*/
public NotificationListener getListener() {
return (_listener);
}
/**
* The filter.
*
* @return The filter
*/
public NotificationFilter getFilter() {
return (_filter);
}
/**
* The handback.
*
* @return The handback
*/
public Object getHandback() {
return (_handback);
}
}
}