📄 xmlserialization.java
字号:
// in ignore list of class?
if (m_Properties.isIgnored(result, getPath(child)))
return result;
// is it allowed?
if (!m_Properties.isAllowed(result, methodName))
return result;
descriptor = (PropertyDescriptor) descriptors.get(methodName);
// unknown property?
if (descriptor == null) {
if (!m_CustomMethods.read().contains(methodName))
System.out.println("WARNING: unknown property '" + name + "." + methodName + "'!");
return result;
}
method = descriptor.getWriteMethod();
methodArgs = new Object[1];
tmpResult = invokeReadFromXML(child);
paramClass = method.getParameterTypes()[0];
// array?
if (paramClass.isArray()) {
// no data?
if (Array.getLength(tmpResult) == 0)
return result;
methodArgs[0] = (Object[]) tmpResult;
}
// non-array
else {
methodArgs[0] = tmpResult;
}
method.invoke(result, methodArgs);
return result;
}
/**
* returns an array with the dimensions of the array stored in XML
* @param node the node to determine the dimensions for
* @return the dimensions of the array
*/
protected int[] getArrayDimensions(Element node) {
Vector children;
Vector tmpVector;
int[] tmp;
int[] result;
int i;
// have we reached the innermost dimension?
if (stringToBoolean(node.getAttribute(ATT_ARRAY)))
children = XMLDocument.getChildTags(node);
else
children = null;
if (children != null) {
tmpVector = new Vector();
if (children.size() > 0) {
// are children also arrays?
tmp = getArrayDimensions((Element) children.get(0));
// further dimensions
if (tmp != null) {
for (i = tmp.length - 1; i >= 0; i--)
tmpVector.add(new Integer(tmp[i]));
}
// add current dimension
tmpVector.add(0, new Integer(children.size()));
}
else {
tmpVector.add(new Integer(0));
}
// generate result
result = new int[tmpVector.size()];
for (i = 0; i < result.length; i++)
result[i] = ((Integer) tmpVector.get(tmpVector.size() - i - 1)).intValue();
}
else {
result = null;
}
return result;
}
/**
* builds the object from the given DOM node.
* (only public due to reflection)
*
* @param parent the parent object to get the properties for
* @param node the associated XML node
* @return the instance created from the XML description
* @throws Exception if instantiation fails
*/
public Object readFromXML(Element node) throws Exception {
String classname;
String name;
boolean primitive;
boolean array;
boolean isnull;
Class cls;
Vector children;
Object result;
int i;
int n;
Hashtable descriptors;
PropertyDescriptor descriptor;
Constructor constructor;
String methodName;
Method method;
Class[] methodClasses;
Object[] methodArgs;
Object tmpResult;
Object[] tmpResultArray;
Class paramClass;
Element child;
// for debugging only
if (DEBUG)
trace(new Throwable(), node.getAttribute(ATT_NAME));
m_CurrentNode = node;
result = null;
name = node.getAttribute(ATT_NAME);
classname = node.getAttribute(ATT_CLASS);
primitive = stringToBoolean(node.getAttribute(ATT_PRIMITIVE));
array = stringToBoolean(node.getAttribute(ATT_ARRAY));
isnull = stringToBoolean(node.getAttribute(ATT_NULL));
// special handling of null
if (isnull)
return result;
children = XMLDocument.getChildTags(node);
cls = determineClass(classname);
// array
if (array) {
result = Array.newInstance(cls, getArrayDimensions(node));
for (i = 0; i < children.size(); i++) {
child = (Element) children.get(i);
Array.set(result, Integer.parseInt(child.getAttribute(ATT_NAME)), invokeReadFromXML(child));
}
}
// non-array
else {
// primitive/String-constructor
if (children.size() == 0) {
// primitive
if (primitive) {
result = getPrimitive(node);
}
// assumed String-constructor
else {
methodClasses = new Class[1];
methodClasses[0] = String.class;
methodArgs = new Object[1];
methodArgs[0] = XMLDocument.getContent(node);
try {
constructor = cls.getConstructor(methodClasses);
result = constructor.newInstance(methodArgs);
}
catch (Exception e) {
// if it's not a class with String constructor, let's try standard constructor
try {
result = cls.newInstance();
}
catch (Exception e2) {
// sorry, can't instantiate!
result = null;
System.out.println("ERROR: Can't instantiate '" + classname + "'!");
}
}
}
}
// normal get/set methods
else {
result = cls.newInstance();
descriptors = getDescriptors(result);
for (i = 0; i < children.size(); i++)
result = readFromXML(result, name, (Element) children.get(i));
}
}
return result;
}
/**
* either invokes a custom method to read a specific property/class or the standard
* method <code>readFromXML(Element)</code>
*
* @param parent the parent object to get the properties for
* @param node the associated XML node
* @return the instance created from the XML description
* @throws Exception if instantiation fails
* @see #m_CustomReadMethods
*/
protected Object invokeReadFromXML(Element node) throws Exception {
Method method;
Class[] methodClasses;
Object[] methodArgs;
boolean array;
boolean useDefault;
useDefault = false;
method = null;
m_CurrentNode = node;
try {
// special handling of null values
if (stringToBoolean(node.getAttribute(ATT_NULL)))
useDefault = true;
if (!useDefault) {
array = stringToBoolean(node.getAttribute(ATT_ARRAY));
// display name?
if (m_CustomMethods.read().contains(node.getAttribute(ATT_NAME)))
method = (Method) m_CustomMethods.read().get(node.getAttribute(ATT_NAME));
else
// class name?
if ( (!array) && (m_CustomMethods.read().contains(determineClass(node.getAttribute(ATT_CLASS)))) )
method = (Method) m_CustomMethods.read().get(determineClass(node.getAttribute(ATT_CLASS)));
else
method = null;
useDefault = (method == null);
}
// custom method
if (!useDefault) {
methodClasses = new Class[1];
methodClasses[0] = Element.class;
methodArgs = new Object[1];
methodArgs[0] = node;
return method.invoke(this, methodArgs);
}
// standard
else {
return readFromXML(node);
}
}
catch (Exception e) {
if (DEBUG)
e.printStackTrace();
if (m_CurrentNode != null) {
System.out.println("Happened near: " + getPath(m_CurrentNode));
// print it only once!
m_CurrentNode = null;
}
System.out.println("PROBLEM (read): " + node.getAttribute("name"));
throw (Exception) e.fillInStackTrace();
}
}
/**
* additional pre-processing can happen in derived classes before the
* actual reading from XML (working on the raw XML). right now it does
* nothing with the document.
*
* @param o the object to perform some additional processing on
* @return the processed object
* @throws Exception if post-processing fails
*/
protected Document readPreProcess(Document document) throws Exception {
return document;
}
/**
* additional post-processing can happen in derived classes after reading
* from XML. right now it only returns the object as it is.
*
* @param o the object to perform some additional processing on
* @return the processed object
* @throws Exception if post-processing fails
*/
protected Object readPostProcess(Object o) throws Exception {
return o;
}
/**
* returns the given DOM document as an instance of the specified class
*
* @param document the parsed DOM document representing the object
* @return the XML as object
* @throws if object instantiation fails
*/
public Object fromXML(Document document) throws Exception {
if (!document.getDocumentElement().getNodeName().equals(ROOT_NODE))
throw new Exception("Expected '" + ROOT_NODE + "' as root element, but found '" + document.getDocumentElement().getNodeName() + "'!");
m_Document.setDocument(readPreProcess(document));
checkVersion();
return readPostProcess(invokeReadFromXML(m_Document.getDocument().getDocumentElement()));
}
/**
* parses the given XML string (can be XML or a filename) and returns an
* Object generated from the representation
*
* @param xml the xml to parse (if "<?xml" is not found then it is considered a file)
* @return the generated instance
* @throws if something goes wrong with the parsing
*/
public Object read(String xml) throws Exception {
return fromXML(m_Document.read(xml));
}
/**
* parses the given file and returns a DOM document
*
* @param file the XML file to parse
* @return the parsed DOM document
* @throws if something goes wrong with the parsing
*/
public Object read(File file) throws Exception {
return fromXML(m_Document.read(file));
}
/**
* parses the given stream and returns a DOM document
*
* @param stream the XML stream to parse
* @return the parsed DOM document
* @throws if something goes wrong with the parsing
*/
public Object read(InputStream stream) throws Exception {
return fromXML(m_Document.read(stream));
}
/**
* parses the given reader and returns a DOM document
*
* @param reader the XML reader to parse
* @return the parsed DOM document
* @throws if something goes wrong with the parsing
*/
public Object read(Reader reader) throws Exception {
return fromXML(m_Document.read(reader));
}
/**
* writes the given object into the file
*
* @param file the filename to write to
* @param o the object to serialize as XML
* @throws if something goes wrong with the parsing
*/
public void write(String file, Object o) throws Exception {
toXML(o).write(file);
}
/**
* writes the given object into the file
*
* @param file the filename to write to
* @param o the object to serialize as XML
* @throws if something goes wrong with the parsing
*/
public void write(File file, Object o) throws Exception {
toXML(o).write(file);
}
/**
* writes the given object into the stream
*
* @param file the filename to write to
* @param o the object to serialize as XML
* @throws if something goes wrong with the parsing
*/
public void write(OutputStream stream, Object o) throws Exception {
toXML(o).write(stream);
}
/**
* writes the given object into the writer
*
* @param file the filename to write to
* @param o the object to serialize as XML
* @throws if something goes wrong with the parsing
*/
public void write(Writer writer, Object o) throws Exception {
toXML(o).write(writer);
}
/**
* for testing only. if the first argument is a filename with ".xml"
* as extension it tries to generate an instance from the XML description
* and does a <code>toString()</code> of the generated object.
*/
public static void main(String[] args) throws Exception {
if (args.length > 0) {
// read xml and print
if (args[0].toLowerCase().endsWith(".xml")) {
System.out.println(new XMLSerialization().read(args[0]).toString());
}
// read binary and print generated XML
else {
// read
FileInputStream fi = new FileInputStream(args[0]);
ObjectInputStream oi = new ObjectInputStream(
new BufferedInputStream(fi));
Object o = oi.readObject();
oi.close();
// print to stdout
//new XMLSerialization().write(System.out, o);
new XMLSerialization().write(new BufferedOutputStream(new FileOutputStream(args[0] + ".xml")), o);
// print to binary file
FileOutputStream fo = new FileOutputStream(args[0] + ".exp");
ObjectOutputStream oo = new ObjectOutputStream(
new BufferedOutputStream(fo));
oo.writeObject(o);
oo.close();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -