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

Java tutorial

Introduction

Here is the source code for co.turnus.trace.io.XmlTraceStreamWriter.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.ENTRY;
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.TYPE_BOOLEAN;
import static co.turnus.trace.io.XmlTraceMarkup.TYPE_INTEGER;
import static co.turnus.trace.io.XmlTraceMarkup.TYPE_LIST;
import static co.turnus.trace.io.XmlTraceMarkup.TYPE_MAP;
import static co.turnus.trace.io.XmlTraceMarkup.TYPE_REAL;
import static co.turnus.trace.io.XmlTraceMarkup.TYPE_SET;
import static co.turnus.trace.io.XmlTraceMarkup.TYPE_STRING;
import static co.turnus.trace.io.XmlTraceMarkup.VALUE;
import static co.turnus.trace.io.XmlTraceMarkup.VARIABLE;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javanet.staxutils.IndentingXMLStreamWriter;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.apache.commons.compress.compressors.CompressorStreamFactory;

import co.turnus.TurnusExtension;
import co.turnus.TurnusRuntimeException;
import co.turnus.generic.Attributable;
import co.turnus.util.TurnusUtils;
import co.turnus.trace.Dependency;
import co.turnus.trace.Dependency.Kind;
import co.turnus.trace.Step;

import com.google.common.collect.Iterables;

public class XmlTraceStreamWriter {

    private XMLStreamWriter writer;
    private OutputStream stream;
    private boolean compressedXml;

    public XmlTraceStreamWriter(File file) {
        switch (TurnusUtils.getExtension(file)) {
        case TurnusExtension.TRACE_COMPRESSED:
            compressedXml = true;
            break;
        case TurnusExtension.TRACE:
            compressedXml = false;
            break;
        default:
            throw new TurnusRuntimeException("Trace file writer: unsupported file extension");
        }

        try {
            stream = new FileOutputStream(file);
            if (compressedXml) {
                stream = new CompressorStreamFactory().createCompressorOutputStream(CompressorStreamFactory.GZIP,
                        stream);
            }
            stream = new BufferedOutputStream(stream);
        } catch (Exception e) {
            throw new TurnusRuntimeException("Error opening the trace file output stream", e.getCause());
        }
    }

    public void close() {
        try {
            writeEndDocument();
            writer.flush();
            writer.close();
            stream.close();
        } catch (Exception e) {
            throw new TurnusRuntimeException("Trace Writer Error: " + e.getLocalizedMessage(), e.getCause());
        }
    }

    private boolean hasEmptyAttributes(Attributable attributable) {
        return Iterables.isEmpty(attributable.getKeyAttributes());
    }

    public void open() {
        try {
            XMLOutputFactory factory = XMLOutputFactory.newInstance();
            writer = factory.createXMLStreamWriter(stream);
            if (!compressedXml) {
                writer = new IndentingXMLStreamWriter(writer);
            }
            writeStartDocument();
        } catch (XMLStreamException e) {
            throw new TurnusRuntimeException("Error opening the trace stream writer", e.getCause());
        }
    }

    public void write(Dependency dep) {
        try {
            boolean noAttributes = hasEmptyAttributes(dep);

            if (noAttributes) {
                writer.writeEmptyElement(DEPENDENCY);
            } else {
                writer.writeStartElement(DEPENDENCY);
            }

            writer.writeAttribute(DEPENDENCY_SOURCE, Long.toString(dep.getSource().getID()));
            writer.writeAttribute(DEPENDENCY_TARGET, Long.toString(dep.getTarget().getID()));

            Kind kind = dep.getKind();
            writer.writeAttribute(DEPENDENCY_KIND, dep.getKind().literal());
            switch (kind) {
            case FSM: {
                break;
            }
            case TOKENS: {
                writer.writeAttribute(SOURCE_PORT, dep.getSourcePort());
                writer.writeAttribute(TARGET_PORT, dep.getTargetPort());
                writer.writeAttribute(COUNT, Integer.toString(dep.getCount()));
                break;
            }
            case STATEVAR: {
                writer.writeAttribute(VARIABLE, dep.getVariable());
                writer.writeAttribute(DIRECTION, dep.getDirection().literal());
                break;
            }
            case PORT: {
                writer.writeAttribute(PORT, dep.getPort());
                writer.writeAttribute(DIRECTION, dep.getDirection().literal());
                break;
            }
            case GUARD: {
                writer.writeAttribute(GUARD, dep.getGuard());
                writer.writeAttribute(DIRECTION, dep.getDirection().literal());
                break;
            }
            default:
                throw new TurnusRuntimeException("Unsupported Dependence kind " + dep);
            }

            if (!noAttributes) {
                writeAttributes(dep);
                writer.writeEndElement();
            }

        } catch (XMLStreamException e) {
            throw new TurnusRuntimeException("Trace Writer Error: " + e.getLocalizedMessage(), e.getCause());
        }

    }

