# HG changeset patch
# User František Kučera <franta-hg@frantovo.cz>
# Date 1402836649 -7200
# Node ID 058c1c39251e45ecfe73bf8b13ee24102db4ebb8
# Parent  f1e91d4ac35c6d5533fcd69a050d76d5fef13c3d
ouptup modules framework + XML (echo) output module

diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLI.java
--- a/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLI.java	Sat Jun 14 22:56:51 2014 +0200
+++ b/java/alt2xml-cli/src/cz/frantovo/alt2xml/cli/CLI.java	Sun Jun 15 14:50:49 2014 +0200
@@ -17,16 +17,19 @@
  */
 package cz.frantovo.alt2xml.cli;
 
-import cz.frantovo.alt2xml.out.EchoContentHandler;
+import cz.frantovo.alt2xml.out.Action;
+import cz.frantovo.alt2xml.out.ActionContext;
+import cz.frantovo.alt2xml.out.ActionFactory;
 import java.io.File;
 import java.io.OutputStream;
 import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ServiceLoader;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.xml.parsers.SAXParser;
 import javax.xml.parsers.SAXParserFactory;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamWriter;
 import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.helpers.DefaultHandler;
 
@@ -43,37 +46,48 @@
 
 		try {
 			File vstup = new File(args[0]);
-			OutputStream výstup = System.out;
+			String actionCode = args[1];
+			OutputStream outputStream = System.out;
 
-			/**
-			 * Serializujeme data do XML.
-			 * To normálně vůbec není potřeba – data se do tvaru proudu obsahujícího ostré závorky
-			 * vůbec nedostanou – zpracováváme události (volání javovských metod – začátky a konce
-			 * elementů atd.)
-			 * a z nich např. deserializujeme nějaké naše objekty, provádíme nějaké akce, nebo třeba
-			 * stavíme DOM.
-			 */
-			XMLOutputFactory xmlOutputFactory = XMLOutputFactory.newFactory();
-			XMLStreamWriter w = xmlOutputFactory.createXMLStreamWriter(výstup);
-			DefaultHandler h = new EchoContentHandler(w);
+			Map<String, ActionFactory> actionFactories = new HashMap<>();
 
-			SAXParserFactory t = SAXParserFactory.newInstance();
-			SAXParser p = t.newSAXParser();
-
-			if (h instanceof LexicalHandler
-					// TODO: add option/feature to disable LexicalHandler registration
-					&& false) {
-				try {
-					p.setProperty(LEXICAL_HANDLER_PROPERTY, h);
-				} catch (Exception e) {
-					log.log(Level.WARNING, "LexicalHandler registration exception:", e);
-					log.log(Level.WARNING,
-							"Tried to register the handler {0} as a LexicalHandler but LexicalHandlers are not supported by the parser {1}",
-							new Object[]{h, p});
-				}
+			for (ActionFactory f : ServiceLoader.load(ActionFactory.class)) {
+				String code = f.getActionCode();
+				actionFactories.put(code, f);
+				log.log(Level.CONFIG, "Discovered output module: {0} = {1}", new Object[]{code, f.getClass().getName()});
 			}
 
-			p.parse(vstup, h);
+			ActionFactory actionFactory = actionFactories.get(actionCode);
+
+			if (actionFactory == null) {
+				log.log(Level.SEVERE, "No such output action with code: {0}", actionCode);
+			} else {
+
+				ActionContext actionContext = new ActionContext(outputStream);
+				Action action = actionFactory.getAction(actionContext);
+
+				DefaultHandler defaultHandler = action.getDefaultHandler();
+				LexicalHandler lexicalHandler = action.getLexicalHandler();
+
+				SAXParserFactory t = SAXParserFactory.newInstance();
+				SAXParser p = t.newSAXParser();
+
+				if (lexicalHandler == null) {
+					log.log(Level.FINE, "No LexicalHandler provided.");
+				} else {
+					try {
+						p.setProperty(LEXICAL_HANDLER_PROPERTY, defaultHandler);
+					} catch (Exception e) {
+						log.log(Level.WARNING, "LexicalHandler registration exception:", e);
+						log.log(Level.WARNING,
+								"Tried to register the handler {0} as a LexicalHandler but LexicalHandlers are not supported by the parser {1}",
+								new Object[]{defaultHandler, p});
+					}
+				}
+
+				p.parse(vstup, defaultHandler);
+			}
+
 		} catch (Exception e) {
 			log.log(Level.SEVERE, "Error during processing: " + Arrays.toString(args), e);
 		}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/AbstractAction.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/AbstractAction.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,47 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out;
+
+import org.xml.sax.ext.LexicalHandler;
+
+/**
+ * Recommended base class for Actions.
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public abstract class AbstractAction implements Action {
+
+	private final ActionContext actionContext;
+
+	public AbstractAction(ActionContext actionContext) {
+		this.actionContext = actionContext;
+	}
+
+	protected ActionContext getActionContext() {
+		return actionContext;
+	}
+
+	/**
+	 * @return null – lexical events are not supported
+	 */
+	@Override
+	public LexicalHandler getLexicalHandler() {
+		return null;
+	}
+
+}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/Action.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/Action.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,39 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out;
+
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Executive class of an output module.
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public interface Action {
+
+	public DefaultHandler getDefaultHandler();
+
+	/**
+	 * For e.g. comment nodes.
+	 *
+	 * @return may return null if this output module does not support lexical events
+	 */
+	public LexicalHandler getLexicalHandler();
+
+}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/ActionContext.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/ActionContext.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,39 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out;
+
+import java.io.OutputStream;
+
+/**
+ * Context for one action instance.
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class ActionContext {
+
+	private OutputStream outputStream;
+
+	public ActionContext(OutputStream outputStream) {
+		this.outputStream = outputStream;
+	}
+
+	public OutputStream getOutputStream() {
+		return outputStream;
+	}
+
+}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/ActionFactory.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/ActionFactory.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,39 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out;
+
+/**
+ * Interface of an output module.
+ * Modules are discovered over META-INF/services.
+ * Must have non-parametric constructor.
+ * Should be lightweight – use lazy initialization
+ * (all factories are instantiated, even if not used).
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public interface ActionFactory {
+
+	/**
+	 * @return short code/name for this action – is used on command line to say, which action should
+	 * be executed.
+	 */
+	public String getActionCode();
+
+	public Action getAction(ActionContext context) throws OutputActionException;
+
+}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/EchoContentHandler.java
--- a/java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/EchoContentHandler.java	Sat Jun 14 22:56:51 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/**
- * Alt2XML
- * Copyright © 2014 František Kučera (frantovo.cz)
- *
- * This program 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.
- *
- * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
- */
-package cz.frantovo.alt2xml.out;
-
-import java.util.logging.Logger;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * Slouží k převodu právě parsovaného XML zpět na XML.
- * Určen pro testování a ladění a pro použití s neobvyklými „XML“ parsery,
- * které nečtou XML ale jiný jazyk (např. JSON, INI atd.), ale používají stejné rozhraní (SAX).
- *
- * TODO: další typy uzlů a jmenné prostory.
- *
- * @author Ing. František Kučera (frantovo.cz)
- */
-public class EchoContentHandler extends DefaultHandler {
-
-	private static final Logger log = Logger.getLogger(EchoContentHandler.class.getName());
-	private XMLStreamWriter w;
-
-	/**
-	 * @param writer kam se bude vypisovat XML.
-	 */
-	public EchoContentHandler(XMLStreamWriter writer) {
-		w = writer;
-	}
-
-	@Override
-	public void startDocument() throws SAXException {
-		try {
-			w.writeStartDocument();
-		} catch (XMLStreamException e) {
-			throw new SAXException(e);
-		}
-	}
-
-	@Override
-	public void endDocument() throws SAXException {
-		try {
-			w.writeEndDocument();
-			w.close();
-		} catch (XMLStreamException e) {
-			throw new SAXException(e);
-		}
-	}
-
-	@Override
-	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
-		try {
-			w.writeStartElement(qName);
-
-			if (attributes != null) {
-				for (int i = 0; i < attributes.getLength(); i++) {
-					w.writeAttribute(attributes.getQName(i), attributes.getValue(i));
-				}
-			}
-
-			w.flush();
-		} catch (XMLStreamException e) {
-			throw new SAXException(e);
-		}
-	}
-
-	@Override
-	public void endElement(String uri, String localName, String qName) throws SAXException {
-		try {
-			w.writeEndElement();
-			w.flush();
-		} catch (XMLStreamException e) {
-			throw new SAXException(e);
-		}
-	}
-
-	@Override
-	public void characters(char[] ch, int start, int length) throws SAXException {
-		try {
-			w.writeCharacters(ch, start, length);
-			w.flush();
-		} catch (XMLStreamException e) {
-			throw new SAXException(e);
-		}
-	}
-
-	/**
-	 * LexicalHandler methods
-	 *
-	 * @Override
-	 * public void startDTD(String name, String publicId, String systemId) throws SAXException {
-	 * log.log(Level.WARNING, "Start of DTD: {0} | {1} | {2}", new Object[]{name, publicId,
-	 * systemId});
-	 * }
-	 *
-	 * @Override
-	 * public void endDTD() throws SAXException {
-	 * log.log(Level.WARNING, "End of DTD");
-	 * }
-	 *
-	 * @Override
-	 * public void startEntity(String name) throws SAXException {
-	 * log.log(Level.WARNING, "Start of Entity: {0}", name);
-	 * }
-	 *
-	 * @Override
-	 * public void endEntity(String name) throws SAXException {
-	 * log.log(Level.WARNING, "End of Entity: {0}", name);
-	 * }
-	 *
-	 * @Override
-	 * public void startCDATA() throws SAXException {
-	 * log.log(Level.WARNING, "Start of CDATA");
-	 * }
-	 *
-	 * @Override
-	 * public void endCDATA() throws SAXException {
-	 * log.log(Level.WARNING, "End of CDATA");
-	 * }
-	 *
-	 * @Override
-	 * public void comment(char[] ch, int start, int length) throws SAXException {
-	 * try {
-	 * w.writeComment(new String(ch, start, length));
-	 * w.flush();
-	 * } catch (XMLStreamException e) {
-	 * throw new SAXException(e);
-	 * }
-	 * }
-	 */
-}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/OutputActionException.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-lib-output/src/cz/frantovo/alt2xml/out/OutputActionException.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,41 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out;
+
+/**
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class OutputActionException extends Exception {
+
+	public OutputActionException() {
+	}
+
+	public OutputActionException(String message) {
+		super(message);
+	}
+
+	public OutputActionException(Throwable cause) {
+		super(cause);
+	}
+
+	public OutputActionException(String message, Throwable cause) {
+		super(message, cause);
+	}
+
+}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/config/META-INF/services/cz.frantovo.alt2xml.out.ActionFactory
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-out-xml/config/META-INF/services/cz.frantovo.alt2xml.out.ActionFactory	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,1 @@
+cz.frantovo.alt2xml.out.xml.XMLActionFactory
\ No newline at end of file
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/nbproject/build-impl.xml
--- a/java/alt2xml-out-xml/nbproject/build-impl.xml	Sat Jun 14 22:56:51 2014 +0200
+++ b/java/alt2xml-out-xml/nbproject/build-impl.xml	Sun Jun 15 14:50:49 2014 +0200
@@ -127,6 +127,7 @@
         </condition>
         <condition property="have.sources">
             <or>
+                <available file="${src.config.dir}"/>
                 <available file="${src.dir}"/>
             </or>
         </condition>
@@ -223,6 +224,7 @@
         <!-- You can override this target in the ../build.xml file. -->
     </target>
     <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.config.dir">Must set src.config.dir</fail>
         <fail unless="src.dir">Must set src.dir</fail>
         <fail unless="test.src.dir">Must set test.src.dir</fail>
         <fail unless="build.dir">Must set build.dir</fail>
@@ -245,7 +247,7 @@
     </target>
     <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
         <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${src.config.dir}:${src.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
             <attribute default="${javac.processorpath}" name="processorpath"/>
@@ -286,7 +288,7 @@
     </target>
     <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
         <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${src.config.dir}:${src.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
             <attribute default="${javac.processorpath}" name="processorpath"/>
@@ -319,7 +321,7 @@
     </target>
     <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
         <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
-            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${src.config.dir}:${src.dir}" name="srcdir"/>
             <attribute default="${build.classes.dir}" name="destdir"/>
             <attribute default="${javac.classpath}" name="classpath"/>
             <sequential>
@@ -925,11 +927,12 @@
                 <include name="*"/>
             </dirset>
         </pathconvert>
-        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
+        <j2seproject3:depend srcdir="${src.config.dir}:${src.dir}:${build.generated.subdirs}"/>
     </target>
     <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
         <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
         <copy todir="${build.classes.dir}">
+            <fileset dir="${src.config.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
             <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
         </copy>
     </target>
@@ -951,7 +954,7 @@
     <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
         <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
         <j2seproject3:force-recompile/>
-        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.config.dir}:${src.dir}"/>
     </target>
     <target name="-post-compile-single">
         <!-- Empty placeholder for easier customization. -->
@@ -1217,6 +1220,9 @@
             <classpath>
                 <path path="${javac.classpath}"/>
             </classpath>
+            <fileset dir="${src.config.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
             <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
                 <filename name="**/*.java"/>
             </fileset>
