org.shaf.server.log.XesWriter.java Source code

Java tutorial

Introduction

Here is the source code for org.shaf.server.log.XesWriter.java

Source

/**
 * Copyright 2014-2015 SHAF-WORK
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.shaf.server.log;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Stack;

import com.google.common.base.Strings;

/**
 * The log-file writer in XES format.
 * 
 * @author Mykola Galushka
 */
public class XesWriter extends FileWriter {

    /**
     * The opened tags stack.
     */
    private Stack<String> tags;

    /**
     * The random access file for populating a log.
     */
    private final RandomAccessFile raf;

    /**
     * Constructs a new log-file writer in XES format.
     * 
     * @param path
     *            the path to writing log file.
     * @param overwrite
     *            the flag to overwrite log file.
     * @throws IOException
     *             if the writer initialization error occurs.
     */
    public XesWriter(final String path, final boolean overwrite) throws IOException {
        super(path, overwrite);

        this.tags = new Stack<>();
        this.raf = new RandomAccessFile(path, "rw");

        this.writeStartDocument();

        this.writeStartElement("log", new String[][] { { "xes.version", "1.1" },
                { "xes.features", "arbitrary-depth" }, { "xmlns", "http://www.xes-standard.org/" } });

        this.writeStartElement("extension", new String[][] { { "name", "Concept" }, { "prefix", "concept" },
                { "uri", "http://www.xes-standard.org/concept.xesext" } });
        this.writeEndElement();

        this.writeStartElement("extension", new String[][] { { "name", "Time" }, { "prefix", "time" },
                { "uri", "http://www.xes-standard.org/time.xesext" } });
        this.writeEndElement();

        this.writeStartElement("global", new String[][] { { "scope", "trace" } });
        this.writeStartElement("string",
                new String[][] { { "key", "concept:name" }, { "value", "Server Process Log" } });
        this.writeEndElement();
        this.writeEndElement();

        this.writeEndDocument();
    }

    /**
     * Constructs a new log-file writer in XES format.
     * 
     * @param path
     *            the path to writing log file.
     * @throws IOException
     *             if the writer initialization error occurs.
     */
    public XesWriter(final String path) throws IOException {
        this(path, true);
    }

    /**
     * Writes the start trace to XES log-file.
     */
    @Override
    public void startTrace(final LogTrace trace) throws IOException {
        this.raf.seek(this.raf.length() - "</log>".length());

        this.writeStartElement("trace");

        this.writeStartElement("int",
                new String[][] { { "key", "concept:id" }, { "value", String.valueOf(trace.getId()) } });
        this.writeEndElement();

        this.writeStartElement("string",
                new String[][] { { "key", "concept:info" }, { "value", trace.getInfo() } });
        this.writeEndElement();
    }

    /**
     * Writes the start event to XES log-file.
     */
    @Override
    public void startEvent(final LogEvent event) throws IOException {
        this.writeStartElement("event");

        this.writeStartElement("string",
                new String[][] { { "key", "concept:name" }, { "value", event.getProcessName() } });
        this.writeEndElement();

        this.writeStartElement("string",
                new String[][] { { "key", "org:resource" }, { "value", event.getProcessResource() } });
        this.writeEndElement();

        this.writeStartElement("date",
                new String[][] { { "key", "time:timestamp" }, { "value", super.format(event.getTimestamp()) } });
        this.writeEndElement();

        this.writeStartElement("string",
                new String[][] { { "key", "concept:info" }, { "value", event.getInfo() } });
        this.writeEndElement();

        this.writeStartElement("string",
                new String[][] { { "key", "lifecycle:transition" }, { "value", "SCHEDULE" } });
        this.writeEndElement();

        this.writeEndElement();
    }

    /**
     * Writes the end event to XES log-file.
     */
    @Override
    public void endEvent(final LogEvent event) throws IOException {
        this.writeStartElement("event");

        this.writeStartElement("string",
                new String[][] { { "key", "concept:name" }, { "value", event.getProcessName() } });
        this.writeEndElement();

        this.writeStartElement("string",
                new String[][] { { "key", "org:resource" }, { "value", event.getProcessResource() } });
        this.writeEndElement();

        this.writeStartElement("date",
                new String[][] { { "key", "time:timestamp" }, { "value", super.format(event.getTimestamp()) } });
        this.writeEndElement();

        this.writeStartElement("string",
                new String[][] { { "key", "lifecycle:transition" }, { "value", "COMPLETE" } });
        this.writeEndElement();

        this.writeEndElement();
    }

    /**
     * Writes the end trace to XES log-file.
     */
    public void endTrace(final LogTrace trace) throws IOException {
        this.writeEndElement();
        this.writeEndDocument();
    }

    /**
     * Closes the XES file writer.
     */
    @Override
    public void close() throws IOException {
        if (this.raf != null) {
            this.raf.close();
        }
    }

    // ========================================================================
    // The service methods
    // ========================================================================

    /**
     * Writes the start of the XES document.
     * 
     * @throws IOException
     *             if an I/O error occurs during writing process.
     */
    private final void writeStartDocument() throws IOException {
        this.raf.writeBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + System.lineSeparator());
    }

    /**
     * Writes the start of the XES element.
     * 
     * @param tag
     *            the element tag name.
     * @param attributes
     *            the element attributes.
     * @throws IOException
     *             if an I/O error occurs during writing process.
     */
    private final void writeStartElement(final String tag, final String[][] attributes) throws IOException {
        this.raf.writeBytes(Strings.repeat("   ", this.tags.size()));
        this.tags.push(tag);
        this.raf.writeBytes("<" + tag);
        if (attributes != null) {
            for (String[] attribute : attributes) {
                this.raf.writeBytes(" " + attribute[0] + "=\"" + attribute[1] + "\"");
            }
        }
        this.raf.writeBytes(">" + System.lineSeparator());
    }

    /**
     * Writes the start of the XES element.
     * 
     * @param tag
     *            the element tag name.
     * @throws IOException
     *             if an I/O error occurs during writing process.
     */
    private final void writeStartElement(final String tag) throws IOException {
        this.writeStartElement(tag, null);
    }

    /**
     * Writes the end of the XES element.
     * 
     * @param tag
     *            the element tag name.
     * @throws IOException
     *             if an I/O error occurs during writing process.
     */
    private final void writeEndElement() throws IOException {
        String tag = this.tags.pop();
        this.raf.writeBytes(Strings.repeat("   ", this.tags.size()));
        this.raf.writeBytes("</" + tag + ">" + System.lineSeparator());
    }

    /**
     * Writes the end of the XES document.
     * 
     * @throws IOException
     *             if an I/O error occurs during writing process.
     */
    private final void writeEndDocument() throws IOException {
        this.raf.writeBytes("</log>");
    }

}