    public void write(Step step) {
        try {

            boolean noAttributes = hasEmptyAttributes(step);
            if (noAttributes) {
                writer.writeEmptyElement(STEP);
            } else {
                writer.writeStartElement(STEP);
            }

            writer.writeAttribute(STEP_FIRING, Long.toString(step.getID()));
            writer.writeAttribute(STEP_ACTOR, step.getActor());
            writer.writeAttribute(STEP_ACTION, step.getAction());
            writer.writeAttribute(STEP_ACTOR_CLASS, step.getActorClass());

            if (!noAttributes) {
                writeAttributes(step);
                writer.writeEndElement();
            }

        } catch (XMLStreamException e) {
            throw new TurnusRuntimeException("Trace Writer Error: " + e.getLocalizedMessage(), e.getCause());
        }
    }

    public void writeAttribute(String name, Object value) {
        try {
            writer.writeStartElement(ATTRIBUTE);
            writer.writeAttribute(ATTRIBUTE_NAME, name);
            writeObject(value);
            writer.writeEndElement();
        } catch (XMLStreamException e) {
            throw new TurnusRuntimeException("Trace Writer Error: " + e.getLocalizedMessage(), e.getCause());
        }
    }

    public void writeAttributes(Attributable attributable) {
        for (String key : attributable.getKeyAttributes()) {
            writeAttribute(key, attributable.getAttribute(key));
        }
    }

    private void writeEndDocument() {
        try {
            // </trace>
            writer.writeEndElement();
            // close the document
            writer.writeEndDocument();

        } catch (Exception e) {

            throw new TurnusRuntimeException("Trace Writer Error: " + e.getLocalizedMessage(), e.getCause());
        }
    }

    @SuppressWarnings("rawtypes")
    private void writeObject(Object v) {
        try {
            if (v instanceof Boolean) {
                writer.writeEmptyElement(TYPE_BOOLEAN);
                writer.writeAttribute(VALUE, Boolean.toString((Boolean) v));
            } else if (v instanceof Byte || v instanceof Short || v instanceof Integer) {
                writer.writeEmptyElement(TYPE_INTEGER);
                writer.writeAttribute(VALUE, Integer.toString((Integer) v));
            } else if (v instanceof Long) {
                writer.writeEmptyElement(TYPE_INTEGER);
                writer.writeAttribute(VALUE, Long.toString((Long) v));
            } else if (v instanceof Float) {
                writer.writeEmptyElement(TYPE_REAL);
                writer.writeAttribute(VALUE, Float.toString((Float) v));
            } else if (v instanceof Double) {
                writer.writeEmptyElement(TYPE_REAL);
                writer.writeAttribute(VALUE, Double.toString((Double) v));
            } else if (v instanceof String) {
                writer.writeEmptyElement(TYPE_STRING);
                writer.writeAttribute(VALUE, (String) v);
            } else if (v instanceof List) {
                writer.writeStartElement(TYPE_LIST);
                for (Object o : (List) v) {
                    writeObject(o);
                }
                writer.writeEndElement();
            } else if (v instanceof Set) {
                writer.writeStartElement(TYPE_SET);
                for (Object o : (Set) v) {
                    writeObject(o);
                }
                writer.writeEndElement();
            } else if (v instanceof Map) {
                writer.writeStartElement(TYPE_MAP);
                for (Object k : ((Map) v).keySet()) {
                    writer.writeStartElement(ENTRY);
                    writeObject(k);
                    writeObject(((Map) v).get(k));
                    writer.writeEndElement();
                }
                writer.writeEndElement();
            }
        } catch (XMLStreamException e) {
            throw new TurnusRuntimeException("Trace Writer Error: " + e.getLocalizedMessage(), e.getCause());
        }

    }

    private void writeStartDocument() {
        try {
            String date = new SimpleDateFormat("yyyy.MM.dd, HH:mm:ss").format(new Date());

            writer.writeStartDocument();
            writer.writeComment("Trace exported the " + date);
            writer.writeStartElement(TRACE);
        } catch (XMLStreamException e) {
            throw new TurnusRuntimeException("Trace Writer Error: " + e.getLocalizedMessage(), e.getCause());
        }
    }

}