@@ -1227,6 +1233,9 @@
             <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
         </javadoc>
         <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.config.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
             <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
                 <filename name="**/doc-files/**"/>
             </fileset>
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/nbproject/genfiles.properties
--- a/java/alt2xml-out-xml/nbproject/genfiles.properties	Sat Jun 14 22:56:51 2014 +0200
+++ b/java/alt2xml-out-xml/nbproject/genfiles.properties	Sun Jun 15 14:50:49 2014 +0200
@@ -1,8 +1,8 @@
-build.xml.data.CRC32=8bcc59de
+build.xml.data.CRC32=8237fb99
 build.xml.script.CRC32=c7a10d41
 build.xml.stylesheet.CRC32=8064a381@1.74.2.48
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=8bcc59de
-nbproject/build-impl.xml.script.CRC32=40cffe34
+nbproject/build-impl.xml.data.CRC32=8237fb99
+nbproject/build-impl.xml.script.CRC32=88681dba
 nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.2.48
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/nbproject/project.properties
--- a/java/alt2xml-out-xml/nbproject/project.properties	Sat Jun 14 22:56:51 2014 +0200
+++ b/java/alt2xml-out-xml/nbproject/project.properties	Sun Jun 15 14:50:49 2014 +0200
@@ -1,9 +1,10 @@
 annotation.processing.enabled=true
 annotation.processing.enabled.in.editor=false
