Package org.squirrelframework.foundation.fsm.impl

Source Code of org.squirrelframework.foundation.fsm.impl.SCXMLVisitorImpl

package org.squirrelframework.foundation.fsm.impl;

import org.squirrelframework.foundation.fsm.*;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.io.StringWriter;

/**
* Use visitor pattern to export SCXML definition.
*
* @author Henry.He
*
* @param <T> state machine type
* @param <S> state type
* @param <E> event type
* @param <C> context type
*/
class SCXMLVisitorImpl extends AbstractVisitor implements SCXMLVisitor {
   
    @Override
    public void visitOnEntry(StateMachine<?, ?, ?, ?> visitable) {
        writeLine("<scxml initial=" + quoteName(visitable.getInitialState().toString()) + " version=\"1.0\" " +
                "xmlns=\"http://www.w3.org/2005/07/scxml\" xmlns:sqrl=\"http://squirrelframework.org/squirrel\">");
        writeLine("<sqrl:fsm "+visitable.getDescription()+" />");
    }

    @Override
    public void visitOnExit(StateMachine<?, ?, ?, ?> visitable) {
        writeLine("</scxml>");
    }

    @Override
    public void visitOnEntry(ImmutableState<?, ?, ?, ?> visitable) {
        if(visitable.isParallelState()) {
            writeLine("<parallel id= " + quoteName(visitable.toString()) + ">");
        } else if(visitable.isFinalState()) {
            writeLine("<final id= " + quoteName(visitable.toString()) + ">");
        } else {
            StringBuilder builder = new StringBuilder("<state id= ");
            builder.append(quoteName(visitable.toString()));
            if(visitable.getInitialState()!=null) {
                builder.append(" initial= ").append(quoteName(visitable.getInitialState().toString()));
            }
            builder.append(">");
            writeLine(builder.toString());
        }
        if(!visitable.getEntryActions().isEmpty()) {
            writeLine("<onentry>");
            for(Action<?, ?, ?, ?> entryAction : visitable.getEntryActions()) {
                writeAction(entryAction);
            }
            writeLine("</onentry>");
        }
        if(visitable.getHistoryType()!=HistoryType.NONE) {
            writeLine("<history type= "+ quoteName(visitable.getHistoryType().name().toLowerCase())+"/>");
        }
    }

    @Override
    public void visitOnExit(ImmutableState<?, ?, ?, ?> visitable) {
        if(!visitable.getExitActions().isEmpty()) {
            writeLine("<onexit>");
            for(Action<?, ?, ?, ?> exitAction : visitable.getExitActions()) {
                writeAction(exitAction);
            }
            writeLine("</onexit>");
        }
        if(visitable.isParallelState())
            writeLine("</parallel>");
        else if(visitable.isFinalState())
            writeLine("</final>");
        else
            writeLine("</state>");
    }

    @Override
    public void visitOnEntry(ImmutableTransition<?, ?, ?, ?> visitable) {
        writeLine("<transition event="
                + quoteName(visitable.getEvent().toString()) + " sqrl:priority="
                + quoteName(Integer.toString(visitable.getPriority())) + " sqrl:type="
                + quoteName(visitable.getType().toString()) + " target="
                + quoteName(visitable.getTargetState().toString()) + " cond="
                + quoteName(visitable.getCondition().toString())+">");
        for(Action<?, ?, ?, ?> action : visitable.getActions()) {
            writeAction(action);
        }
    }

    @Override
    public void visitOnExit(ImmutableTransition<?, ?, ?, ?> visitable) {
        writeLine("</transition>");
    }
   
    private void writeAction(final Action<?, ?, ?, ?> action) {
        if(isExternalAction(action))
            writeLine("<sqrl:action content="+quoteName(action.toString())+"/>");
    }
   
    private boolean isExternalAction(final Action<?, ?, ?, ?> action) {
        return action.name().startsWith("__")==false;
    }

    @Override
    public String getScxml(boolean beautifyXml) {
        return beautifyXml ? beautify(buffer.toString()) : buffer.toString();
    }
   
    @Override
    public void convertSCXMLFile(final String filename, boolean beautifyXml) {
        saveFile(filename + ".scxml", getScxml(beautifyXml));
    }
   
    private String beautify(String unformattedXml) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(unformattedXml));
            Document doc = db.parse(is);
           
            DOMImplementationRegistry domReg = DOMImplementationRegistry.newInstance();
            DOMImplementationLS lsImpl = (DOMImplementationLS) domReg.getDOMImplementation("LS");
            LSSerializer lsSerializer = lsImpl.createLSSerializer();
            lsSerializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
            LSOutput output = lsImpl.createLSOutput();
            output.setEncoding("UTF-8");
           
            StringWriter destination = new StringWriter();
            output.setCharacterStream(destination);
            lsSerializer.write(doc, output);
            return destination.toString();
        } catch (Exception e) {
            // format failed, return unformatted xml
            return unformattedXml;
        }
    }
}
TOP

Related Classes of org.squirrelframework.foundation.fsm.impl.SCXMLVisitorImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.