Site Sponsors:
XML IO Using Generics - Before Java 1.7 
In as much as we often teach students who are using an older version of Java, we decided to put together another demonstration. -An example that can readily be targeted for earlier versions of Java.

Remember - the use of Java Serialization is NOT required. In order to use the XML serialization technique, all we need is a POJO!

First, the I/O Demonstration (note that checking for nulls (etc) has been omitted so as to enhance conceptual review):

package com.soft9000.file;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class XmlClassIO<T> {
public String sLastError = "";

public boolean write(String fileName, T ref) {
try {
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream(fileName)));
encoder.writeObject(ref);
encoder.close();
return true;
} catch (Exception ex) {
this.sLastError = ex.getMessage();
return false;
}
}

public T read(String fileName) {
try {
XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(
new FileInputStream(fileName)));
T result = (T) decoder.readObject();
decoder.close();
return result;
} catch (Exception ex) {
this.sLastError = ex.getMessage();
return null;
}
}
}

Next, the testable class:

package com.soft9000.file;

import java.util.List;
import java.util.ArrayList;

public class BigBadFoo {

private ArrayList<String> list = new ArrayList<String>();
private String foo;

public BigBadFoo() {

}

public void setList(List<String> someList) {
this.list = new ArrayList<String>(someList);
}

public List<String> getList() {
return this.list;
}

public void setFoo(String string) {
this.foo = string;
}

public String getFoo() {
return this.foo;
}

public boolean equals(Object obj) {
if (obj instanceof BigBadFoo) {
if (super.equals(obj))
return true;
BigBadFoo ref = (BigBadFoo) obj;
if (foo.equals(ref.foo) == true) {
return list.equals(ref.list);
}
}
return false;
}

}

Finally, the test case:

package com.soft9000.file;

import java.util.ArrayList;

/**
* Proof of concept.
*
* @author Profnagy
*
*/
public class Main {

public static void main(String[] args) {
ArrayList<String> SomeList = new ArrayList();
SomeList.add("one");
SomeList.add("two");
SomeList.add("three");
BigBadFoo foo1 = new BigBadFoo();
foo1.setFoo("12345");
foo1.setList(SomeList);
com.soft9000.file.XmlClassIO<BigBadFoo> io = new XmlClassIO<BigBadFoo>();
io.write("test.xml", foo1);

BigBadFoo foo2 = io.read("test.xml");
if(foo2.equals(foo1) == false) {
System.out.println("Serialization Failure.");
System.exit(-1);
}
System.out.println("Serialization Success.");
}
}

Notes


The above has been designed to be cut-and-pasted.

Be sure to re-format the code after doing so.


Enjoy,

-Rn

Student Note: Regression


While fine for illustrative purposes, over time things can change.

In as much as we might want to be sure that things actually break when they should, it is always nice to add-in a few "should break" tests, as well. Such will help us a-lot as we perform feature regression tests, over time:

Here is a simple example:
      
foo2.setFoo("shazam");
if(foo2.equals(foo1) == true) {
System.out.println("Assignment/Equality Regression.");
System.exit(-1);
}


[ add comment ] ( 1916 views )   |  permalink  |  related link
XML IO Using Generics 
When it comes to reading and writing Java-hosted classes, why not use generics?

package com.soft9000.file;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

/**
*
* @author profnagy
*/
public class XmlClassIO<T> {
public String sLastError = "";

public boolean write(String fileName, T ref) {
try {
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(
new FileOutputStream(fileName)));
encoder.writeObject(ref);
encoder.close();
return true;
} catch (Exception ex) {
this.sLastError = ex.getMessage();
return false;
}
}

public T read(String fileName) {
try {
XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(
new FileInputStream(fileName)));
T result = (T) decoder.readObject();
decoder.close();
return result;
} catch (Exception ex) {
this.sLastError = ex.getMessage();
return null;
}
}
}


When our classes adhere to a few common conventions, not only do we no longer need to use 'Serializable', but we can avoid creating the usual set of encoders / decoders, as well.

BigBadFoo



For example, suppose we have a class (BigBadFoo) to save in the XML. Better still, let's suppose that the class has used an ArrayList: (*)

        ArrayList<String> SomeList = new ArrayList<>();
SomeList.add("one");
SomeList.add("two");
SomeList.add("three");
BigBadFoo foo = new BigBadFoo();
foo.setFoo("12345");
foo.setList(SomeList);
com.soft9000.file.XmlClassIO<BigBadFoo> io = new XmlClassIO<>();
io.write("test.xml", foo);

By upcasting the getter / setter to use List, even collections can be quickly converted to XML:

    public List<String> getList() {
return list;
}

public void setList(List<String> list) {
this.list = new ArrayList(list);
}

Here is what the entire class looks like:

public class BigBadFoo {

private String foo = "noneya";
private ArrayList<String> list = new ArrayList<>();

public BigBadFoo() {
}

public String getFoo() {
return foo;
}

public void setFoo(String foo) {
this.foo = foo;
}

public List<String> getList() {
return list;
}

public void setList(List<String> list) {
this.list = new ArrayList(list);
}
}

Here is what the above XML-test writing of BigBadFoo looks like:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_04" class="java.beans.XMLDecoder">
<object class="console01.foo">
<void property="foo">
<string>12345</string>
</void>
<void property="list">
<void method="add">
<string>one</string>
</void>
<void method="add">
<string>two</string>
</void>
<void method="add">
<string>three</string>
</void>
</void>
</object>
</java>


Beware the NULL?


Curiously - while completely understandable - it seems that saving default-objects will do little in the XML. Hence, while we might righteously feel that the word "noneya" (the initialized default) could appear somewhere, doing things like:

        io.write("test.xml", new BigBadFoo());

Results in absolutely nada being saved to the XML:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_04" class="java.beans.XMLDecoder">
<object class="console01.BigBadFoo"/>
</java>


So while a default object will indeed be returned by the decoder, note that if our defaults ever change, that we will loose any previously-defined default value(s).

-It's an .isNull() type of 'thang.


Enjoy,

-Rn

(*) Before Java 1.7?


Note that if we are not using Java 1.7, then we will have to fix that new "Diamond Notation" (as used above.)

So to make the examples work on previous versions, simply add the "String" back in so as to change ArrayList<>, to ArrayList<String>().

After adding the string - and thru the miracle of type replacement on archaic versions - all will work just as well elsewhere.

Caveat Outsourcing?


Moving forward, be prepared to note the ever growing host of new, anal-retentive, style-not-grammar warnings & errors. Designed to suppress personal style, freedom of expression, and change?

[ add comment ] ( 1905 views )   |  permalink  |  related link

<<First <Back | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | Next> Last>>