diff --git a/.gitignore b/.gitignore
index 9751ddd..b75c73e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
.settings
.project
.classpath
+/schema/
diff --git a/build.gradle b/build.gradle
index 6c4b529..920694b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -25,7 +25,6 @@ repositories {
}
dependencies {
- compile 'ch.psi:ch.psi.fda.core:2.3.4'
compile 'ch.psi:jcae:2.4.1'
compile 'com.google.inject:guice:3.0'
compile 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.5.1'
@@ -39,6 +38,7 @@ dependencies {
compile 'org.freehep:freehep-xdr:2.0.4'
compile 'ch.psi:plot:2.1-SNAPSHOT'
+ compile 'com.google.guava:guava:>15.0'
compile 'com.sun.mail:javax.mail:1.5.0'
compile 'javax.inject:javax.inject:1'
@@ -58,14 +58,16 @@ task sourcesJar(type: Jar, dependsOn: classes) {
from sourceSets.main.allSource
}
+/*
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
+*/
artifacts {
archives sourcesJar
- archives javadocJar
+ //archives javadocJar
}
jaxb{
diff --git a/src/main/java/ch/psi/fda/DescriptorProvider.java b/src/main/java/ch/psi/fda/DescriptorProvider.java
new file mode 100644
index 0000000..bcd198f
--- /dev/null
+++ b/src/main/java/ch/psi/fda/DescriptorProvider.java
@@ -0,0 +1,17 @@
+package ch.psi.fda;
+
+import java.io.File;
+
+import ch.psi.fda.edescriptor.EDescriptor;
+import ch.psi.fda.vdescriptor.VDescriptor;
+
+public interface DescriptorProvider {
+
+ public void load(File ... files );
+
+ public EDescriptor getEDescriptor();
+ public VDescriptor getVDescriptor();
+
+ public Class> getEDescriptorClass();
+
+}
diff --git a/src/main/java/ch/psi/fda/EContainer.java b/src/main/java/ch/psi/fda/EContainer.java
new file mode 100644
index 0000000..5de340f
--- /dev/null
+++ b/src/main/java/ch/psi/fda/EContainer.java
@@ -0,0 +1,28 @@
+package ch.psi.fda;
+
+public interface EContainer {
+
+ /**
+ * Initialize execution container like required resources, etc.
+ */
+ public void initialize();
+
+ /**
+ * Executes the logic implemented by the ExecutionContainer
+ * Execute is a blocking function and must not return before the actual logic is executed
+ */
+ public void execute();
+
+ /**
+ * Try to abort the execution of the logic
+ */
+ public void abort();
+
+ public boolean isActive();
+
+ /**
+ * Destroy execution container and free all allocated resources
+ */
+ public void destroy();
+
+}
diff --git a/src/main/java/ch/psi/fda/EContainerFactory.java b/src/main/java/ch/psi/fda/EContainerFactory.java
new file mode 100644
index 0000000..0debf27
--- /dev/null
+++ b/src/main/java/ch/psi/fda/EContainerFactory.java
@@ -0,0 +1,22 @@
+package ch.psi.fda;
+
+import ch.psi.fda.edescriptor.EDescriptor;
+
+import com.google.common.eventbus.EventBus;
+
+public interface EContainerFactory {
+
+ /**
+ * Check whether the factory supports
+ * @param descriptor
+ * @return
+ */
+ public boolean supportsEDescriptor(EDescriptor descriptor);
+
+ /**
+ * Create the execution container based on the passed descriptor
+ * @param descriptor
+ * @return
+ */
+ public EContainer getEContainer(EDescriptor descriptor, EventBus bus);
+}
diff --git a/src/main/java/ch/psi/fda/edescriptor/EDescriptor.java b/src/main/java/ch/psi/fda/edescriptor/EDescriptor.java
new file mode 100644
index 0000000..67be011
--- /dev/null
+++ b/src/main/java/ch/psi/fda/edescriptor/EDescriptor.java
@@ -0,0 +1,15 @@
+package ch.psi.fda.edescriptor;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+/**
+ * Execution container descriptor
+ */
+@XmlRootElement
+@XmlTransient
+public interface EDescriptor {
+
+
+ // TODO Need to contain what need to be streamed
+}
diff --git a/src/main/java/ch/psi/fda/messages/ControlMessage.java b/src/main/java/ch/psi/fda/messages/ControlMessage.java
new file mode 100644
index 0000000..ec9cda9
--- /dev/null
+++ b/src/main/java/ch/psi/fda/messages/ControlMessage.java
@@ -0,0 +1,29 @@
+/**
+ *
+ * Copyright 2010 Paul Scherrer Institute. All rights reserved.
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This code 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this code. If not, see .
+ *
+ */
+
+package ch.psi.fda.messages;
+
+
+/**
+ * A control message that is not holding any data but
+ * control information (like end of loop, etc.)
+ */
+public abstract class ControlMessage extends Message{
+ private static final long serialVersionUID = 1L;
+}
diff --git a/src/main/java/ch/psi/fda/messages/DataMessage.java b/src/main/java/ch/psi/fda/messages/DataMessage.java
new file mode 100644
index 0000000..2b3d19c
--- /dev/null
+++ b/src/main/java/ch/psi/fda/messages/DataMessage.java
@@ -0,0 +1,105 @@
+/**
+ *
+ * Copyright 2010 Paul Scherrer Institute. All rights reserved.
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This code 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this code. If not, see .
+ *
+ */
+
+package ch.psi.fda.messages;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Message holding data
+ */
+public class DataMessage extends Message{
+
+ private static final long serialVersionUID = 1L;
+
+ private final List data;
+ private List metadata;
+
+// public DataMessage(){
+// this.data = new ArrayList();
+// this.metadata = new ArrayList<>();
+// }
+//
+ public DataMessage(List metadata){
+ this.data = new ArrayList();
+ this.metadata = metadata;
+ }
+
+ public List getData(){
+ return(data);
+ }
+ public List getMetadata(){
+ return metadata;
+ }
+ public void setMetadata(List metadata){
+ this.metadata = metadata;
+ }
+
+ // Utility functions
+
+ @SuppressWarnings("unchecked")
+ public T getData(String id){
+ int i=0;
+ for(Metadata m: metadata){
+ if(m.getId().equals(id)){
+ return (T) data.get(i);
+ }
+ i++;
+ }
+ throw new IllegalArgumentException("No data found for id: "+id);
+ }
+
+ public Metadata getMetadata(String id){
+ for(Metadata m: metadata){
+ if(m.getId().equals(id)){
+ return m;
+ }
+ }
+ throw new IllegalArgumentException("No data found for id: "+id);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer b = new StringBuffer();
+ b.append("Message [ ");
+ for (Object o : data) {
+ if (o.getClass().isArray()) {
+ // If the array object is of type double[] display its content
+ if (o instanceof double[]) {
+ double[] oa = (double[]) o;
+ b.append("[ ");
+ for (double o1 : oa) {
+ b.append(o1);
+ b.append(" ");
+ }
+ b.append("]");
+ } else {
+ b.append(o.toString());
+ }
+ } else {
+ b.append(o);
+ }
+
+ b.append(" ");
+ }
+ b.append("]");
+ return b.toString();
+ }
+}
diff --git a/src/main/java/ch/psi/fda/messages/EndOfStreamMessage.java b/src/main/java/ch/psi/fda/messages/EndOfStreamMessage.java
new file mode 100644
index 0000000..409a85c
--- /dev/null
+++ b/src/main/java/ch/psi/fda/messages/EndOfStreamMessage.java
@@ -0,0 +1,52 @@
+/**
+ *
+ * Copyright 2010 Paul Scherrer Institute. All rights reserved.
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This code 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this code. If not, see .
+ *
+ */
+
+package ch.psi.fda.messages;
+
+/**
+ * Message that is send at the end of the action loop inside an ActionLoop implementation
+ * of just to indicate that a particular stream has finished
+ */
+public class EndOfStreamMessage extends ControlMessage {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Intersect flag - flag to indicate that stream should be intersected
+ * after this message.
+ */
+ private final boolean iflag;
+
+ public EndOfStreamMessage(){
+ this(false);
+ }
+
+ public EndOfStreamMessage(boolean iflag){
+ this.iflag = iflag;
+ }
+
+ public boolean isIflag(){
+ return(iflag);
+ }
+
+ @Override
+ public String toString() {
+ return "Message[ c message: end of stream ]";
+ }
+}
diff --git a/src/main/java/ch/psi/fda/messages/Message.java b/src/main/java/ch/psi/fda/messages/Message.java
new file mode 100644
index 0000000..9c5f4f7
--- /dev/null
+++ b/src/main/java/ch/psi/fda/messages/Message.java
@@ -0,0 +1,29 @@
+/**
+ *
+ * Copyright 2010 Paul Scherrer Institute. All rights reserved.
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This code 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this code. If not, see .
+ *
+ */
+
+package ch.psi.fda.messages;
+
+import java.io.Serializable;
+
+/**
+ * Message that can be put to the data queue
+ */
+public abstract class Message implements Serializable{
+ private static final long serialVersionUID = 1L;
+}
diff --git a/src/main/java/ch/psi/fda/messages/Metadata.java b/src/main/java/ch/psi/fda/messages/Metadata.java
new file mode 100644
index 0000000..cc208fc
--- /dev/null
+++ b/src/main/java/ch/psi/fda/messages/Metadata.java
@@ -0,0 +1,58 @@
+/**
+ *
+ * Copyright 2010 Paul Scherrer Institute. All rights reserved.
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This code 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this code. If not, see .
+ *
+ */
+
+package ch.psi.fda.messages;
+
+import java.io.Serializable;
+
+/**
+ * Metadata of a component of a message. Each component has a global id.
+ * Optionally the component can also belong to a dimension. However, depending on the
+ * view the number of the dimension might vary. Therefore the dimension number
+ * might change during the lifetime of a message (component).
+ */
+public class Metadata implements Serializable{
+
+ private static final long serialVersionUID = 1L;
+
+ private final String id;
+ private int dimension;
+
+ public Metadata(String id){
+ this.id = id;
+ this.dimension = 0;
+ }
+
+ public Metadata(String id, int dimension){
+ this.id = id;
+ this.dimension = dimension;
+ }
+
+ public void setDimension(int dimension){
+ this.dimension = dimension;
+ }
+
+ public int getDimension() {
+ return dimension;
+ }
+
+ public String getId() {
+ return id;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/messages/StreamDelimiterMessage.java b/src/main/java/ch/psi/fda/messages/StreamDelimiterMessage.java
new file mode 100644
index 0000000..91c7b87
--- /dev/null
+++ b/src/main/java/ch/psi/fda/messages/StreamDelimiterMessage.java
@@ -0,0 +1,67 @@
+/**
+ *
+ * Copyright 2010 Paul Scherrer Institute. All rights reserved.
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This code 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this code. If not, see .
+ *
+ */
+
+package ch.psi.fda.messages;
+
+/**
+ * Message that is send at the end of the action loop inside an ActionLoop implementation
+ */
+public class StreamDelimiterMessage extends ControlMessage{
+ private static final long serialVersionUID = 1L;
+ /**
+ * Number of the dimension this delimiter belongs to.
+ */
+ private final int number;
+
+ /**
+ * Intersect flag - flag to indicate that stream should be intersected
+ * after this message.
+ */
+ private final boolean iflag;
+
+ /**
+ * @param number Number of the dimension this delimiter belongs to
+ */
+ public StreamDelimiterMessage(int number){
+ this(number, false);
+ }
+
+ /**
+ * @param number
+ * @param iflag Flag to indicate that data is grouped
+ */
+ public StreamDelimiterMessage(int number, boolean iflag){
+ this.number = number;
+ this.iflag = iflag;
+ }
+
+ public int getNumber() {
+ return number;
+ }
+
+ public boolean isIflag(){
+ return iflag;
+ }
+
+ @Override
+ public String toString() {
+ // TODO Auto-generated method stub
+ return "Message [ c message: delimiter dimension "+number+" ]";
+ }
+}
diff --git a/src/main/java/ch/psi/fda/serializer/SerializerTXT.java b/src/main/java/ch/psi/fda/serializer/SerializerTXT.java
new file mode 100644
index 0000000..9ee5869
--- /dev/null
+++ b/src/main/java/ch/psi/fda/serializer/SerializerTXT.java
@@ -0,0 +1,224 @@
+/**
+ *
+ * Copyright 2010 Paul Scherrer Institute. All rights reserved.
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This code 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this code. If not, see .
+ *
+ */
+
+package ch.psi.fda.serializer;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.google.common.eventbus.Subscribe;
+
+import ch.psi.fda.messages.DataMessage;
+import ch.psi.fda.messages.EndOfStreamMessage;
+import ch.psi.fda.messages.Message;
+import ch.psi.fda.messages.Metadata;
+import ch.psi.fda.messages.StreamDelimiterMessage;
+
+/**
+ * Serialize data received by a DataQueue
+ */
+public class SerializerTXT {
+
+ private static final Logger logger = Logger.getLogger(SerializerTXT.class.getName());
+
+ private File file;
+ private boolean appendSuffix = true;
+
+ private boolean first = true;
+ private File outfile;
+
+ private int icount;
+ private String basename;
+ private String extension;
+ private boolean newfile;
+ private boolean dataInBetween;
+ private BufferedWriter writer;
+ private StringBuffer b;
+ private StringBuffer b1;
+ private boolean showDimensionHeader = true;
+
+ public SerializerTXT(File file) {
+ this.file = file;
+ }
+
+ /**
+ * @param metadata
+ * @param file
+ * @param appendSuffix
+ * Flag whether to append a _0000 suffix after the original file
+ * name
+ */
+ public SerializerTXT(File file, boolean appendSuffix) {
+ this.file = file;
+ this.appendSuffix = appendSuffix;
+ }
+
+ @Subscribe
+ public void onMessage(Message message) {
+ try {
+ if (first) {
+ first = false;
+ // Write header
+
+ icount = 0;
+ newfile = true;
+ dataInBetween = false;
+ writer = null;
+
+ // Get basename of the file
+ basename = this.file.getAbsolutePath(); // Determine file name
+ extension = basename.replaceAll("^.*\\.", ""); // Determine
+ // extension
+ basename = basename.replaceAll("\\." + extension + "$", "");
+ }
+
+ if (message instanceof DataMessage) {
+ dataInBetween = true;
+ if (newfile) {
+
+ b = new StringBuffer();
+ b1 = new StringBuffer();
+ b.append("#");
+ b1.append("#");
+ for (Metadata c : ((DataMessage) message).getMetadata()) {
+
+ b.append(c.getId());
+ b.append("\t");
+
+ b1.append(c.getDimension());
+ b1.append("\t");
+ }
+ b.setCharAt(b.length() - 1, '\n');
+ b1.setCharAt(b1.length() - 1, '\n');
+
+ // Open new file and write header
+ // Construct file name
+ if (appendSuffix) {
+ outfile = new File(String.format("%s_%04d.%s", basename, icount, extension));
+ }
+ else {
+ outfile = new File(String.format("%s.%s", basename, extension));
+ }
+
+ // Open file
+ logger.fine("Open new data file: " + outfile.getAbsolutePath());
+ writer = new BufferedWriter(new FileWriter(outfile));
+
+ // Write header
+ writer.write(b.toString());
+ if (showDimensionHeader) {
+ writer.write(b1.toString());
+ }
+
+ newfile = false;
+ }
+
+ // Write message to file - each message will result in one line
+ DataMessage m = (DataMessage) message;
+ StringBuffer buffer = new StringBuffer();
+ for (Object o : m.getData()) {
+ if (o.getClass().isArray()) {
+ // If the array object is of type double[] display its
+ // content
+ if (o instanceof double[]) {
+ double[] oa = (double[]) o;
+ for (double o1 : oa) {
+ buffer.append(o1);
+ buffer.append(" "); // Use space instead of tab
+ }
+ buffer.replace(buffer.length() - 1, buffer.length() - 1, "\t"); // Replace
+ // last
+ // space
+ // with
+ // tab
+ }
+ else if (o instanceof Object[]) {
+ // TODO need to be recursive ...
+ Object[] oa = (Object[]) o;
+ for (Object o1 : oa) {
+ buffer.append(o1);
+ buffer.append(" "); // Use space instead of tab
+ }
+ buffer.replace(buffer.length() - 1, buffer.length() - 1, "\t"); // Replace
+ // last
+ // space
+ // with
+ // tab
+ }
+ else {
+ buffer.append("-"); // Not supported
+ }
+ }
+ else {
+ buffer.append(o);
+ buffer.append("\t");
+ }
+ }
+
+ if (buffer.length() > 0) {
+ buffer.deleteCharAt(buffer.length() - 1); // Remove last
+ // character
+ // (i.e. \t)
+ buffer.append("\n"); // Append newline
+ }
+ writer.write(buffer.toString());
+ }
+ else if (message instanceof StreamDelimiterMessage) {
+ StreamDelimiterMessage m = (StreamDelimiterMessage) message;
+ logger.info("Delimiter - number: " + m.getNumber() + " iflag: " + m.isIflag());
+ if (m.isIflag() && appendSuffix) {
+ // Only increase iflag counter if there was data in between
+ // subsequent StreamDelimiterMessages.
+ if (dataInBetween) {
+ icount++;
+ }
+ dataInBetween = false;
+
+ // Set flag to open new file
+ newfile = true;
+
+ // Close file
+ writer.close();
+ }
+ }
+ else if (message instanceof EndOfStreamMessage) {
+ if (writer != null) {
+ // Close file
+ writer.close(); // If the stream was closed previously this
+ // has no effect
+ }
+ }
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "Data serializer had a problem writing to the specified file", e);
+ throw new RuntimeException("Data serializer had a problem writing to the specified file", e);
+ }
+ }
+
+ public boolean isShowDimensionHeader() {
+ return showDimensionHeader;
+ }
+
+ public void setShowDimensionHeader(boolean showDimensionHeader) {
+ this.showDimensionHeader = showDimensionHeader;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/LinePlot.java b/src/main/java/ch/psi/fda/vdescriptor/LinePlot.java
new file mode 100644
index 0000000..adaca5d
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/LinePlot.java
@@ -0,0 +1,53 @@
+package ch.psi.fda.vdescriptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name="lineplot")
+public class LinePlot extends Plot {
+ private List data = new ArrayList<>();
+
+ private Double minX;
+ private Double maxX;
+ private Integer maxSeries;
+
+ public LinePlot(){
+ }
+
+ public LinePlot(String title){
+ setTitle(title);
+ }
+
+ @XmlElement
+ public List getData() {
+ return data;
+ }
+ public void setData(List data) {
+ this.data = data;
+ }
+ @XmlAttribute
+ public Double getMinX() {
+ return minX;
+ }
+ public void setMinX(Double minX) {
+ this.minX = minX;
+ }
+ @XmlAttribute
+ public Double getMaxX() {
+ return maxX;
+ }
+ public void setMaxX(Double maxX) {
+ this.maxX = maxX;
+ }
+ @XmlAttribute
+ public Integer getMaxSeries() {
+ return maxSeries;
+ }
+ public void setMaxSeries(Integer maxSeries) {
+ this.maxSeries = maxSeries;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/MatrixPlot.java b/src/main/java/ch/psi/fda/vdescriptor/MatrixPlot.java
new file mode 100644
index 0000000..c7ac61e
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/MatrixPlot.java
@@ -0,0 +1,87 @@
+package ch.psi.fda.vdescriptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+
+@XmlRootElement(name="matrixplot")
+public class MatrixPlot extends Plot {
+
+ private List data = new ArrayList<>();
+ private Double minX;
+ private Double maxX;
+ private Integer nX;
+
+ private Double minY;
+ private Double maxY;
+ private Integer nY;
+
+ private String type;
+
+ public MatrixPlot(){
+ }
+
+ public MatrixPlot(String title){
+ setTitle(title);
+ }
+
+ public List getData() {
+ return data;
+ }
+ public void setData(List data) {
+ this.data = data;
+ }
+ @XmlAttribute
+ @XmlSchemaType(name = "float")
+ public Double getMinX() {
+ return minX;
+ }
+ public void setMinX(Double minX) {
+ this.minX = minX;
+ }
+ @XmlAttribute
+ public Double getMaxX() {
+ return maxX;
+ }
+ public void setMaxX(Double maxX) {
+ this.maxX = maxX;
+ }
+ @XmlAttribute
+ public Integer getnX() {
+ return nX;
+ }
+ public void setnX(Integer nX) {
+ this.nX = nX;
+ }
+ @XmlAttribute
+ public Double getMinY() {
+ return minY;
+ }
+ public void setMinY(Double minY) {
+ this.minY = minY;
+ }
+ @XmlAttribute
+ public Double getMaxY() {
+ return maxY;
+ }
+ public void setMaxY(Double maxY) {
+ this.maxY = maxY;
+ }
+ @XmlAttribute
+ public Integer getnY() {
+ return nY;
+ }
+ public void setnY(Integer nY) {
+ this.nY = nY;
+ }
+ @XmlAttribute
+ public String getType() {
+ return type;
+ }
+ public void setType(String type) {
+ this.type = type;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/Plot.java b/src/main/java/ch/psi/fda/vdescriptor/Plot.java
new file mode 100644
index 0000000..4ebb53a
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/Plot.java
@@ -0,0 +1,20 @@
+package ch.psi.fda.vdescriptor;
+
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+
+
+@XmlSeeAlso({LinePlot.class, MatrixPlot.class})
+@XmlTransient
+public abstract class Plot {
+
+ private String title;
+
+ public String getTitle() {
+ return title;
+ }
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/Series.java b/src/main/java/ch/psi/fda/vdescriptor/Series.java
new file mode 100644
index 0000000..9d1263e
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/Series.java
@@ -0,0 +1,12 @@
+package ch.psi.fda.vdescriptor;
+
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+
+
+@XmlSeeAlso({XYSeries.class, XYZSeries.class})
+@XmlTransient
+public abstract class Series {
+
+
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/VDescriptor.java b/src/main/java/ch/psi/fda/vdescriptor/VDescriptor.java
new file mode 100644
index 0000000..8026f2c
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/VDescriptor.java
@@ -0,0 +1,28 @@
+package ch.psi.fda.vdescriptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name="vdescriptor")
+public class VDescriptor {
+
+ private List plots = new ArrayList<>();
+
+ @XmlElementWrapper
+ @XmlElements({
+ @XmlElement(name="lineplot",type=LinePlot.class),
+ @XmlElement(name="matrixplot",type=MatrixPlot.class),
+ })
+ public List getPlots() {
+ return plots;
+ }
+
+ public void setPlots(List plots) {
+ this.plots = plots;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/XYSeries.java b/src/main/java/ch/psi/fda/vdescriptor/XYSeries.java
new file mode 100644
index 0000000..4303e0d
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/XYSeries.java
@@ -0,0 +1,42 @@
+package ch.psi.fda.vdescriptor;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name="xyseries")
+public class XYSeries extends Series {
+
+ private String x = null;
+ private String y = null;
+ private Integer maxItemCount = -1;
+
+ public XYSeries(){
+ }
+
+ public XYSeries(String x, String y){
+ this.x = x;
+ this.y = y;
+ }
+
+ @XmlAttribute
+ public String getX() {
+ return x;
+ }
+ public void setX(String x) {
+ this.x = x;
+ }
+ @XmlAttribute
+ public String getY() {
+ return y;
+ }
+ public void setY(String y) {
+ this.y = y;
+ }
+ @XmlAttribute
+ public Integer getMaxItemCount() {
+ return maxItemCount;
+ }
+ public void setMaxItemCount(Integer maxCount) {
+ this.maxItemCount = maxCount;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/XYZSeries.java b/src/main/java/ch/psi/fda/vdescriptor/XYZSeries.java
new file mode 100644
index 0000000..520f5cc
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/XYZSeries.java
@@ -0,0 +1,43 @@
+package ch.psi.fda.vdescriptor;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name="xyzseries")
+public class XYZSeries extends Series {
+
+ private String x = null;
+ private String y = null;
+ private String z = null;
+
+ public XYZSeries(){
+ }
+
+ public XYZSeries(String x, String y, String z){
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ @XmlAttribute
+ public String getX() {
+ return x;
+ }
+ public void setX(String x) {
+ this.x = x;
+ }
+ @XmlAttribute
+ public String getY() {
+ return y;
+ }
+ public void setY(String y) {
+ this.y = y;
+ }
+ @XmlAttribute
+ public String getZ() {
+ return z;
+ }
+ public void setZ(String z) {
+ this.z = z;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/YSeries.java b/src/main/java/ch/psi/fda/vdescriptor/YSeries.java
new file mode 100644
index 0000000..2447725
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/YSeries.java
@@ -0,0 +1,28 @@
+package ch.psi.fda.vdescriptor;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * In a YSeries the Y components hold an data array in which the index i the x and the value the y value.
+ */
+@XmlRootElement(name="yseries")
+public class YSeries extends Series {
+
+ private String y = null;
+
+ public YSeries(){
+ }
+
+ public YSeries(String y){
+ this.y = y;
+ }
+
+ @XmlAttribute
+ public String getY() {
+ return y;
+ }
+ public void setY(String y) {
+ this.y = y;
+ }
+}
diff --git a/src/main/java/ch/psi/fda/vdescriptor/YZSeries.java b/src/main/java/ch/psi/fda/vdescriptor/YZSeries.java
new file mode 100644
index 0000000..03bc40d
--- /dev/null
+++ b/src/main/java/ch/psi/fda/vdescriptor/YZSeries.java
@@ -0,0 +1,38 @@
+package ch.psi.fda.vdescriptor;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+
+/**
+ * In a YZSeries the Y components hold an data array in which the index i the x and the value the y value.
+ */
+@XmlRootElement(name="yzseries")
+public class YZSeries extends Series {
+
+ private String y = null;
+ private String z = null;
+
+ public YZSeries(){
+ }
+
+ public YZSeries(String y, String z){
+ this.y = y;
+ this.z = z;
+ }
+
+ @XmlAttribute
+ public String getY() {
+ return y;
+ }
+ public void setY(String y) {
+ this.y = y;
+ }
+ @XmlAttribute
+ public String getZ() {
+ return z;
+ }
+ public void setZ(String z) {
+ this.z = z;
+ }
+}
diff --git a/src/test/java/ch/psi/fda/vdescriptor/VDescriptorTest.java b/src/test/java/ch/psi/fda/vdescriptor/VDescriptorTest.java
new file mode 100644
index 0000000..1501c4f
--- /dev/null
+++ b/src/test/java/ch/psi/fda/vdescriptor/VDescriptorTest.java
@@ -0,0 +1,43 @@
+package ch.psi.fda.vdescriptor;
+
+import java.io.File;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class VDescriptorTest {
+
+ private static final Logger logger = Logger.getLogger(VDescriptorTest.class.getName());
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() throws JAXBException {
+ try {
+ JAXBContext context = JAXBContext.newInstance(VDescriptor.class);
+ Unmarshaller u = context.createUnmarshaller();
+
+ VDescriptor descriptor = (VDescriptor) u.unmarshal(new File("src/test/resources/vdescriptor.xml"));
+ for (Plot p : descriptor.getPlots()) {
+ logger.info(p.getClass().getName());
+ }
+ } catch (JAXBException e) {
+ e.printStackTrace();
+ throw e;
+ }
+
+ }
+
+}
diff --git a/src/test/resources/vdescriptor.xml b/src/test/resources/vdescriptor.xml
new file mode 100644
index 0000000..caf5fb4
--- /dev/null
+++ b/src/test/resources/vdescriptor.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file