package org.jboss.mx.persistence;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import org.jboss.logging.Logger;
import org.jboss.mx.modelmbean.ModelMBeanConstants;
import org.jboss.mx.modelmbean.ModelMBeanInvoker;
public class DelegatingPersistenceManager
implements PersistenceManager
{
private static Logger log = Logger.getLogger(DelegatingPersistenceManager.class);
private AttributePersistenceManager persistor;
private String persistName;
private boolean isLoading;
public DelegatingPersistenceManager()
{
}
public void load(ModelMBeanInvoker invoker, MBeanInfo metadata)
throws MBeanException
{
if (this.persistor == null) {
init(invoker, metadata);
}
if (log.isDebugEnabled())
log.debug("load() called for: '" + this.persistName + "'");
AttributeList attrs = null;
try {
attrs = this.persistor.load(this.persistName);
}
catch (Exception e) {
log.warn("Caught exception while loading", e);
throw new MBeanException(e);
}
if (attrs != null) {
try {
setIsLoading(true);
if (log.isDebugEnabled())
log.debug("loading attributes: " + attrs);
invoker.setAttributes(attrs);
}
finally {
setIsLoading(false);
}
}
else {
if (log.isDebugEnabled())
log.debug("No attributes to load");
}
}
public void store(MBeanInfo metadata)
throws MBeanException
{
if (this.persistor == null) {
throw new MBeanException(new Exception("store() called before instance initialized"));
}
if (isLoading()) {
return; }
else {
if (log.isDebugEnabled())
log.debug("store() called for: '" + this.persistName + "'");
AttributeList attributes = new AttributeList();
MBeanAttributeInfo[] attrs = metadata.getAttributes();
if (log.isDebugEnabled() && attrs.length > 0)
log.debug("store() --- ModelMBeanAttributeInfo[] ---");
for (int i = 0; i < attrs.length; i++)
{
ModelMBeanAttributeInfo attributeInfo = (ModelMBeanAttributeInfo)attrs[i];
if (log.isDebugEnabled())
log.debug(" attr (#" + i + ") - " + attributeInfo);
if (attributeInfo.isWritable()) {
Descriptor attrDesc = attributeInfo.getDescriptor();
Object name = attrDesc.getFieldValue(ModelMBeanConstants.NAME);
Object value = attrDesc.getFieldValue(ModelMBeanConstants.ATTRIBUTE_VALUE);
Object updated = attrDesc.getFieldValue(ModelMBeanConstants.LAST_UPDATED_TIME_STAMP2);
Object pPolicy = attrDesc.getFieldValue(ModelMBeanConstants.PERSIST_POLICY);
boolean noPersistPolicy =
pPolicy != null &&
((String)pPolicy).equalsIgnoreCase(ModelMBeanConstants.PP_NEVER) ? true : false;
if (updated != null && noPersistPolicy == false) {
attributes.add(new Attribute(name.toString(), value));
}
}
}
try {
if (!attributes.isEmpty()) {
if (log.isDebugEnabled())
log.debug("calling persistor.store(" + this.persistName + ") attrs=" + attributes);
persistor.store(this.persistName, attributes);
}
else {
if (log.isDebugEnabled())
log.debug("nothing to persist");
}
}
catch (Exception e) {
log.warn("cought exception during store()", e);
}
}
}
protected void init(ModelMBeanInvoker invoker, MBeanInfo metadata)
throws MBeanException
{
Descriptor desc = ((ModelMBeanInfo)metadata).getMBeanDescriptor();
if (log.isDebugEnabled()) {
log.debug("init() --- ModelMBeanInfo Descriptor --- ");
log.debug(desc);
}
String name = (String)desc.getFieldValue(ModelMBeanConstants.PERSIST_NAME);
if (name != null) {
this.persistName = name;
}
else {
ObjectName objectName = (ObjectName)desc.getFieldValue(ModelMBeanConstants.OBJECT_NAME);
if (objectName != null) {
this.persistName = objectName.toString();
}
else {
throw new MBeanException(new Exception("must specify a value for: " + ModelMBeanConstants.PERSIST_NAME));
}
}
if (log.isDebugEnabled())
log.debug("chosen persistent id: '" + this.persistName + "'");
String service = (String)desc.getFieldValue(ModelMBeanConstants.DELEGATING_PM_SERVICE_DESCRIPTOR);
if (service == null)
{
service = ModelMBeanConstants.DELEGATING_PM_SERVICE_DEFAULT_VALUE;
}
String operation = (String)desc.getFieldValue(ModelMBeanConstants.DELEGATING_PM_OPERATION_DESCRIPTOR);
if (operation == null)
{
operation = ModelMBeanConstants.DELEGATING_PM_OPERATION_DEFAULT_VALUE;
}
try {
ObjectName objName = new ObjectName(service);
MBeanServer server = invoker.getServer();
this.persistor = (AttributePersistenceManager)server.invoke(objName,
operation,
new Object[] {},
new String[] {});
if (this.persistor == null) {
throw new MBeanException(new NullPointerException("null AttributePersistenceManager from: " + service));
}
}
catch (MalformedObjectNameException e) {
throw new MBeanException(e, "not a valid ObjectName: " + service);
}
catch (InstanceNotFoundException e) {
throw new MBeanException(e, "service not registered: " + service);
}
catch (ReflectionException e) {
throw new MBeanException(e);
}
if (log.isDebugEnabled())
log.debug("using AttributePersistenceManager: " + this.persistor.getClass().getName());
}
protected boolean isLoading()
{
return isLoading;
}
protected void setIsLoading(boolean newIsLoading)
{
isLoading = newIsLoading;
}
}