1
2
3
4
5
6
7
8
9
10
11
12
13 package org.gscg.gameleader.interactionlayer.experiment;
14
15 import java.io.IOException;
16 import java.net.URL;
17 import java.net.URLClassLoader;
18 import java.util.ArrayList;
19 import java.util.Calendar;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Properties;
25
26 import nl.tudelft.simulation.dsol.ModelInterface;
27 import nl.tudelft.simulation.dsol.experiment.Experiment;
28 import nl.tudelft.simulation.dsol.experiment.Replication;
29 import nl.tudelft.simulation.dsol.experiment.RunControl;
30 import nl.tudelft.simulation.dsol.experiment.TimeUnitInterface;
31 import nl.tudelft.simulation.dsol.experiment.Treatment;
32 import nl.tudelft.simulation.jstats.streams.Java2Random;
33 import nl.tudelft.simulation.jstats.streams.StreamInterface;
34 import nl.tudelft.simulation.language.io.URLResource;
35 import nl.tudelft.simulation.logger.Logger;
36
37 import org.jdom.Element;
38 import org.jdom.JDOMException;
39 import org.jdom.input.SAXBuilder;
40
41 /***
42 * The ExperimentParser parses xml-based experiments into their java objects
43 * <p>
44 * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
45 * Delft, the Netherlands. All rights reserved.
46 *
47 * See for project information <a href="http://www.simulation.tudelft.nl/">
48 * www.simulation.tudelft.nl </a>.
49 *
50 * The source code and binary code of this software is proprietary information
51 * of Delft University of Technology.
52 *
53 * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
54 * Jacobs </a>
55 * @version $Revision: 1.1 $ $Date: 2005/06/16 12:34:06 $
56 * @since 1.0.0 <br>
57 */
58 public class ExperimentParser
59 {
60
61 /*** builder the xerces parser with validation turned on */
62 private static SAXBuilder builder = new SAXBuilder(
63 "org.apache.xerces.parsers.SAXParser", true);
64 static
65 {
66
67 builder.setFeature("http://xml.org/sax/features/validation", true);
68 builder.setFeature("http://apache.org/xml/features/validation/schema",
69 true);
70
71 String xsd = URLResource.getResource("/xsd/experiment.xsd")
72 .toExternalForm();
73 builder
74 .setProperty(
75 "http://apache.org/xml/properties/schema/external-schemaLocation",
76 "http://www.simulation.tudelft.nl " + xsd);
77 }
78
79 /***
80 * constructs a new ExperimentParser This is a Utility Class.
81 */
82 protected ExperimentParser()
83 {
84
85 }
86
87 /***
88 * parses an experiment xml-file.
89 *
90 * @param element the experiment in the form of a jdom element
91 * @return Experiment the experiment
92 * @throws IOException whenever parsing fails
93 */
94 public static Experiment parseExperiment(final Element element)
95 throws IOException
96 {
97 if (element == null)
98 {
99 throw new IOException("experiment element=null");
100 }
101 try
102 {
103 ClassLoader loader = ExperimentParser.class.getClassLoader();
104 Element rootElement = element;
105 Experiment experiment = new Experiment();
106 if (rootElement.getChild("name") != null)
107 {
108 experiment.setProperty(Experiment.EXPERIMENT_NAME, rootElement
109 .getChildText("name"));
110 }
111 if (rootElement.getChild("analyst") != null)
112 {
113 experiment.setProperty(Experiment.EXPERIMENT_ANALYST,
114 rootElement.getChildText("analyst"));
115 }
116 Element modelElement = rootElement.getChild("model");
117
118 if (modelElement.getChild("class-path") != null)
119 {
120 List jarFiles = modelElement.getChild("class-path")
121 .getChildren("jar-file");
122 URL[] urls = new URL[jarFiles.size()];
123 int nr = 0;
124 for (Iterator i = jarFiles.iterator(); i.hasNext();)
125 {
126 Element child = (Element) i.next();
127 urls[nr] = URLResource.getResource(child.getValue());
128 nr++;
129 }
130 loader = new URLClassLoader(urls, loader);
131 }
132 Thread.currentThread().setContextClassLoader(loader);
133
134 experiment.setUrl(new URL(
135 "http://simulation.tudelft.nl/dsol-gaming"));
136
137 Class modelClass = Class.forName(modelElement
138 .getChildText("model-class"), true, loader);
139
140 ModelInterface model = (ModelInterface) modelClass.getConstructor(
141 null).newInstance(null);
142 experiment.setModel(model);
143 List treatmentList = rootElement.getChildren("treatment");
144 int number = 0;
145 ArrayList treatmentArray = new ArrayList();
146 for (Iterator i = treatmentList.iterator(); i.hasNext();)
147 {
148 Treatment treatment = ExperimentParser.parseTreatment(
149 (Element) i.next(), experiment, number);
150 number++;
151 treatmentArray.add(treatment);
152 }
153 Treatment[] treatments = new Treatment[treatmentArray.size()];
154 experiment.setTreatments((Treatment[]) treatmentArray
155 .toArray(treatments));
156 return experiment;
157 } catch (Exception exception)
158 {
159 Logger
160 .warning(ExperimentParser.class, "parseExperiment",
161 exception);
162 throw new IOException(exception.getMessage());
163 }
164 }
165
166 /***
167 * parses the dateTime
168 *
169 * @param value the string value in the yyyy-mm-ddThh:mm:ss format
170 * @return long the amount of milliseconds since 1970.
171 */
172 private static long parseDateTime(final String value)
173 {
174 Calendar calendar = Calendar.getInstance();
175 String concatDate = value.split("T")[0];
176 String concatTime = value.split("T")[1];
177 String[] date = concatDate.split("-");
178 String[] time = concatTime.split(":");
179 calendar.set(new Integer(date[0]).intValue(), new Integer(date[1])
180 .intValue() - 1, new Integer(date[2]).intValue(), new Integer(
181 time[0]).intValue(), new Integer(time[1]).intValue(),
182 new Integer(time[2]).intValue());
183 return calendar.getTimeInMillis();
184 }
185
186 /***
187 * parses a period
188 *
189 * @param element the xml-element representing the period
190 * @param treatmentTimeUnit the timeUnit of the treatment
191 * @return double the value in units defined by the treatment
192 * @throws Exception whenever the period.
193 */
194 private static double parsePeriod(final Element element,
195 final TimeUnitInterface treatmentTimeUnit) throws Exception
196 {
197 TimeUnitInterface timeUnit = ExperimentParser.parseTimeUnit(element
198 .getAttribute("unit").getValue());
199 double value = -1;
200 if (element.getText().equals("INF"))
201 {
202 value = Double.MAX_VALUE;
203 } else
204 {
205 value = new Double(element.getText()).doubleValue();
206 }
207 if (value < 0)
208 {
209 throw new JDOMException("parsePeriod: value = " + value
210 + " <0. simulator cannot schedule in past");
211 }
212 return timeUnit.getValue() * value / treatmentTimeUnit.getValue();
213 }
214
215 /***
216 * parses a replication
217 *
218 * @param element the JDOM element
219 * @param parent the RunControl
220 * @param number the number
221 * @return the replication
222 * @throws Exception on failure
223 */
224 private static Replication parseReplication(final Element element,
225 final RunControl parent, final int number) throws Exception
226 {
227 Replication replication = new Replication(parent, number);
228 if (element.getAttribute("description") != null)
229 {
230 replication.setDescription(element.getAttribute("description")
231 .getValue());
232 }
233 Map streams = new HashMap();
234 List streamElements = element.getChildren("stream");
235 for (Iterator i = streamElements.iterator(); i.hasNext();)
236 {
237 Element streamElement = (Element) i.next();
238 long seed = new Long(streamElement.getAttributeValue("seed"))
239 .longValue();
240 StreamInterface stream = new Java2Random(seed);
241 streams.put(streamElement.getAttributeValue("name"), stream);
242 }
243 replication.setStreams(streams);
244 return replication;
245 }
246
247 /***
248 * parses proprties to treatments
249 *
250 * @param element the element
251 * @return Properties
252 */
253 private static Properties parseProperties(final Element element)
254 {
255 Properties result = new Properties();
256 List children = element.getChildren("property");
257 for (Iterator i = children.iterator(); i.hasNext();)
258 {
259 Element child = (Element) i.next();
260 String key = child.getAttributeValue("key");
261 String value = child.getAttributeValue("value");
262 result.put(key, value);
263 }
264 return result;
265 }
266
267 /***
268 * parses the runcontrol
269 *
270 * @param element the element
271 * @param parent the treatment
272 * @return RunControl result
273 * @throws Exception on failure
274 */
275 private static RunControl parseRunControl(final Element element,
276 final Treatment parent) throws Exception
277 {
278 RunControl runControl = new RunControl(parent);
279 if (element.getChild("warmupPeriod") != null)
280 {
281 runControl.setWarmupPeriod(ExperimentParser.parsePeriod(element
282 .getChild("warmupPeriod"), parent.getTimeUnit()));
283 }
284 if (element.getChild("runLength") != null)
285 {
286 runControl.setRunLength(ExperimentParser.parsePeriod(element
287 .getChild("runLength"), parent.getTimeUnit()));
288 }
289 List replicationElements = element.getChildren("replication");
290 ArrayList replicationArray = new ArrayList();
291 int number = 0;
292 for (Iterator i = replicationElements.iterator(); i.hasNext();)
293 {
294 replicationArray.add(ExperimentParser.parseReplication((Element) i
295 .next(), runControl, number));
296 number++;
297 }
298 Replication[] replications = new Replication[replicationArray.size()];
299 runControl.setReplications((Replication[]) replicationArray
300 .toArray(replications));
301 return runControl;
302 }
303
304 /***
305 * parses a timeUnit
306 *
307 * @param name the name
308 * @return TimeUnitInterface result
309 * @throws Exception on failure
310 */
311 private static TimeUnitInterface parseTimeUnit(final String name)
312 throws Exception
313 {
314 if (name.equals("DAY"))
315 {
316 return TimeUnitInterface.DAY;
317 }
318 if (name.equals("HOUR"))
319 {
320 return TimeUnitInterface.HOUR;
321 }
322 if (name.equals("MILLISECOND"))
323 {
324 return TimeUnitInterface.MILLISECOND;
325 }
326 if (name.equals("MINUTE"))
327 {
328 return TimeUnitInterface.MINUTE;
329 }
330 if (name.equals("SECOND"))
331 {
332 return TimeUnitInterface.SECOND;
333 }
334 if (name.equals("WEEK"))
335 {
336 return TimeUnitInterface.WEEK;
337 }
338 if (name.equals("UNIT"))
339 {
340 return TimeUnitInterface.UNIT;
341 }
342 throw new Exception("parseTimeUnit.. unknown argument: " + name);
343 }
344
345 /***
346 * parses the treatment
347 *
348 * @param element the xml-element
349 * @param parent parent
350 * @param number the number
351 * @return Treatment
352 * @throws Exception on failure
353 */
354 private static Treatment parseTreatment(final Element element,
355 final Experiment parent, final int number) throws Exception
356 {
357 Treatment treatment = new Treatment(parent, number);
358 treatment.setTimeUnit(ExperimentParser.parseTimeUnit(element
359 .getChildText("timeUnit")));
360 if (element.getChild("startTime") != null)
361 {
362 treatment.setStartTime(ExperimentParser.parseDateTime(element
363 .getChildText("startTime")));
364 }
365 treatment.setRunControl(ExperimentParser.parseRunControl(element
366 .getChild("runControl"), treatment));
367 if (element.getChild("properties") != null)
368 {
369 treatment.setProperties(ExperimentParser.parseProperties(element
370 .getChild("properties")));
371 }
372 return treatment;
373 }
374 }