org.jboss.mx.interceptor.PersistenceInterceptor Maven / Gradle / Ivy
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.mx.interceptor;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import javax.management.Descriptor;
import javax.management.PersistentMBean;
import javax.management.MBeanException;
import javax.management.InstanceNotFoundException;
import javax.management.modelmbean.ModelMBeanInfo;
import org.jboss.mx.modelmbean.ModelMBeanConstants;
import org.jboss.mx.service.ServiceConstants;
import org.jboss.mx.server.Invocation;
import org.jboss.mx.server.MBeanInvoker;
/** A peristence interceptor that uses the java.util.Timer framework for the
* scheculed peristence policies.
*
* @see javax.management.PersistentMBean
*
* @author Juha Lindfors.
* @author [email protected]
* @author Dimitris Andreadis.
*
* @version $Revision: 37459 $
*/
public class PersistenceInterceptor
extends AbstractInterceptor
implements ModelMBeanConstants, ServiceConstants
{
/** The HashMap of attribute level policies */
private HashMap attrPersistencePolicies = new HashMap();
/** The HashMap of scheduled peristence */
private HashMap timerTaskMap = new HashMap();
/** The bean level peristence policy */
private String mbeanPersistencePolicy;
/** The PersistentMBean load/store callback interface */
private PersistentMBean callback;
public PersistenceInterceptor()
{
super("Default Persistence Interceptor");
}
// Public --------------------------------------------------------
public Object invoke(Invocation invocation) throws Throwable
{
if( callback == null )
{
lazyInit(invocation);
}
Object returnValue = invocation.nextInterceptor().invoke(invocation);
String type = invocation.getType();
if (type != Invocation.OP_SETATTRIBUTE )
return returnValue;
String attrName = invocation.getName();
String policy = (String)attrPersistencePolicies.get(attrName);
if (policy == null)
policy = mbeanPersistencePolicy;
if (policy.equalsIgnoreCase(PP_ON_UPDATE) == true)
{
MBeanInvoker invoker = invocation.getInvoker();
Descriptor attrDesc = invocation.getDescriptor();
invoker.updateAttributeInfo(attrDesc);
callback.store();
}
else if(policy.equalsIgnoreCase(PP_NO_MORE_OFTEN_THAN) == true)
{
PersistenceTimerTask task = (PersistenceTimerTask) timerTaskMap.get(attrName);
if( task != null )
task.setHasUpdated(true);
}
return returnValue;
}
/**
*
* @param invocation
*/
private synchronized void lazyInit(Invocation invocation) throws MBeanException
{
// This requires the invoker to implement PersistentMBean
MBeanInvoker invoker = invocation.getInvoker();
callback = (PersistentMBean) invocation.getInvoker();
ModelMBeanInfo info = (ModelMBeanInfo) invoker.getMetaData();
Descriptor mbeanDesc = info.getMBeanDescriptor();
String policy = (String) mbeanDesc.getFieldValue(PERSIST_POLICY);
String persistPeriod = (String)mbeanDesc.getFieldValue(PERSIST_PERIOD);
mbeanPersistencePolicy = PP_NEVER;
if (policy != null)
{
mbeanPersistencePolicy = policy;
if (mbeanPersistencePolicy.equalsIgnoreCase(PP_ON_TIMER) ||
mbeanPersistencePolicy.equalsIgnoreCase(PP_NO_MORE_OFTEN_THAN))
{
boolean isNoMoreOftenThan = mbeanPersistencePolicy.equalsIgnoreCase(PP_NO_MORE_OFTEN_THAN);
schedulePersistenceNotifications(Long.parseLong(persistPeriod), MBEAN_DESCRIPTOR, isNoMoreOftenThan);
}
}
Descriptor[] attrDescs = info.getDescriptors(ATTRIBUTE_DESCRIPTOR);
for (int i = 0; i < attrDescs.length; ++i)
{
policy = (String) attrDescs[i].getFieldValue(PERSIST_POLICY);
persistPeriod = (String)attrDescs[i].getFieldValue(PERSIST_PERIOD);
if (policy != null)
{
String name = (String) attrDescs[i].getFieldValue(NAME);
attrPersistencePolicies.put(name, policy);
if(policy.equalsIgnoreCase(PP_ON_TIMER) ||
policy.equalsIgnoreCase(PP_NO_MORE_OFTEN_THAN))
{
boolean isNoMoreOftenThan = policy.equalsIgnoreCase(PP_NO_MORE_OFTEN_THAN);
schedulePersistenceNotifications(Long.parseLong(persistPeriod), name, isNoMoreOftenThan);
}
}
}
}
private void schedulePersistenceNotifications(long persistPeriod, String name,
boolean isNoMoreOftenThan)
{
// @todo: unschedule on unregistration/descriptor field change
PersistenceTimerTask task = new PersistenceTimerTask(name, isNoMoreOftenThan);
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(task, 0, persistPeriod);
timerTaskMap.put(name, task);
}
// Inner classes -------------------------------------------------
private class PersistenceTimerTask extends TimerTask
{
boolean noMoreOftenThan;
boolean hasUpdated;
String name;
PersistenceTimerTask(String name, boolean noMoreOftenThan)
{
this.name = name;
this.noMoreOftenThan = noMoreOftenThan;
}
synchronized void setHasUpdated(boolean flag)
{
hasUpdated = flag;
}
public void run()
{
try
{
// @todo: add PersistenceContext field to MBean's descriptor to
// relay attribute name (and possibly other) info with the
// persistence callback
boolean doStore = (noMoreOftenThan == true && hasUpdated == true)
|| noMoreOftenThan == false;
if( doStore == true )
{
callback.store();
setHasUpdated(false);
}
}
catch (MBeanException e)
{
// FIXME: log exception
}
catch (InstanceNotFoundException e)
{
// FIXME: log exception
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy