001    package EVolve.util.xmlutils;
002    
003    import org.xml.sax.helpers.*;
004    import org.xml.sax.*;
005    import java.util.*;
006    import java.io.*;
007    import java.lang.reflect.Field;
008    import EVolve.Scene;
009    import EVolve.exceptions.EVolveException;
010    
011    /**
012     * User: Wei Wang
013     * Date: Jun 4, 2003
014     * Time: 1:10:56 PM
015     */
016    public class XMLLoader extends DefaultHandler{
017        private XMLReader xmlReader;
018        private HashSet tags;
019        private String xmlFName, rootTag, currentTag, lastTag="";
020        private Object[] storage;
021        private boolean valueWanted,beginParse;
022        private int numberOfValueRead;
023    
024        public XMLLoader () {
025            tags = new HashSet();
026        }
027    
028        public void initialReader(String xmlFName, Object rootData) throws EVolveException{
029            tags.clear();
030            Field[] fields = rootData.getClass().getFields();
031            for (int i=0; i<fields.length; i++)
032                tags.add(fields[i].getName());
033    
034            this.xmlFName = xmlFName;
035            rootTag = null;
036            storage = null;
037            numberOfValueRead = 0;
038    
039            try {
040                xmlReader = XMLReaderFactory.createXMLReader();
041                xmlReader.setContentHandler(this);
042                xmlReader.setContentHandler(this);
043            } catch (SAXException e) {
044                Scene.showErrorMessage("Failed to initialize XML Reader, reason:"+e.getMessage()+".");
045                throw new EVolveException(e.getMessage());
046            }
047        }
048    
049        public void read(Object[] data) throws IOException{
050            storage = data;
051            valueWanted = false;
052            beginParse = rootTag==null;
053            try {
054                BufferedReader input = new BufferedReader(new FileReader(xmlFName));
055                xmlReader.parse(new InputSource(input));
056                input.close();
057            } catch (SAXException e) {
058                Scene.showErrorMessage("Error occurred during processing XML file.");
059                return;
060            }
061        }
062    
063        public void read(String rootTag, Object[] data) throws IOException{
064            this.rootTag = rootTag;
065            read(data);
066        }
067    
068        public void startElement(String uri, String name, String qName, Attributes atts) {
069            if ((rootTag!=null)&&(rootTag.equals(qName)))
070                beginParse = true;
071    
072            currentTag = qName;
073    
074            if (beginParse&&tags.contains(qName))
075                valueWanted = true;
076        }
077    
078        public void endElement(String uri, String name, String qName) {
079            valueWanted = false;
080            if (beginParse&&tags.contains(name)) {
081                numberOfValueRead++;
082            }
083        }
084    
085        public void characters(char ch[], int start, int length) {
086            if (!valueWanted) return;
087    
088            Field[] fields = storage[numberOfValueRead/tags.size()].getClass().getFields();
089            for (int i=0; i<fields.length; i++) {
090                if (fields[i].getName().equals(currentTag)) {
091                    try {
092                        if (fields[i].getType().getName().indexOf("String") != -1) {
093                            String value = new String(ch,start,length);
094                            if (lastTag.equals(currentTag)) {// the data is too long to be sent in one characters event
095                                String oldValue = (String)fields[i].get(storage[numberOfValueRead/tags.size()]);
096                                value = oldValue+value;
097                            }
098                            fields[i].set(storage[numberOfValueRead/tags.size()],value);
099                        }
100                        lastTag = currentTag;
101                        break;
102                    } catch (IllegalAccessException e) {
103                        Scene.showErrorMessage("Internal error, please check XMLLoader.characters(...)");
104                    }
105                }
106            }
107        }
108    }