本项目的目的是使用适配器模式将DocumentHandler的接口适配成Java.util.Properties的接口。采用的是对象的适配器模式。XMLproperties是一个继承自Java.util.Properties的对象,并委派一个DocumentHandler类型的对象。
本项目需要两个类:XMLProperties类和XMLParser类,前者是Java.util.Properties类型,后者是DocumentHandler类型。
源代码如下,适配器类XMLProperties:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Properties;
import org.xml.sax.SAXException;
public class XMLProperties extends Properties{
XMLParser p=null;
/*
* 从一个输入流读取xml
* */
public synchronized void load(InputStream in) throws IOException
{
try {
p=new XMLParser(in,this);
} catch (SAXException e) {
// TODO Auto-generated catch block
throw new IOException(e.getMessage());
}
}
/*
* 将XML文件读入
* */
public synchronized void load(File file) throws FileNotFoundException, SAXException
{
InputStream in=new BufferedInputStream(new FileInputStream(file));
try {
p=new XMLParser(in, this);
} catch (SAXException e) {
// TODO Auto-generated catch block
System.out.println(e);
throw e;
}
}
/*调用下面的store()方法*/
public synchronized void save(OutputStream out,String header)
{
store( out, header);
}
/*
* 将此property列表写入到输出流里
* */
public synchronized void store(OutputStream out,String header)
{
PrintWriter wout=new PrintWriter(out);
wout.println("<?xml version=‘1.0‘>");
if(header!=null)
{
wout.println("<!--"+header+"-->");
}
wout.print("<properties>");
for(Enumeration e=keys();e.hasMoreElements();)
{
String key=(String)e.nextElement();
String val=(String)get(key);
wout.print("\n<key name=\""+key+"\">");
wout.print(encode(val));
wout.print("</key>");
}
wout.print("\n</properties>");
wout.flush();
}
protected StringBuffer encode(String string)
{
int len=string.length();
StringBuffer buffer=new StringBuffer(len);
char c;
for(int i=0;i<len;i++)
{
switch(c=string.charAt(i))
{
case ‘&‘:
buffer.append("&");
break;
case ‘x‘:
buffer.append("<");
break;
case ‘ ‘:
buffer.append(">");
break;
default:
buffer.append(c);
}
}
return buffer;
}
public XMLProperties()
{
super();
}
public XMLProperties(Properties properties)
{
super(properties);
}
}
XMLParser源代码:
import javax.management.RuntimeErrorException;
import org.junit.runner.Computer;
import org.xml.sax.AttributeList;
import org.xml.sax.DocumentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.Parser;
import org.xml.sax.SAXException;
public class XMLParser implements DocumentHandler{
private static final int IN_NOTHING=0;
private static final int IN_DOCUMENT=1;
private static final int IN_KEY=2;
private int state=IN_NOTHING;
private String key;
private StringBuffer value;
private Parser parser;
private Class parser_class=null;
private Properties xmlprop=null;
public static final String PARSER_P="org.apache.xerces.parsers.SAXParser";
private Class getParserClass()throws ClassNotFoundException
{
if(parser_class==null)
parser_class=Class.forName(PARSER_P);
return parser_class;
}
private Parser getParser()
{
try {
return (Parser)getParserClass().newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException("Unable to intantiate"+PARSER_P);
}
}
public XMLParser(InputStream in,XMLProperties xmlprop) throws SAXException
{
// TODO Auto-generated constructor stub
this.xmlprop=xmlprop;
this.state=IN_NOTHING;
this.value=new StringBuffer();
try {
parser=getParser();
parser.setDocumentHandler(this);
parser.parse(new InputSource(in));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
throw new SAXException("can‘t create parser");
}
}
@Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startElement(String name, AttributeList atts)
throws SAXException {
// TODO Auto-generated method stub
if(state==IN_NOTHING)
{
if(name.equals("properties"))
{
state=IN_DOCUMENT;
}
else {
throw new SAXException("attemp to find properties");
}
}
else if(state==IN_DOCUMENT)
{
if(name.equals("propertylist"))
{
state=IN_DOCUMENT;
key=atts.getValue("name");
if(key==null)
{
throw new SAXException("no name for key "+atts);
}
}
else if(name.equals("property"))
{
state=IN_KEY;
key=atts.getValue("name");
if(key==null)
{
throw new SAXException("no name for key "+atts);
}
}
else
{
throw new SAXException("attemp to find keys");
}
}
else
{
throw new SAXException("invalid element "+name);
}
}
@Override
public void endElement(String name) throws SAXException {
// TODO Auto-generated method stub
if(state==IN_KEY)
{
xmlprop.setProperty(key, value.toString());
System.out.println("<key name=\""+key+"\">");
System.out.println(value.toString()+"</key>\n");
state=IN_DOCUMENT;
name=null;
value=new StringBuffer();
}
else if(state==IN_DOCUMENT)
{
state=IN_NOTHING;
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
if(state==IN_KEY)
{
compute(ch,start,length);
}
}
public void compute(char[] ch,int start,int length)
{
int st=start;
int len=length-1;
while(st<length && ((ch[st]==‘\n‘)||(ch[st]==‘\t‘)||(ch[st]==‘ ‘)||(ch[st]==‘\r‘)))
st++;
while(len>0 && ((ch[len]==‘\n‘)||(ch[len]==‘\t‘)||(ch[len]==‘ ‘)||(ch[len]==‘\r‘)))
len--;
while(st<=len)
{
value.append(ch[st]);
st++;
}
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
// TODO Auto-generated method stub
}
}
测试类源代码:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import org.xml.sax.SAXException;
public class TestXML
{
public static void main(String[] args) throws IOException, SAXException
{
XMLProperties xml=new XMLProperties();
xml.load(new File("D:\\data\\testXml.xml"));
Enumeration keyEnumeration=xml.keys();
Enumeration valueEnumeration=xml.elements();
while(keyEnumeration.hasMoreElements())
{
String key=(String)keyEnumeration.nextElement();
String value=(String)valueEnumeration.nextElement();
System.out.println(key+"="+value);
OutputStream out=new FileOutputStream(new File("D:\\data\\out.xml"));
xml.save(out, "test");
}
}
}
测试需要的xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "D:\data\xmlproperties.dtd"> <!--XML Wrapper for Properties--> <properties> <propertylist name="mylist"> <property name="name"> webendshaere </property> <property name="website"> www.webendshaere.com </property> <property name="email"> webmaster@webendshaere.com </property> <property name="techsupport"> support@webendshaere.com </property> </propertylist> </properties>
测试需要的xmlproperties.dtd文件
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT properties (#PCDATA|property)*> <!ELEMENT key (#PCDATA)> <!ATTLIST key name CDATA #IMPLIED>
把xml文件转成properties类型----适配器模式的应用
原文:http://www.cnblogs.com/xtsylc/p/4722891.html