From 0339299652f0026899f8e19f532c256e2373bf3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20Henning?= <stu114708@informatik.uni-kiel.de>
Date: Thu, 31 Mar 2016 14:10:33 +0200
Subject: [PATCH] added JAXB marshal stages

---
 .../graph/export/graphml/GraphMLExporter.java |  2 +-
 .../analysis/util/JAXBMarshalStage.java       | 62 ++++++++++++++++++
 .../util/UniversalJAXBMarshalStage.java       | 64 +++++++++++++++++++
 3 files changed, 127 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/kieker/analysis/util/JAXBMarshalStage.java
 create mode 100644 src/main/java/kieker/analysis/util/UniversalJAXBMarshalStage.java

diff --git a/src/main/java/kieker/analysis/graph/export/graphml/GraphMLExporter.java b/src/main/java/kieker/analysis/graph/export/graphml/GraphMLExporter.java
index 81d32dd2..bd3ac7df 100644
--- a/src/main/java/kieker/analysis/graph/export/graphml/GraphMLExporter.java
+++ b/src/main/java/kieker/analysis/graph/export/graphml/GraphMLExporter.java
@@ -30,7 +30,7 @@ public class GraphMLExporter {
 			ObjectFactory objectFactory = new ObjectFactory();
 			JAXBElement<GraphmlType> rootElement = objectFactory.createGraphml(graphmlType);
 
-			JAXBContext context = JAXBContext.newInstance(rootElement.getValue().getClass());
+			JAXBContext context = JAXBContext.newInstance(rootElement.getDeclaredType());
 			Marshaller marshaller = context.createMarshaller();
 			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, FORMATTED_OUTPUT);
 
diff --git a/src/main/java/kieker/analysis/util/JAXBMarshalStage.java b/src/main/java/kieker/analysis/util/JAXBMarshalStage.java
new file mode 100644
index 00000000..7f6997b9
--- /dev/null
+++ b/src/main/java/kieker/analysis/util/JAXBMarshalStage.java
@@ -0,0 +1,62 @@
+package kieker.analysis.util;
+
+import java.io.OutputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import teetime.framework.AbstractConsumerStage;
+
+/**
+ * This stage marshals the content tree rooted at an incoming element into an
+ * output stream.
+ *
+ * A class object has to be passed at creation. Only elements of this type or
+ * elements of this type wrapped in a {@code JAXBElement} could be marshaled.
+ *
+ * Incoming elements have to be an instance of {@code JAXBElement} or are
+ * annotated with {@code @XmlRootElement}.
+ *
+ * Marshaling with this stage is faster than using
+ * {@link UniversalJAXBMarshalStage}. So It should be used if the type of the
+ * incoming elements is known.
+ *
+ * @author Sören Henning
+ *
+ */
+public class JAXBMarshalStage extends AbstractConsumerStage<Object> {
+
+	private static final Boolean FORMATTED_OUTPUT_DEFAULT = Boolean.TRUE;
+
+	private final Marshaller marshaller;
+	private final OutputStream outputStream;
+
+	public JAXBMarshalStage(final Class<?> elementsClass, final OutputStream outputStream) {
+		this(elementsClass, outputStream, FORMATTED_OUTPUT_DEFAULT);
+	}
+
+	public JAXBMarshalStage(final Class<?> elementsClass, final OutputStream outputStream, final Boolean formattedOutput) {
+		this.outputStream = outputStream;
+
+		try {
+			this.marshaller = JAXBContext.newInstance(elementsClass).createMarshaller();
+			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, formattedOutput);
+		} catch (JAXBException e) {
+			// TODO Exception
+			throw new IllegalStateException(e);
+		}
+	}
+
+	@Override
+	protected void execute(final Object element) {
+
+		try {
+			marshaller.marshal(element, outputStream);
+		} catch (JAXBException e) {
+			// TODO Exception
+			throw new IllegalStateException("The received element could not be marshalled.", e);
+		}
+	}
+
+}
diff --git a/src/main/java/kieker/analysis/util/UniversalJAXBMarshalStage.java b/src/main/java/kieker/analysis/util/UniversalJAXBMarshalStage.java
new file mode 100644
index 00000000..b08db056
--- /dev/null
+++ b/src/main/java/kieker/analysis/util/UniversalJAXBMarshalStage.java
@@ -0,0 +1,64 @@
+package kieker.analysis.util;
+
+import java.io.OutputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import teetime.framework.AbstractConsumerStage;
+
+/**
+ * This stage marshals the content tree rooted at an incoming element into an
+ * output stream.
+ *
+ * Incoming elements have to be an instance of {@code JAXBElement} or are
+ * annotated with {@code @XmlRootElement}.
+ *
+ * {@link JAXBMarshalStage} should be preferred if all incoming elements have
+ * the same type and the type is known, because {@link JAXBMarshalStage} is
+ * faster.
+ *
+ * @author Sören Henning
+ *
+ */
+public class UniversalJAXBMarshalStage extends AbstractConsumerStage<Object> {
+
+	private static final Boolean FORMATTED_OUTPUT_DEFAULT = Boolean.TRUE;
+
+	private final OutputStream outputStream;
+	private final Boolean formattedOutput;
+
+	public UniversalJAXBMarshalStage(final OutputStream outputStream) {
+		this(outputStream, FORMATTED_OUTPUT_DEFAULT);
+	}
+
+	public UniversalJAXBMarshalStage(final OutputStream outputStream, final Boolean formattedOutput) {
+		this.outputStream = outputStream;
+		this.formattedOutput = formattedOutput;
+	}
+
+	@Override
+	protected void execute(final Object element) {
+
+		// Determine whether the incoming object is wrapped in a JAXBElement
+		Class<?> elementClass;
+		if (element instanceof JAXBElement) {
+			elementClass = ((JAXBElement<?>) element).getDeclaredType();
+		} else {
+			elementClass = element.getClass();
+		}
+
+		try {
+			final Marshaller marshaller = JAXBContext.newInstance(elementClass).createMarshaller();
+			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, formattedOutput);
+			marshaller.marshal(element, outputStream);
+		} catch (JAXBException e) {
+			// TODO Exception
+			throw new IllegalStateException("The received element could not be marshalled.", e);
+		}
+
+	}
+
+}
-- 
GitLab