Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
rs.data.file.storage.XmlStorageStrategy Maven / Gradle / Ivy
/**
*
*/
package rs.data.file.storage;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.SubnodeConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
import rs.baselib.bean.IBean;
import rs.data.api.IDaoFactory;
import rs.data.api.bo.IGeneralBO;
/**
* Storage strategy for XML files.
* @param type of ID for Business Objects to be managed
* @param type of Business Object the strategy manages
* @author ralph
*
*/
public class XmlStorageStrategy> extends AbstractStorageStrategy {
/**
* Constructor.
*/
public XmlStorageStrategy(IDaoFactory daoFactory) {
super(daoFactory);
}
/**
* {@inheritDoc}
*/
@Override
public void load(T bo, K id, File specifier) throws IOException {
// Find all relevant property names
Collection propertyNames = new ArrayList(getPropertyNames(bo));
propertyNames.add("id");
try {
XMLConfiguration cfg = new XMLConfiguration();
cfg.setListDelimiter((char)0);
cfg.load(specifier);
for (String name : propertyNames) {
try {
SubnodeConfiguration subConfig = cfg.configurationAt(name+"(0)");
bo.set(name, loadValue(subConfig));
} catch (IllegalArgumentException e) {
bo.set(name, null);
}
}
} catch (Exception e) {
throw new IOException("Cannot load XML file", e);
}
}
/**
* Internal helper to load a sub configuration.
* Descendants shall not override this but several specific helper methods.
* @param cfg the tag to be loaded
* @return th eobject represented by this tag
* @see #loadBusinessObject(Class, HierarchicalConfiguration)
* @see #loadCollection(Class, HierarchicalConfiguration)
* @see #loadMap(Class, HierarchicalConfiguration)
* @see #loadBean(Class, HierarchicalConfiguration)
* @see #loadSerialized(Class, HierarchicalConfiguration)
*/
protected Object loadValue(HierarchicalConfiguration cfg) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
String className = cfg.getString("[@class]");
if ((className != null) && !className.isEmpty()) {
Class> clazz = Class.forName(className);
Object rc = null;
if (IGeneralBO.class.isAssignableFrom(clazz)) {
rc = loadBusinessObject(clazz, cfg);
} else if (Collection.class.isAssignableFrom(clazz)) {
rc = loadCollection(clazz, cfg);
} else if (Map.class.isAssignableFrom(clazz)) {
rc = loadMap(clazz, cfg);
} else if (IBean.class.isAssignableFrom(clazz)) {
rc = loadBean(clazz, cfg);
} else {
rc = loadSerialized(clazz, cfg);
if (rc == null) {
throw new RuntimeException("Cannot unserialize property: "+className+": "+cfg.getString(""));
}
}
return rc;
} else {
return null;
}
}
/**
* Loads a {@link IGeneralBO business object} from the XML tag.
* @param clazz class to be loaded
* @param cfg configuration of class
* @return the loaded object
*/
@SuppressWarnings("unchecked")
protected IGeneralBO> loadBusinessObject(Class> clazz, HierarchicalConfiguration cfg) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Serializable id = (Serializable)loadValue(cfg.configurationAt("refid(0)"));
IDaoFactory factory = getDaoFactory();
if (factory != null) {
return factory.getDaoFor((Class extends IGeneralBO extends Serializable>>)clazz).findById(id);
}
return null;
}
/**
* Loads a collection from the XML tag.
* @param clazz class to be loaded
* @param cfg configuration of class
* @return the loaded collection
*/
@SuppressWarnings("unchecked")
protected Collection> loadCollection(Class> clazz, HierarchicalConfiguration cfg) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Collection collection = (Collection)clazz.newInstance();
for (HierarchicalConfiguration subConfig : cfg.configurationsAt("item")) {
collection.add(loadValue(subConfig));
}
return collection;
}
/**
* Loads a map from the XML tag.
* @param clazz class to be loaded
* @param cfg configuration of class
* @return the loaded map
*/
protected Map,?> loadMap(Class> clazz, HierarchicalConfiguration cfg) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Map map = new HashMap();
for (HierarchicalConfiguration subConfig : cfg.configurationsAt("item")) {
Object key = loadValue(subConfig.configurationAt("key(0)"));
Object value = loadValue(subConfig.configurationAt("value(0)"));
map.put(key, value);
}
return map;
}
/**
* Loads a {@link IBean} from the XML tag.
* @param clazz class to be loaded
* @param cfg configuration of class
* @return the loaded bean
*/
protected IBean loadBean(Class> clazz, HierarchicalConfiguration cfg) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
IBean bean = (IBean)clazz.newInstance();
for (String name : getBeanPropertyNames(clazz)) {
bean.set(name, loadValue(cfg.configurationAt(name+"(0)")));
}
return bean;
}
/**
* Loads a {@link Serializable} from the XML tag.
* @param clazz class to be loaded
* @param cfg configuration of class
* @return the loaded object
*/
protected Object loadSerialized(Class> clazz, HierarchicalConfiguration cfg) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
String valueString = cfg.getString(""); // ?
return unserialize(clazz.getName(), valueString);
}
/**
* {@inheritDoc}
*/
@Override
public void save(T bo, File specifier) throws IOException {
// Find all relevant property names
Collection propertyNames = new ArrayList(getPropertyNames(bo));
propertyNames.add("id");
FileWriter out = null;
try {
out = new FileWriter(specifier);
out.write("\n");
out.write("\n");
for (String name : propertyNames) {
Object value = PropertyUtils.getProperty(bo, name);
writeValue(out, 1, value, name);
}
out.write(" ");
} catch (Exception e) {
throw new IOException("Cannot load XML file", e);
} finally {
if (out != null) {
out.flush();
out.close();
}
}
}
/**
* Internal helper to write a value to the XML stream.
* @param out the stream
* @param indent the indentation to be used
* @param value the value to be written
* @param tagName the tag name to be used
*/
protected void writeValue(Writer out, int indent, Object value, String tagName) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
String indentS = "";
for (int i=0; i");
if (value instanceof IGeneralBO) {
out.write("\n");
writeValue(out, indent+1, ((IGeneralBO>) value).getId(), "refid");
out.write(indentS);
} else if (value instanceof Collection) {
out.write("\n");
// We need to split this up
for (Object o : (Collection>)value) {
writeValue(out, indent+1, o, "item");
}
out.write(indentS);
} else if (value instanceof Map) {
out.write("\n");
// We need to split this up
for (Map.Entry,?> entry : ((Map,?>)value).entrySet()) {
out.write(indentS+" - \n");
writeValue(out, indent+2, entry.getKey(), "key");
writeValue(out, indent+2, entry.getValue(), "value");
out.write(indentS+"
\n");
}
out.write(indentS);
} else if (value instanceof IBean) {
out.write("\n");
for (String name : getBeanPropertyNames(value)) {
Object v = PropertyUtils.getProperty(value, name);
writeValue(out, indent+1, v, name);
}
out.write(indentS);
} else {
String s = serialize(value);
if (s != null) {
if (isXmlCompatible(s)) {
out.write(s);
} else {
out.write("");
}
} else {
out.write("");
}
}
out.write(""+tagName+">\n");
} else {
out.write(indentS+"<"+tagName+"/>\n");
}
}
/**
* Returns whether the string is XML compatible.
* @param s string to be evaluated
* @return true") < 0) && (s.indexOf("<") < 0);
}
/**
* {@inheritDoc}
*/
@Override
public void refresh(T bo, File specifier) throws IOException {
load(bo, bo.getId(), specifier);
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public Map getList(Collection specifiers) throws IOException {
Map rc = new HashMap();
// Read the ID of each file
for (File f : specifiers) {
try {
XMLConfiguration cfg = new XMLConfiguration();
cfg.setListDelimiter((char)0);
cfg.load(f);
try {
SubnodeConfiguration subConfig = cfg.configurationAt("id(0)");
K id = (K)loadValue(subConfig);
rc.put(id, f);
} catch (IllegalArgumentException e) {
// Ignore
}
} catch (Exception e) {
throw new IOException("Cannot load XML file", e);
}
}
return rc;
}
}