package org.jboss.mx.persistence;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.management.Attribute;
import javax.management.AttributeList;
import javax.management.Descriptor;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import org.apache.log4j.Logger;
import org.jboss.mx.modelmbean.ModelMBeanConstants;
import org.jboss.mx.modelmbean.ModelMBeanInvoker;
import org.jboss.mx.persistence.PersistenceManager;
/**
* Object Stream Persistence Manager. <p>
*
* Persists the MBean to the file system using an Object Stream.
* Includes code based on examples in Juha's JMX Book. <p>
*
* Object Streams written to disk are admittedly lacking in the area of "long-term", "portable",
* or "human-readable" persistence. They are fairly straightforward, however.
* Primarily, this class is useful for demonstration and "quick & dirty" persistence.
*
* @todo currently metadata as well as data is stored. only data needs to be stored.
* @author Matt Munz
*/
public class ObjectStreamPersistenceManager
extends MBeanInfoOdb
implements PersistenceManager
{
protected boolean fIsLoading;
// Constructors --------------------------------------------------
public ObjectStreamPersistenceManager()
{
super();
}
// Public --------------------------------------------------------
/**
* deserializes state from the object input stream
*
* @param mbean
* @param metadata
* @exception MBeanException
*/
public void load(ModelMBeanInvoker mbean, MBeanInfo metadata) throws MBeanException
{
logger().debug("FilePersist.load; metadata: " + metadata);
// based on jmx book
if (metadata == null)
{
return;
}
Descriptor d = ((ModelMBeanInfo)metadata).getMBeanDescriptor();
String dir = (String)d.getFieldValue(ModelMBeanConstants.PERSIST_LOCATION);
String file = (String)d.getFieldValue(ModelMBeanConstants.PERSIST_NAME);
if (file == null)
{
return;
}
try
{
File f = new File(dir, file);
metadata = (ModelMBeanInfoSupport) load(f);
logger().info("metadata deserialized");
loadFromMetadata(mbean, (ModelMBeanInfo)metadata);
}
catch (Exception e)
{
logger().error("Error loading MBean state", e);
}
// end from book
}
/**
* What we need to get here is 1) the persist location, and 2) the entire contents of the mbean
* #2 contains the entire contents (state) of the model object, as well as the meta data
* that the mbean provides.
* As such, serializing this (MBeanInfo) object (brute force) in effect serializes the model as well.
*
* @param metadata
* @exception MBeanException
*/
public void store(MBeanInfo metadata) throws MBeanException
{
System.out.println("FilePersist.store; metadata: " + metadata);
if (isLoading())
{
logger().info("store(): loading metadata. cannot store.");
return;
}
// based on jmx book
try
{
Descriptor d = ((ModelMBeanInfo)metadata).getMBeanDescriptor();
String dirPath = (String)d.getFieldValue(ModelMBeanConstants.PERSIST_LOCATION);
String file = (String)d.getFieldValue(ModelMBeanConstants.PERSIST_NAME);
File dir = new File(dirPath);
dir.mkdirs();
File f = new File(dir, file);
store(metadata, f);
}
catch (IOException e)
{
throw new MBeanException(e, "Error in persisting MBean.");
}
// end from book
}
// Protected -----------------------------------------------------
/**
* @param mbean
* @param metadata
* @todo I think there is a bug here where the attribute access value is not being restored.
*/
protected void loadFromMetadata(ModelMBeanInvoker mbean, ModelMBeanInfo metadata)
{
AttributeList attributes = new AttributeList();
// iterate over all attributes in metadata
MBeanAttributeInfo[] attrs = metadata.getAttributes();
for (int i = 0; i < attrs.length; i++)
{
/// for each attribute, create a new Attribute object and add it to the collection
ModelMBeanAttributeInfo attributeInfo = (ModelMBeanAttributeInfo)attrs[i];
Descriptor attrDesc = attributeInfo.getDescriptor();
Object name = attrDesc.getFieldValue(ModelMBeanConstants.NAME);
Object value = attrDesc.getFieldValue(ModelMBeanConstants.VALUE);
logger().debug("creating attribute. name: " + name + ", value: " + value);
Attribute curAttribute = new Attribute(name.toString(), value);
attributes.add(curAttribute);
}
setIsLoading(true);
mbean.setAttributes(attributes);
setIsLoading(false);
}
// accessors
protected boolean isLoading()
{
return fIsLoading;
}
protected void setIsLoading(boolean newIsLoading)
{
fIsLoading = newIsLoading;
}
}