/* * Copyright(c) 2005 Center for E-Commerce Infrastructure Development, The * University of Hong Kong (HKU). All Rights Reserved. * * This software is licensed under the GNU GENERAL PUBLIC LICENSE Version 2.0 [1] * * [1] http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt */ package hk.hku.cecid.corvus.ws.data; import java.util.Map; import java.util.HashMap; import java.math.BigInteger; import java.io.File; import java.io.IOException; import java.net.URL; import hk.hku.cecid.piazza.commons.util.PropertyTree; import hk.hku.cecid.piazza.commons.util.DateUtil; import hk.hku.cecid.piazza.commons.util.UtilitiesException; import hk.hku.cecid.piazza.commons.module.ComponentException; /** * A <code>DataFactory</code> imports data from the XML property tree to create different data object used for * sending web service request. * <br/><br/> * * Creation Date: 19/3/2007 * * @author Twinsen Tsang * @version 1.0.0 * @since Dwarf 10315 * * @see hk.hku.cecid.piazza.commons.util.PropertyTree */ // TODO: Re-factor required after the enhancement of data convertor. public class DataFactory { /** The constants representing the XML Separator **/ public static final char XML_SEPARATOR = '/'; /** Singleton. */ public static final DataFactory instance = new DataFactory(); /* * A set of data convertor for converting object to string. */ private Map dataConvertors = new HashMap(); /** * Private constructor. Create an instance of <code>DataFactory</code>. */ private DataFactory() { this.dataConvertors.put(String.class, new NoOpDataConvertor()); this.dataConvertors.put(byte[].class, new ByteArrayDataConvertor()); } /** * Singleton instance. */ public static DataFactory getInstance(){ return DataFactory.instance; } public PermitRedownloadData createAS2PermitRedownloadDataFromXML(PropertyTree t){ return this.createPermitRedownloadDataFromXML(t, PermitRedownloadData.PROTOCOL_AS2); } public PermitRedownloadData createEBMSPermitRedownloadDataFromXML(PropertyTree t){ return this.createPermitRedownloadDataFromXML(t, PermitRedownloadData.PROTOCOL_EBMS); } private PermitRedownloadData createPermitRedownloadDataFromXML(PropertyTree t, String protocol){ if (t == null) throw new NullPointerException("The property tree is missing."); PermitRedownloadData data = new PermitRedownloadData(protocol); if(protocol.equalsIgnoreCase(PermitRedownloadData.PROTOCOL_AS2)){ final String[] prefix = { PermitRedownloadData.AS2_CONFIG_PREFIX, PermitRedownloadData.AS2_PARAM_PREFIX}; final String[][] keySet = { PermitRedownloadData.CONFIG_KEY_SET,PermitRedownloadData.PARAM_KEY_SET }; this.loadKVPairDataFromXML(data, t, prefix, keySet); } if(protocol.equalsIgnoreCase(PermitRedownloadData.PROTOCOL_EBMS)){ final String[] prefix = { PermitRedownloadData.EBMS_CONFIG_PREFIX, PermitRedownloadData.EBMS_PARAM_PREFIX}; final String[][] keySet = { PermitRedownloadData.CONFIG_KEY_SET,PermitRedownloadData.PARAM_KEY_SET }; this.loadKVPairDataFromXML(data, t, prefix, keySet); } return data; } /** * Create an instance of <code>AS2MessageData</code> from the XML property tree. * * @param t The property tree to import the data. * @return A new instance of <code>AS2MessageData</code> with data imported from the property tree. */ public AS2MessageData createAS2MessageDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. AS2MessageData ret = new AS2MessageData(); // All key prefix. final String[] prefix = { AS2MessageData.CONFIG_PREFIX, AS2MessageData.PARAM_PREFIX}; // All key set final String[][] keySet = { AS2MessageData.CONFIG_KEY_SET,AS2MessageData.PARAM_KEY_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Store an instance of <code>AS2Message<code> to XML. * * @param d The <code>AS2MessageData<code> to store. * @param path The URL specified the location for storing the data. * * @throws IOException when storing the data fails. */ public void storeAS2MessageDataToXML(AS2MessageData d, URL path) throws IOException { PropertyTree marshalTree = new PropertyTree(); // All key prefix. final String[] prefix = { AS2MessageData.CONFIG_PREFIX, AS2MessageData.PARAM_PREFIX}; // All key set final String[][] keySet = { AS2MessageData.CONFIG_KEY_SET,AS2MessageData.PARAM_KEY_SET }; // Store all key-value pair to XML. this.storeKVPairDataToXML(d, marshalTree, path, prefix, keySet, null); } /** * Create an instance of <code>EBMSMessageData</code> from the XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>EBMSMessageData</code> * with data imported from the property tree. */ public EBMSMessageData createEBMSMessageDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. EBMSMessageData ret = new EBMSMessageData(); // All key prefix. final String[] prefix = { EBMSMessageData.CONFIG_PREFIX, EBMSMessageData.PARAM_PREFIX}; // All key set final String[][] keySet = { EBMSMessageData.CONFIG_KEY_SET,EBMSMessageData.PARAM_KEY_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Store an instance of <code>EBMSMessage<code> to XML. * * @param d The <code>AS2MessageData<code> to store. * @param path The URL specified the location for storing the data. * * @throws IOException when storing the data fails. */ public void storeEBMSMessageDataToXML(EBMSMessageData d, URL path) throws IOException { PropertyTree marshalTree = new PropertyTree(); // All key prefix. final String[] prefix = { EBMSMessageData.CONFIG_PREFIX, EBMSMessageData.PARAM_PREFIX}; // All key set final String[][] keySet = { EBMSMessageData.CONFIG_KEY_SET,EBMSMessageData.PARAM_KEY_SET}; // Store all key-value pair to XML. this.storeKVPairDataToXML(d, marshalTree, path, prefix, keySet, null); } /** * Create an instance of <code>AS2ConfigData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>AS2ConfigData</code> * with data imported from the property tree. */ public AS2ConfigData createAS2ConfigDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. AS2ConfigData ret = new AS2ConfigData(); // All key prefix. final String[] prefix = { AS2ConfigData.CONFIG_PREFIX, AS2ConfigData.PARAM_PREFIX }; // All key set final String[][] keySet = { AS2ConfigData.CONFIG_KEY_SET, AS2ConfigData.PARAM_KEY_SET}; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Create an instance of <code>EBMSConfigData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>EBMSConfigData</code> * with data imported from the property tree. */ public EBMSConfigData createEBMSConfigDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. EBMSConfigData ret = new EBMSConfigData(); // All key prefix. final String[] prefix = { EBMSConfigData.CONFIG_PREFIX, EBMSConfigData.PARAM_PREFIX }; // All key set final String[][] keySet = { EBMSConfigData.CONFIG_KEY_SET, EBMSConfigData.PARAM_KEY_SET}; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Create an instance of <code>AS2PartnershipData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>AS2PartnershipData</code> * with data imported from the property tree. */ public AS2PartnershipData createAS2PartnershipFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. AS2PartnershipData ret = new AS2PartnershipData(); // All key prefix. final String[] prefix = { AS2PartnershipData.PARAM_PREFIX}; // All key set final String[][] keySet = { AS2PartnershipData.PARAM_KEY_SET }; // All key value type set final Class [][] typeSet = { AS2PartnershipData.PARAM_CLASS_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet, typeSet); return ret; } /** * Store the instance of <code>AS2PartnershipData</code> to the XML * specified at <code>path<code>. * * @param d The <code>AS2PartnershipData</code> you want to store. * @param path The URL specified the location for storing the data. * * @throws IOException when storing the data fails. */ public void storeAS2PartnershipFromXML(AS2PartnershipData d, URL path) throws IOException { PropertyTree marshalTree = new PropertyTree(); // All key prefix. final String[] prefix = { AS2PartnershipData.PARAM_PREFIX }; // All key set final String[][] keySet = { AS2PartnershipData.PARAM_KEY_SET }; // All key value type set final Class [][] typeSet = { AS2PartnershipData.PARAM_CLASS_SET }; // Store all key-value pair to XML. this.storeKVPairDataToXML(d, marshalTree, path, prefix, keySet, typeSet); } /** * * Create an instance of <code>EBMSPartnershipData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>EBMSPartnershipData</code> * with data imported from the property tree. */ public EBMSPartnershipData createEBMSPartnershipFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. EBMSPartnershipData ret = new EBMSPartnershipData(); // All key prefix. final String[] prefix = { EBMSPartnershipData.PARAM_PREFIX}; // All key set final String[][] keySet = { EBMSPartnershipData.PARAM_KEY_SET }; // All key value type set final Class [][] typeSet = { EBMSPartnershipData.PARAM_CLASS_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet, typeSet); return ret; } /** * Store the instance of <code>EBMSPartnershipData</code> to the XML * specified at <code>path<code>. * * @param d The <code>EBMSPartnershipData</code> you want to store. * @param path The URL specified the location for storing the data. * * @throws IOException when storing the data fails. */ public void storeEBMSPartnershipFromXML(EBMSPartnershipData d, URL path) throws IOException { PropertyTree marshalTree = new PropertyTree(); // All key prefix. final String[] prefix = { EBMSPartnershipData.PARAM_PREFIX}; // All key set final String[][] keySet = { EBMSPartnershipData.PARAM_KEY_SET }; // All key value type set final Class [][] typeSet = { EBMSPartnershipData.PARAM_CLASS_SET }; // Store all key-value pair to XML. this.storeKVPairDataToXML(d, marshalTree, path, prefix, keySet, typeSet); } /** * Create an instance of <code>AS2StatusQueryData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>AS2StatusQueryData</code> * with data imported from the property tree. */ public AS2StatusQueryData createAS2StatusQueryDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. AS2StatusQueryData ret = new AS2StatusQueryData(); // All key prefix final String[] prefix = { AS2StatusQueryData.PARAM_PREFIX, AS2StatusQueryData.CONFIG_PREFIX }; // All key set final String[][] keySet = { AS2StatusQueryData.PARAM_KEY_SET, AS2StatusQueryData.CONFIG_KEY_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Create an instance of <code>EBMSStatusQueryData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>EBMSStatusQueryData</code> * with data imported from the property tree. */ public EBMSStatusQueryData createEBMSStatusQueryDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. EBMSStatusQueryData ret = new EBMSStatusQueryData(); // All key prefix final String[] prefix = { EBMSStatusQueryData.PARAM_PREFIX, EBMSStatusQueryData.CONFIG_PREFIX }; // All key set final String[][] keySet = { EBMSStatusQueryData.PARAM_KEY_SET, EBMSStatusQueryData.CONFIG_KEY_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Create an instance of <code>AS2AdminData</code> from the XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>AS2AdminData</code> with data imported from the property tree. */ public AS2AdminData createAS2AdminDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. AS2AdminData ret = new AS2AdminData(); // All key prefix final String[] prefix = { AS2AdminData.PARAM_PREFIX, AS2AdminData.CONFIG_PREFIX }; // All key set final String[][] keySet = { AS2AdminData.PARAM_KEY_SET, AS2AdminData.CONFIG_KEY_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Create an instance of <code>EBMSAdminData</code> from the XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>EBMSAdminData</code> with data imported from the property tree. */ public EBMSAdminData createEBMSAdminDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. EBMSAdminData ret = new EBMSAdminData(); // All key prefix final String[] prefix = { EBMSAdminData.PARAM_PREFIX, EBMSAdminData.CONFIG_PREFIX }; // All key set final String[][] keySet = { EBMSAdminData.PARAM_KEY_SET, EBMSAdminData.CONFIG_KEY_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Create an instance of <code>SFRMStatusQueryData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>SFRMStatusQueryData</code> with data imported from the property tree. */ public SFRMStatusQueryData createSFRMStatusQueryDataFromXML(PropertyTree t) { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. SFRMStatusQueryData ret = new SFRMStatusQueryData(); // All key prefix final String[] prefix = { SFRMStatusQueryData.PARAM_PREFIX, SFRMStatusQueryData.CONFIG_PREFIX }; // All key set final String[][] keySet = { SFRMStatusQueryData.PARAM_KEY_SET, SFRMStatusQueryData.CONFIG_KEY_SET }; // Load all key-value pair from XML. this.loadKVPairDataFromXML(ret, t, prefix, keySet); return ret; } /** * Create an instance of <code>EBMSMessageHistoryRequestData</code> from the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>EBMSMessageHistoryRequestData</code> with data imported from the property tree. */ public EBMSMessageHistoryRequestData createEbmsMessageHistoryQueryDataFromXML(PropertyTree t){ if(t == null) throw new NullPointerException("The property tree is missing."); EBMSMessageHistoryRequestData data = new EBMSMessageHistoryRequestData(); final String[] config_prefix = { EBMSMessageHistoryRequestData.CONFIG_PREFIX}; final String[][] config_keySet = { EBMSMessageHistoryRequestData.CONFIG_KEY_SET}; this.loadKVPairDataFromXML(data, t, config_prefix, config_keySet); final String[] prefix = {EBMSMessageHistoryRequestData.CRITERIA_PARAM_PREFIX, EBMSMessageHistoryRequestData.CRITERIA_PARAM_PREFIX}; final String[][] keySet = { EBMSMessageHistoryRequestData.PARAM_KEY_SET, EBMSMessageHistoryRequestData.PARAM_EBMS_KEY_SET}; this.loadKVPairDataFromXML(data, t, prefix, keySet); return data; } /** * Create an instance of <code>AS2MessageHistoryRequestData</code> from the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>AS2MessageHistoryRequestData</code> with data imported from the property tree. */ public AS2MessageHistoryRequestData createAs2MessageHistoryQueryDataFromXML(PropertyTree t){ if(t == null) throw new NullPointerException("The property tree is missing."); AS2MessageHistoryRequestData data = new AS2MessageHistoryRequestData(); final String[] config_prefix = { AS2MessageHistoryRequestData.CONFIG_PREFIX}; final String[][] config_keySet = { AS2MessageHistoryRequestData.CONFIG_KEY_SET}; this.loadKVPairDataFromXML(data, t, config_prefix, config_keySet); final String[] prefix = {AS2MessageHistoryRequestData.PARAM_PREFIX, AS2MessageHistoryRequestData.PARAM_PREFIX}; final String[][] keySet = { AS2MessageHistoryRequestData.PARAM_KEY_SET, AS2MessageHistoryRequestData.PARAM_AS2_KEY_SET}; this.loadKVPairDataFromXML(data, t, prefix, keySet); return data; } /** * Create an instance of <code>MessageStatusRequestData</code> From a * file written in XML format. * * @param filename The file to load the message status request data. * @return * A new instance of <code>MessageStatusRequestData</code> * with data imported from the file with name <code>filename</code> * @throws ComponentException * When unable to load the file or invalid file format. */ public static MessageStatusRequestData createMessageStatusDataFromXML(String filename) throws ComponentException { if (filename == null) throw new NullPointerException("The filename is missing."); try{ PropertyTree t = new PropertyTree(new File(filename).toURI().toURL()); return createMessageRequestStatusDataFromXML(t); }catch(Exception e){ throw new ComponentException("Unable to create property tree", e); } } /** * Create an instance of <code>MessageStatusRequestData</code> From the * XML property tree. * * @param t The property tree to import the data. * @return * A new instance of <code>MessageStatusRequestData</code> * with data imported from the property tree. * @throws UtilitiesException * When the data factory is unable to import the data from the property * tree. */ public static MessageStatusRequestData createMessageRequestStatusDataFromXML(PropertyTree t) throws UtilitiesException { if (t == null) throw new NullPointerException("The property tree is missing."); // Create return object. MessageStatusRequestData ret = new MessageStatusRequestData(); // variable decl int len = MessageStatusRequestData.PARAM_KEY_SET.length; String [] valueSet = new String[len]; // Extract the key param set. for (int i = 0; i < len; i++){ valueSet[i] = t.getProperty( MessageStatusRequestData.PARAM_PREFIX + "/" + MessageStatusRequestData.PARAM_KEY_SET[i]); } // Filling all string-typed param. ret.setPartnershipId (valueSet[0]); ret.setChannelType (valueSet[1]); ret.setChannelId (valueSet[2]); ret.setFolderName (valueSet[3]); ret.setFileName (valueSet[4]); ret.setConversationId(valueSet[8]); ret.setMessageId (valueSet[9]); ret.setMessageType (valueSet[10]); ret.setMessageStatus (valueSet[11]); ret.setProtocol (valueSet[12]); ret.setLocale (valueSet[13]); // Filling all time-stamp. if (!DataFactory.isNullOrEmpty(valueSet[5])) ret.setFromTimestamp(DateUtil.UTC2Calendar(valueSet[5])); if (!DataFactory.isNullOrEmpty(valueSet[6])) ret.setToTimestamp(DateUtil.UTC2Calendar(valueSet[6])); // Filling all big integer set. if (!DataFactory.isNullOrEmpty(valueSet[7])) ret.setNumOfRecords (new BigInteger(valueSet[7])); if (!DataFactory.isNullOrEmpty(valueSet[14])) ret.setLevelOfDetails(new BigInteger(valueSet[14])); if (!DataFactory.isNullOrEmpty(valueSet[15])) ret.setOffset (new BigInteger(valueSet[15])); len = MessageStatusRequestData.CONFIG_KEY_SET.length; valueSet = new String[len]; // Now Extract the configuration parameter set. for (int i = 0; i < len; i++){ valueSet[i] = t.getProperty( MessageStatusRequestData.CONFIG_PREFIX + "/" + MessageStatusRequestData.CONFIG_KEY_SET[i]); } // Filling ret.setWSEndpoint(valueSet[0]); ret.setUsername (valueSet[1]); ret.setPassword (valueSet[2]); return ret; } /* * Load the data from XML <code>t</code> into reference <code>d</code> of KVPairData. * The loading schema is based on XPath prefix set <code>prefix<code> plus the * available <code>key-set</code>. * * @param d The Data object to be loaded. * @param t The XML data source to be loaded into <code>d</code> * @param prefix * The XPath prefix for the key-set. * @param keySet * The XML tag name available in the property tree <code>t</code> */ private void loadKVPairDataFromXML(KVPairData d, PropertyTree t, String[] prefix, String[][] keySet) { if (d == null) throw new NullPointerException("Data is missing."); int len; Map props = d.getProperties(); // Iterate all key and set the properties. for (int i = 0; i < keySet.length; i++){ len = keySet[i].length; for (int j = 0; j < len; j++){ props.put(keySet[i][j], t.getProperty(prefix[i] + "/" + keySet[i][j])); } } // Set back all properties to message data. d.setProperties(props); } /* * Load the data from XML <code>t</code> into reference <code>d</code> of KVPairData. * The loading schema is based on XPath prefix set <code>prefix<code> plus the * available <code>key-set</code>. * * @param d The Data object to be loaded. * @param t The XML data source to be loaded into <code>d</code> * @param prefix * The XPath prefix for the key-set. * @param keySet * The XML tag name available in the property tree <code>t</code> */ private void loadKVPairDataFromXML(KVPairData d, PropertyTree t, String[] prefix, String[][] keySet, Class[][] typeSet) { // Check the validity of all data. DataFactory.checkValidity(d, t, prefix, keySet, typeSet); Map props = d.getProperties(); int len; String dataValue; Class dataValueClass; Object convertedValue; // Iterate all key and set the properties. for (int i = 0; i < keySet.length; i++) { len = keySet[i].length; for (int j = 0; j < len; j++) { dataValue = t.getProperty(prefix[i] + XML_SEPARATOR + keySet[i][j]); // Get the data type for this data. dataValueClass = this.getDataType(typeSet, i, j); DataConvertor dc = (DataConvertor) this.dataConvertors.get(dataValueClass); try { convertedValue = dc.deserialize(dataValue); } catch(Exception ex) { // TODO : do logging. convertedValue = dataValue; } // Set the converted value to the map in the data. props.put(keySet[i][j], convertedValue); } } // Push back all properties to the kv-pair data. d.setProperties(props); } /* * Store the data from XML <code>t</code> into reference <code>d</code> of KVPairData. * The loading schema is based on XPath prefix set <code>prefix<code> plus the * available <code>key-set</code>. * * @param d The Data object to be loaded. * @param t The XML data source to be loaded into <code>d</code> * @param path * @param prefix * The XPath prefix for the key-set. * @param keySet * The XML tag name available in the property tree <code>t</code> * @throws IOException * When unable to store the data to XML. */ private void storeKVPairDataToXML(KVPairData d, PropertyTree t, URL path, String[] prefix, String[][] keySet, Class[][] typeSet) throws IOException { // Check the validity of all data. DataFactory.checkValidity(d, t, prefix, keySet, typeSet); // Get the properties map. Map props = d.getProperties(); int len; Object dataValue; Class dataValueClass; String convertedValue; // Iterate all key and set the properties. for (int i = 0; i < keySet.length; i++) { len = keySet[i].length; for (int j = 0; j < len; j++) { dataValue = (Object) props.get(keySet[i][j]); if (dataValue == null) dataValue = ""; // Get the data type for this data. dataValueClass = this.getDataType(typeSet, i, j); DataConvertor dc = (DataConvertor) this.dataConvertors.get(dataValueClass); try { convertedValue = dc.serialize(dataValue); } catch(Exception ex) { // TODO : do logging. convertedValue = dataValue.toString(); } // Set the converted value to the XML tree. t.setProperty(prefix[i] + XML_SEPARATOR + keySet[i][j], convertedValue); } } // Now all the data from KVPairData is pushed into property tree, store the tree. try { if (path == null) path = t.getURL(); t.store(path); } catch(ComponentException ce) { // TODO: it the exception has enough message ? throw new IOException("Unable to store data to XML: " + ce.getMessage()); } } /** * The <code>DataConvertor</code> is a simple data conversion interface for converting data to string or vice-versa. */ private static interface DataConvertor { Class handleClass(); String serialize (Object dataToConvert) throws Exception; Object deserialize (String convertedString) throws Exception; } /** * The <code>ByteArrayDataConvertor</code> is a data convertor converting a byte array to string * or string back to byte array. */ private static class ByteArrayDataConvertor implements DataConvertor { public Class handleClass(){ return byte[].class; } public String serialize(Object dataToConvert) throws Exception { if (dataToConvert instanceof byte[]) return new String((byte[])dataToConvert, "UTF-8"); return ""; } public Object deserialize(String convertedString) { if (convertedString != null) return convertedString.getBytes(); return new byte[]{}; } } /** * The <code>NoOpDataConvertor</code> is a data convertor which do nothing during conversation. * Just pass-in and return-out the argument. */ private static class NoOpDataConvertor implements DataConvertor { public Class handleClass(){ return String.class; } public String serialize(Object dataToConvert) throws Exception { return dataToConvert.toString(); } public Object deserialize(String convertedString) { return convertedString; } } /* * Check the validity for the input arguments. * * @throws NullPointerException * If the KVPairData d is null. * If the PropertyTree t is null. * If the prefix is null. * If the keySet is null. * @throws IllegalArgumentException * If the length of prefix equal to zero. * If the length of keySet equal to zero. * If the length of prefix does not match with keySet. */ private static void checkValidity(KVPairData d, PropertyTree t, String[] prefix, String[][] keySet, Class[][] typeSet) { if (d == null) throw new NullPointerException("Missing KVPairData in the arguments."); if (t == null) throw new NullPointerException("Missing PropertyTree in the arguments."); if (prefix == null) throw new NullPointerException("Missing Prefix in the arguments."); if (keySet == null) throw new NullPointerException("Missing KeySet in the arguments."); /*if (typeSet == null) throw new NullPointerException("Missing TypeSet in the arguments.");*/ if (prefix.length == 0) throw new IllegalArgumentException("No XPath prefix found."); if (keySet.length == 0) throw new IllegalArgumentException("No XPath key found."); if (prefix.length != keySet.length) throw new IllegalArgumentException("The length of XPath prefix and key does not match:" + prefix.length + "," + keySet.length); } /* * Check the input var is null or empty. * * @param var The string to test. * @return true if the input is null or empty. */ private static boolean isNullOrEmpty(String var) { return (var == null || "".equals(var)); } /* * A Helper method for getting the class type from typeSet at i and j. * * It simply return typeSet[i][j] when it exist and not null. Otherwise, it return String.class. */ private Class getDataType(Class[][] typeSet, int i, int j) { if (typeSet != null && i < typeSet.length && j < typeSet[i].length) { return typeSet[i][j]; } // Default data type return String.class; } }