Java tutorial
/* * TURNUS, the co-exploration framework * * Copyright (C) 2014 EPFL SCI STI MM * * This file is part of TURNUS. * * TURNUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * TURNUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with TURNUS. If not, see <http://www.gnu.org/licenses/>. * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining it * with Eclipse (or a modified version of Eclipse or an Eclipse plugin or * an Eclipse library), containing parts covered by the terms of the * Eclipse Public License (EPL), the licensors of this Program grant you * additional permission to convey the resulting work. Corresponding Source * for a non-source form of such a combination shall include the source code * for the parts of Eclipse libraries used as well as that of the covered work. * */ package co.turnus.trace.io; import static co.turnus.trace.io.XmlTraceMarkup.ATTRIBUTE; import static co.turnus.trace.io.XmlTraceMarkup.ATTRIBUTE_NAME; import static co.turnus.trace.io.XmlTraceMarkup.COUNT; import static co.turnus.trace.io.XmlTraceMarkup.DEPENDENCY; import static co.turnus.trace.io.XmlTraceMarkup.DEPENDENCY_KIND; import static co.turnus.trace.io.XmlTraceMarkup.DEPENDENCY_SOURCE; import static co.turnus.trace.io.XmlTraceMarkup.DEPENDENCY_TARGET; import static co.turnus.trace.io.XmlTraceMarkup.DIRECTION; import static co.turnus.trace.io.XmlTraceMarkup.GUARD; import static co.turnus.trace.io.XmlTraceMarkup.PORT; import static co.turnus.trace.io.XmlTraceMarkup.SOURCE_PORT; import static co.turnus.trace.io.XmlTraceMarkup.STEP; import static co.turnus.trace.io.XmlTraceMarkup.STEP_ACTION; import static co.turnus.trace.io.XmlTraceMarkup.STEP_ACTOR; import static co.turnus.trace.io.XmlTraceMarkup.STEP_ACTOR_CLASS; import static co.turnus.trace.io.XmlTraceMarkup.STEP_FIRING; import static co.turnus.trace.io.XmlTraceMarkup.TARGET_PORT; import static co.turnus.trace.io.XmlTraceMarkup.TRACE; import static co.turnus.trace.io.XmlTraceMarkup.VARIABLE; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.events.XMLEvent; import org.apache.commons.compress.compressors.CompressorStreamFactory; import co.turnus.TurnusException; import co.turnus.TurnusRuntimeException; import co.turnus.TurnusExtension; import co.turnus.generic.AbstractAttributable; import co.turnus.generic.Attributable; import co.turnus.util.ProgressTheadPrinter; import co.turnus.util.TurnusLogger; import co.turnus.util.TurnusUtils; import co.turnus.trace.Dependency.Direction; import co.turnus.trace.Dependency.Kind; import co.turnus.trace.PersistentTrace; import co.turnus.trace.Trace; import co.turnus.trace.TraceFactory; import co.turnus.trace.TraceProject; public class XmlTraceReader { private class TempDependency extends AbstractAttributable { private Integer count; private Direction direction; private String guard; private Kind kind; private String port; private Long sourceId; private String sourcePort; private Long targetId; private String targetPort; private String variable; private void clear() { attributesMap = null; direction = null; guard = null; kind = null; port = null; sourceId = null; targetId = null; sourcePort = null; targetPort = null; variable = null; count = null; } private Map<String, Object> getAttributesMap() { return attributesMap; } } private class TempStep extends AbstractAttributable { private String action; private String actor; private String actorClass; private Long id; private void clear() { attributesMap = null; id = null; actor = null; actorClass = null; action = null; } private Map<String, Object> getAttributesMap() { return attributesMap; } } private Attributable currentAttributable; private TraceFactory factory; private ProgressTheadPrinter progressPrinter; private XMLStreamReader reader; private TempDependency tempDep; private TempStep tempStep; private Trace trace; public XmlTraceReader(File file, TraceFactory factory) { try { XMLInputFactory inputFactory = XMLInputFactory.newInstance(); String extension = TurnusUtils.getExtension(file); if (!extension.equals(TurnusExtension.TRACE) && !extension.equals(TurnusExtension.TRACE_COMPRESSED)) { throw new TurnusRuntimeException("Trace file reader: unsupported extension"); } InputStream stream = new BufferedInputStream(new FileInputStream(file)); if (extension.equals(TurnusExtension.TRACE_COMPRESSED)) { stream = new CompressorStreamFactory().createCompressorInputStream(CompressorStreamFactory.GZIP, stream); } reader = inputFactory.createXMLStreamReader(stream); } catch (Exception e) { throw new TurnusRuntimeException("Error initializing the trace reader", e.getCause()); } this.factory = factory; tempDep = new TempDependency(); tempStep = new TempStep(); } public XmlTraceReader(TraceProject project, TraceFactory factory) { this(project.getTraceFile(), factory); try { long steps = project.getProfilingData().getFirings(); progressPrinter = new ProgressTheadPrinter("Trace file loading", steps); } catch (Exception e) { TurnusLogger.warning("Error while reading profiling data: the lenght of the trace is unknown"); progressPrinter = null; } } private void endElement(QName name) { switch (name.toString()) { case TRACE: currentAttributable = null; break; case STEP: factory.addStep(tempStep.id, tempStep.actor, tempStep.action, tempStep.actorClass, tempStep.getAttributesMap()); currentAttributable = trace; break; case DEPENDENCY: switch (tempDep.kind) { case FSM: factory.addDependencyFsm(tempDep.sourceId, tempDep.targetId, tempDep.getAttributesMap()); break; case GUARD: factory.addDependencyGuard(tempDep.sourceId, tempDep.targetId, tempDep.guard, tempDep.direction, tempDep.getAttributesMap()); break; case PORT: factory.addDependencyPort(tempDep.sourceId, tempDep.targetId, tempDep.port, tempDep.direction, tempDep.getAttributesMap()); break; case STATEVAR: factory.addDependencyStateVar(tempDep.sourceId, tempDep.targetId, tempDep.variable, tempDep.direction, tempDep.getAttributesMap()); break; case TOKENS: factory.addDependencyTokens(tempDep.sourceId, tempDep.targetId, tempDep.sourcePort, tempDep.targetPort, tempDep.count, tempDep.getAttributesMap()); break; default: break; } currentAttributable = trace; break; default: break; } } private Object parseAttribute() { // TODO Auto-generated method stub return null; } public Trace read() { if (progressPrinter != null) { progressPrinter.start(); } trace = factory.newTrace(); try { while (reader.hasNext()) { reader.next(); switch (reader.getEventType()) { case XMLEvent.START_ELEMENT: startElement(reader.getName()); break; case XMLEvent.END_ELEMENT: endElement(reader.getName()); break; default: break; } } } catch (Exception e) { throw new TurnusRuntimeException("Error parsing the trace file", e.getCause()); } if (trace instanceof PersistentTrace) { try { ((PersistentTrace) trace).commit(); } catch (TurnusException e) { TurnusLogger.warning("Error while finalising the trace writing", e.getCause()); } } if (progressPrinter != null) { progressPrinter.finish(); try { progressPrinter.join(); } catch (InterruptedException e) { } } return trace; } private void startElement(QName name) { switch (name.toString()) { case TRACE: currentAttributable = trace; break; case STEP: tempStep.clear(); tempStep.id = Long.parseLong(reader.getAttributeValue("", STEP_FIRING)); tempStep.actor = reader.getAttributeValue("", STEP_ACTOR); tempStep.action = reader.getAttributeValue("", STEP_ACTION); tempStep.actorClass = reader.getAttributeValue("", STEP_ACTOR_CLASS); currentAttributable = tempStep; if (progressPrinter != null) { progressPrinter.increment(); } break; case DEPENDENCY: tempDep.clear(); tempDep.sourceId = Long.parseLong(reader.getAttributeValue("", DEPENDENCY_SOURCE)); tempDep.targetId = Long.parseLong(reader.getAttributeValue("", DEPENDENCY_TARGET)); tempDep.kind = Kind.get(reader.getAttributeValue("", DEPENDENCY_KIND)); switch (tempDep.kind) { case GUARD: tempDep.guard = reader.getAttributeValue("", GUARD); tempDep.direction = Direction.get(reader.getAttributeValue("", DIRECTION)); break; case STATEVAR: tempDep.variable = reader.getAttributeValue("", VARIABLE); tempDep.direction = Direction.get(reader.getAttributeValue("", DIRECTION)); break; case PORT: tempDep.port = reader.getAttributeValue("", PORT); tempDep.direction = Direction.get(reader.getAttributeValue("", DIRECTION)); break; case TOKENS: tempDep.sourcePort = reader.getAttributeValue("", SOURCE_PORT); tempDep.targetPort = reader.getAttributeValue("", TARGET_PORT); tempDep.count = Integer.parseInt(reader.getAttributeValue("", COUNT)); break; default: break; } currentAttributable = tempDep; break; case ATTRIBUTE: String attName = reader.getAttributeValue("", ATTRIBUTE_NAME); Object attValue = parseAttribute(); currentAttributable.setAttribute(attName, attValue); break; default: break; } } }