View Javadoc

1   /*
2    * @(#)ExperimentParser.java Aug 18, 2003
3    * 
4    * Copyright (c) 2003-2005 Delft University of Technology, Jaffalaan 5, 2628 BX
5    * Delft, the Netherlands. All rights reserved.
6    * 
7    * See for project information <a href="http://www.simulation.tudelft.nl/">
8    * www.simulation.tudelft.nl </a>.
9    * 
10   * The source code and binary code of this software is proprietary information
11   * of Delft University of Technology.
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  		//turns on Schema Validation with Xerces
67  		builder.setFeature("http://xml.org/sax/features/validation", true);
68  		builder.setFeature("http://apache.org/xml/features/validation/schema",
69  				true);
70  		//Let's find the XSD file
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  		//A utility class should not be instantiated
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 }