source: src/main/java/weka/experiment/xml/XMLExperiment.java @ 27

Last change on this file since 27 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 11.0 KB
RevLine 
[4]1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 * XMLExperiment.java
19 * Copyright (C) 2004 University of Waikato, Hamilton, New Zealand
20 */
21
22package weka.experiment.xml;
23
24import java.beans.PropertyDescriptor;
25import java.io.BufferedInputStream;
26import java.io.BufferedOutputStream;
27import java.io.FileInputStream;
28import java.io.FileOutputStream;
29import java.io.ObjectInputStream;
30import java.io.ObjectOutputStream;
31import java.util.Vector;
32
33import org.w3c.dom.Element;
34
35import weka.core.RevisionUtils;
36import weka.core.xml.XMLBasicSerialization;
37import weka.core.xml.XMLDocument;
38import weka.experiment.Experiment;
39import weka.experiment.PropertyNode;
40
41/**
42 * This class serializes and deserializes an Experiment instance to and
43 * fro XML.<br>
44 * It omits the <code>options</code> from the Experiment, since these are handled
45 * by the get/set-methods. For the <code>Classifier</code> class with all its
46 * derivative classes it stores only <code>debug</code> and <code>options</code>.
47 * For <code>SplitEvaluator</code> and <code>ResultProducer</code> only the
48 * options are retrieved. The <code>PropertyNode</code> is done manually since
49 * it has no get/set-methods for its public fields.<br>
50 * Since there's no read-method for <code>m_ClassFirst</code> we always save it
51 * as <code>false</code>.
52 *
53 * @see Experiment#m_ClassFirst
54 *
55 * @author FracPete (fracpete at waikato dot ac dot nz)
56 * @version $Revision: 1.6 $
57 */
58public class XMLExperiment
59   extends XMLBasicSerialization {
60 
61   /** the name of the classFirst property */
62   public final static String NAME_CLASSFIRST = "classFirst";
63
64   /** PropertyNode member */
65   public final static String NAME_PROPERTYNODE_VALUE = "value";
66
67   /** PropertyNode member */
68   public final static String NAME_PROPERTYNODE_PARENTCLASS = "parentClass";
69
70   /** PropertyNode member */
71   public final static String NAME_PROPERTYNODE_PROPERTY = "property";
72   
73   /**
74    * initializes the serialization
75    *
76    * @throws Exception if initialization fails
77    */
78   public XMLExperiment() throws Exception {
79      super();
80   }
81   
82   /**
83    * generates internally a new XML document and clears also the IgnoreList and
84    * the mappings for the Read/Write-Methods
85    *
86    * @throws Exception if initializing fails
87    */
88   public void clear() throws Exception {
89      super.clear();
90
91      // ignore
92      m_Properties.addIgnored(VAL_ROOT + ".options");
93      m_Properties.addIgnored(Experiment.class, "options");
94     
95      // allow
96      m_Properties.addAllowed(weka.classifiers.Classifier.class, "debug");
97      m_Properties.addAllowed(weka.classifiers.Classifier.class, "options");
98      // we assume that classes implementing SplitEvaluator also implement OptionHandler
99      m_Properties.addAllowed(weka.experiment.SplitEvaluator.class, "options");
100      // we assume that classes implementing ResultProducer also implement OptionHandler
101      m_Properties.addAllowed(weka.experiment.ResultProducer.class, "options");
102     
103      // read/write methods
104      m_CustomMethods.register(this, PropertyNode.class, "PropertyNode");
105   }
106   
107   /**
108    * enables derived classes to add other properties to the DOM tree, e.g.
109    * ones that do not apply to the get/set convention of beans.
110    *
111    * @param o the object that is serialized into XML
112    * @throws Exception if post-processing fails
113    */
114   protected void writePostProcess(Object o) throws Exception {
115      Element              node;
116      Experiment           exp;
117
118      exp = (Experiment) o;
119     
120      // classfirst
121      node = addElement(m_Document.getDocument().getDocumentElement(), NAME_CLASSFIRST, Boolean.class.getName(), false);
122      node.appendChild(node.getOwnerDocument().createTextNode(new Boolean(false).toString()));   // TODO: get-Method for classFirst in Experiment???
123   }
124   
125   /**
126    * additional post-processing can happen in derived classes after reading
127    * from XML.
128    *
129    * @param o the object to perform some additional processing on
130    * @return the processed object
131    * @throws Exception if post-processing fails
132    */
133   protected Object readPostProcess(Object o) throws Exception {
134      Element              node;
135      Experiment           exp;
136      int                  i;
137      Vector               children;
138
139      exp = (Experiment) o;
140     
141      // classfirst
142      children = XMLDocument.getChildTags(m_Document.getDocument().getDocumentElement());
143      for (i = 0; i < children.size(); i++) {
144         node = (Element) children.get(i);
145         if (node.getAttribute(ATT_NAME).equals(NAME_CLASSFIRST)) {
146            exp.classFirst(new Boolean(XMLDocument.getContent(node)).booleanValue());
147            break;
148         }
149      }
150     
151      return o;
152   }
153   
154   /**
155    * adds the given PropertyNode to a DOM structure.
156    *
157    * @param parent the parent of this object, e.g. the class this object is a member of
158    * @param o the Object to describe in XML
159    * @param name the name of the object
160    * @return the node that was created
161    * @throws Exception if the DOM creation fails
162    */
163   public Element writePropertyNode(Element parent, Object o, String name) throws Exception {
164      Element              node;
165      PropertyNode         pnode;
166      Vector               children;
167      int                  i;
168      Element              child;
169
170      // for debugging only
171      if (DEBUG)
172         trace(new Throwable(), name);
173     
174      m_CurrentNode = parent;
175     
176      pnode = (PropertyNode) o;
177      node  = (Element) parent.appendChild(m_Document.getDocument().createElement(TAG_OBJECT));
178      node.setAttribute(ATT_NAME, name);
179      node.setAttribute(ATT_CLASS, pnode.getClass().getName());
180      node.setAttribute(ATT_PRIMITIVE, VAL_NO);
181      node.setAttribute(ATT_ARRAY, VAL_NO);
182     
183      if (pnode.value != null)
184         invokeWriteToXML(node, pnode.value, NAME_PROPERTYNODE_VALUE);
185      if (pnode.parentClass != null)
186         invokeWriteToXML(node, pnode.parentClass.getName(), NAME_PROPERTYNODE_PARENTCLASS);
187      if (pnode.property != null)
188         invokeWriteToXML(node, pnode.property.getDisplayName(), NAME_PROPERTYNODE_PROPERTY);
189     
190      // fix primitive values
191      if (    (pnode.value != null) 
192           && (pnode.property != null) 
193           && (pnode.property.getPropertyType().isPrimitive())) {
194         children = XMLDocument.getChildTags(node);
195         for (i = 0; i < children.size(); i++) {
196            child = (Element) children.get(i);
197            if (!child.getAttribute(ATT_NAME).equals(NAME_PROPERTYNODE_VALUE))
198               continue;
199            child.setAttribute(ATT_CLASS, pnode.property.getPropertyType().getName());
200            child.setAttribute(ATT_PRIMITIVE, VAL_YES);
201         }
202      }
203     
204      return node;
205   }
206
207   /**
208    * builds the PropertyNode from the given DOM node.
209    *
210    * @param node the associated XML node
211    * @return the instance created from the XML description
212    * @throws Exception if instantiation fails
213    * @see javax.swing.DefaultListModel
214    */
215   public Object readPropertyNode(Element node) throws Exception {
216      Object               result;
217      Object               value;
218      String               parentClass;
219      String               property;
220      Vector               children;
221      Element              child;
222      int                  i;
223      Class                cls;
224
225      // for debugging only
226      if (DEBUG)
227         trace(new Throwable(), node.getAttribute(ATT_NAME));
228
229      m_CurrentNode = node;
230     
231      result      = null;
232
233      children    = XMLDocument.getChildTags(node);
234      value       = null;
235      parentClass = null;
236      property    = null;
237     
238      for (i = 0; i < children.size(); i++) {
239         child = (Element) children.get(i);
240         
241         if (child.getAttribute(ATT_NAME).equals(NAME_PROPERTYNODE_VALUE)) {
242            if (stringToBoolean(child.getAttribute(ATT_PRIMITIVE)))
243               value = getPrimitive(child);
244            else
245               value = invokeReadFromXML(child);
246         }
247         if (child.getAttribute(ATT_NAME).equals(NAME_PROPERTYNODE_PARENTCLASS))
248            parentClass = XMLDocument.getContent(child);
249         if (child.getAttribute(ATT_NAME).equals(NAME_PROPERTYNODE_PROPERTY))
250            property = XMLDocument.getContent(child);
251      }
252     
253      if (parentClass != null)
254         cls = Class.forName(parentClass);
255      else
256         cls = null;
257     
258      if (cls != null)
259         result = new PropertyNode(value, new PropertyDescriptor(property, cls), cls);
260      else
261         result = new PropertyNode(value);
262     
263      return result;
264   }
265   
266   /**
267    * Returns the revision string.
268    *
269    * @return           the revision
270    */
271   public String getRevision() {
272     return RevisionUtils.extract("$Revision: 1.6 $");
273   }
274
275   /**
276    * for testing only. if the first argument is a filename with ".xml"
277    * as extension it tries to generate an instance from the XML description
278    * and does a <code>toString()</code> of the generated object.
279    * Otherwise it loads the binary file, saves the XML representation in a
280    * file with the original filename appended by ".xml" and once again in a
281    * binary file with the original filename appended by ".exp".
282    *
283    * @param args       the commandline arguments
284    * @throws Exception if something goes wrong, e.g., file not found
285    */
286   public static void main(String[] args) throws Exception {
287      if (args.length > 0) {
288         // read xml and print
289         if (args[0].toLowerCase().endsWith(".xml")) {
290            System.out.println(new XMLExperiment().read(args[0]).toString());
291         }
292         // read binary and print generated XML
293         else {
294            // read
295            FileInputStream fi = new FileInputStream(args[0]);
296            ObjectInputStream oi = new ObjectInputStream(
297                                   new BufferedInputStream(fi));
298            Object o = oi.readObject();
299            oi.close();
300            // print to stdout
301            //new XMLExperiment().write(System.out, o);
302            // write to XML file
303            new XMLExperiment().write(new BufferedOutputStream(new FileOutputStream(args[0] + ".xml")), o);
304            // print to binary file
305            FileOutputStream fo = new FileOutputStream(args[0] + ".exp");
306            ObjectOutputStream oo = new ObjectOutputStream(
307                                   new BufferedOutputStream(fo));
308            oo.writeObject(o);
309            oo.close();
310         }
311      }
312   }
313}
Note: See TracBrowser for help on using the repository browser.