-annotation.processing.processor.options=
 annotation.processing.processors.list=
 annotation.processing.run.all.processors=true
 annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=alt2xml-out-xml
+application.vendor=fiki
 build.classes.dir=${build.dir}/classes
 build.classes.excludes=**/*.java,**/*.form
 # This directory is removed when the project is cleaned:
@@ -26,6 +27,7 @@
 dist.dir=dist
 dist.jar=${dist.dir}/alt2xml-out-xml.jar
 dist.javadoc.dir=${dist.dir}/javadoc
+endorsed.classpath=
 excludes=
 includes=**
 jar.compress=false
@@ -70,5 +72,6 @@
     ${javac.test.classpath}:\
     ${build.test.classes.dir}
 source.encoding=UTF-8
+src.config.dir=config
 src.dir=src
 test.src.dir=test
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/nbproject/project.xml
--- a/java/alt2xml-out-xml/nbproject/project.xml	Sat Jun 14 22:56:51 2014 +0200
+++ b/java/alt2xml-out-xml/nbproject/project.xml	Sun Jun 15 14:50:49 2014 +0200
@@ -5,6 +5,7 @@
         <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
             <name>alt2xml-out-xml</name>
             <source-roots>
+                <root id="src.config.dir" name="Config"/>
                 <root id="src.dir"/>
             </source-roots>
             <test-roots>
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/src/cz/frantovo/alt2xml/out/xml/XMLAction.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-out-xml/src/cz/frantovo/alt2xml/out/xml/XMLAction.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,42 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out.xml;
+
+import cz.frantovo.alt2xml.out.AbstractAction;
+import cz.frantovo.alt2xml.out.ActionContext;
+import javax.xml.stream.XMLStreamWriter;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class XMLAction extends AbstractAction {
+
+	private final XMLHandler handler;
+
+	public XMLAction(ActionContext actionContext, XMLStreamWriter writer) {
+		super(actionContext);
+		handler = new XMLHandler(writer);
+	}
+
+	@Override
+	public DefaultHandler getDefaultHandler() {
+		return handler;
+	}
+}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/src/cz/frantovo/alt2xml/out/xml/XMLActionFactory.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-out-xml/src/cz/frantovo/alt2xml/out/xml/XMLActionFactory.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,59 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out.xml;
+
+import cz.frantovo.alt2xml.out.Action;
+import cz.frantovo.alt2xml.out.ActionContext;
+import cz.frantovo.alt2xml.out.ActionFactory;
+import cz.frantovo.alt2xml.out.OutputActionException;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+/**
+ * Prints XML.
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class XMLActionFactory implements ActionFactory {
+
+	private XMLOutputFactory xmlOutputFactory;
+
+	@Override
+	public String getActionCode() {
+		return "xml";
+	}
+
+	@Override
+	public Action getAction(ActionContext context) throws OutputActionException {
+		try {
+			XMLStreamWriter writer = getXmlOutputFactory().createXMLStreamWriter(context.getOutputStream());
+			return new XMLAction(context, writer);
+		} catch (XMLStreamException e) {
+			throw new OutputActionException("Unable to create XMLStreamWriter", e);
+		}
+	}
+
+	private XMLOutputFactory getXmlOutputFactory() {
+		if (xmlOutputFactory == null) {
+			xmlOutputFactory = XMLOutputFactory.newFactory();
+		}
+		return xmlOutputFactory;
+	}
+
+}
diff -r f1e91d4ac35c -r 058c1c39251e java/alt2xml-out-xml/src/cz/frantovo/alt2xml/out/xml/XMLHandler.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/alt2xml-out-xml/src/cz/frantovo/alt2xml/out/xml/XMLHandler.java	Sun Jun 15 14:50:49 2014 +0200
@@ -0,0 +1,145 @@
+/**
+ * Alt2XML
+ * Copyright © 2014 František Kučera (frantovo.cz)
+ *
+ * This program 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.
+ *
+ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cz.frantovo.alt2xml.out.xml;
+
+import java.util.logging.Logger;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+/**
+ * Slouží k převodu právě parsovaného XML zpět na XML.
+ * Určen pro testování a ladění a pro použití s neobvyklými „XML“ parsery,
+ * které nečtou XML ale jiný jazyk (např. JSON, INI atd.), ale používají stejné rozhraní (SAX).
+ *
+ * TODO: další typy uzlů a jmenné prostory.
+ *
+ * @author Ing. František Kučera (frantovo.cz)
+ */
+public class XMLHandler extends DefaultHandler {
+
+	private static final Logger log = Logger.getLogger(XMLHandler.class.getName());
+	private XMLStreamWriter w;
+
+	public XMLHandler(XMLStreamWriter writer) {
+		w = writer;
+	}
+
+	@Override
+	public void startDocument() throws SAXException {
+		try {
+			w.writeStartDocument();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void endDocument() throws SAXException {
+		try {
+			w.writeEndDocument();
+			w.close();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+		try {
+			w.writeStartElement(qName);
+
+			if (attributes != null) {
+				for (int i = 0; i < attributes.getLength(); i++) {
+					w.writeAttribute(attributes.getQName(i), attributes.getValue(i));
+				}
+			}
+
+			w.flush();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void endElement(String uri, String localName, String qName) throws SAXException {
+		try {
+			w.writeEndElement();
+			w.flush();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	@Override
+	public void characters(char[] ch, int start, int length) throws SAXException {
+		try {
+			w.writeCharacters(ch, start, length);
+			w.flush();
+		} catch (XMLStreamException e) {
+			throw new SAXException(e);
+		}
+	}
+
+	/**
+	 * LexicalHandler methods
+	 *
+	 * @Override
+	 * public void startDTD(String name, String publicId, String systemId) throws SAXException {
+	 * log.log(Level.WARNING, "Start of DTD: {0} | {1} | {2}", new Object[]{name, publicId,
+	 * systemId});
+	 * }
+	 *
+	 * @Override
+	 * public void endDTD() throws SAXException {
+	 * log.log(Level.WARNING, "End of DTD");
+	 * }
+	 *
+	 * @Override
+	 * public void startEntity(String name) throws SAXException {
+	 * log.log(Level.WARNING, "Start of Entity: {0}", name);
+	 * }
+	 *
+	 * @Override
+	 * public void endEntity(String name) throws SAXException {
+	 * log.log(Level.WARNING, "End of Entity: {0}", name);
+	 * }
+	 *
+	 * @Override
+	 * public void startCDATA() throws SAXException {
+	 * log.log(Level.WARNING, "Start of CDATA");
+	 * }
+	 *
+	 * @Override
+	 * public void endCDATA() throws SAXException {
+	 * log.log(Level.WARNING, "End of CDATA");
+	 * }
+	 *
+	 * @Override
+	 * public void comment(char[] ch, int start, int length) throws SAXException {
+	 * try {
+	 * w.writeComment(new String(ch, start, length));
+	 * w.flush();
+	 * } catch (XMLStreamException e) {
+	 * throw new SAXException(e);
+	 * }
+	 * }
+	 */
+}
diff -r f1e91d4ac35c -r 058c1c39251e scripts/alt2xml.sh
--- a/scripts/alt2xml.sh	Sat Jun 14 22:56:51 2014 +0200
+++ b/scripts/alt2xml.sh	Sun Jun 15 14:50:49 2014 +0200
@@ -8,14 +8,18 @@
 	"$DIR/java/alt2xml-lib-output/dist/alt2xml-lib-output.jar"
 );
 
-PLUGINS=(
+INPUT_PLUGINS=(
 	"$DIR/java/alt2xml-in-properties/dist/alt2xml-in-properties.jar"
 	
 	"$DIR/java/alt2xml-in-json/dist/alt2xml-in-json.jar"
 	"$DIR/../temp/lib/json_simple-1.1.jar"
 );
 
-for e in "${STANDARD_JARS[@]}" "${PLUGINS[@]}"; do
+OUTPUT_PLUGINS=(
+	"$DIR/java/alt2xml-out-xml/dist/alt2xml-out-xml.jar"
+);
+
+for e in "${STANDARD_JARS[@]}" "${INPUT_PLUGINS[@]}" "${OUTPUT_PLUGINS[@]}"; do
 	CLASS_PATH="$CLASS_PATH:$e";
 done