~ubuntu-branches/ubuntu/precise/weka/precise

« back to all changes in this revision

Viewing changes to weka/experiment/xml/XMLExperiment.java

  • Committer: Bazaar Package Importer
  • Author(s): Soeren Sonnenburg
  • Date: 2008-02-24 09:18:45 UTC
  • Revision ID: james.westby@ubuntu.com-20080224091845-1l8zy6fm6xipbzsr
Tags: upstream-3.5.7+tut1
ImportĀ upstreamĀ versionĀ 3.5.7+tut1

Show diffs side-by-side

added added

removed removed

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