co.turnus.trace.io.XmlTraceReader.java Source code

Java tutorial

Introduction

Here is the source code for co.turnus.trace.io.XmlTraceReader.java

Source

/* 
 * 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;
        }

    }

}