diff --git a/pom.xml b/pom.xml
index 5c2d28c89..eb1289eff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,10 @@
-
+
+ ch.eitchnet
+ ch.eitchnet.utils
+
diff --git a/src/main/java/li/strolch/model/GroupedParameterizedElement.java b/src/main/java/li/strolch/model/GroupedParameterizedElement.java
index 647092943..d09b973ed 100644
--- a/src/main/java/li/strolch/model/GroupedParameterizedElement.java
+++ b/src/main/java/li/strolch/model/GroupedParameterizedElement.java
@@ -32,7 +32,6 @@ import ch.eitchnet.utils.helper.StringHelper;
/**
* @author Robert von Burg
- *
*/
public abstract class GroupedParameterizedElement extends AbstractStrolchElement {
diff --git a/src/main/java/li/strolch/model/OrderVisitor.java b/src/main/java/li/strolch/model/OrderVisitor.java
new file mode 100644
index 000000000..c076175e3
--- /dev/null
+++ b/src/main/java/li/strolch/model/OrderVisitor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model;
+
+/**
+ * @author Robert von Burg
+ */
+public interface OrderVisitor extends StrolchElementVisitor {
+
+ @Override
+ public void visit(Order element);
+}
diff --git a/src/main/java/li/strolch/model/ResourceVisitor.java b/src/main/java/li/strolch/model/ResourceVisitor.java
new file mode 100644
index 000000000..db8c78ba2
--- /dev/null
+++ b/src/main/java/li/strolch/model/ResourceVisitor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model;
+
+/**
+ * @author Robert von Burg
+ */
+public interface ResourceVisitor extends StrolchElementVisitor{
+
+ @Override
+ public void visit(Resource element);
+}
diff --git a/src/main/java/li/strolch/model/StrolchElementVisitor.java b/src/main/java/li/strolch/model/StrolchElementVisitor.java
new file mode 100644
index 000000000..605f3014f
--- /dev/null
+++ b/src/main/java/li/strolch/model/StrolchElementVisitor.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model;
+
+/**
+ * @author Robert von Burg
+ */
+public interface StrolchElementVisitor {
+
+ public void visit(T element);
+}
diff --git a/src/main/java/li/strolch/model/Tags.java b/src/main/java/li/strolch/model/Tags.java
index 212d04f5e..e2d7b86a9 100644
--- a/src/main/java/li/strolch/model/Tags.java
+++ b/src/main/java/li/strolch/model/Tags.java
@@ -18,17 +18,18 @@ package li.strolch.model;
@SuppressWarnings("nls")
public class Tags {
- public static final String ID="Id";
- public static final String NAME="Name";
+ public static final String CDATA = "CDATA";
+ public static final String ID = "Id";
+ public static final String NAME = "Name";
public static final String TYPE = "Type";
- public static final String DATE="Date";
- public static final String STATE="State";
- public static final String VALUE="Value";
- public static final String INTERPRETATION="Interpretation";
- public static final String UOM="Uom";
- public static final String HIDDEN="Hidden";
- public static final String PARAMETER="Parameter";
- public static final String PARAMETERIZED_ELEMENT="ParameterizedElement";
+ public static final String DATE = "Date";
+ public static final String STATE = "State";
+ public static final String VALUE = "Value";
+ public static final String INTERPRETATION = "Interpretation";
+ public static final String UOM = "Uom";
+ public static final String HIDDEN = "Hidden";
+ public static final String PARAMETER = "Parameter";
+ public static final String PARAMETERIZED_ELEMENT = "ParameterizedElement";
public static final String RESOURCE = "Resource";
public static final String ORDER = "Order";
public static final String PARAMETER_BAG = "ParameterBag";
diff --git a/src/main/java/li/strolch/model/visitor/OrderDeepEqualsVisitor.java b/src/main/java/li/strolch/model/visitor/OrderDeepEqualsVisitor.java
new file mode 100644
index 000000000..497c46e29
--- /dev/null
+++ b/src/main/java/li/strolch/model/visitor/OrderDeepEqualsVisitor.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.visitor;
+
+import li.strolch.model.Order;
+import li.strolch.model.OrderVisitor;
+
+/**
+ * @author Robert von Burg
+ */
+public class OrderDeepEqualsVisitor extends StrolchElementDeepEqualsVisitor implements OrderVisitor {
+
+ private Order srcOrder;
+
+ public OrderDeepEqualsVisitor(Order srcOrder) {
+ this.srcOrder = srcOrder;
+ }
+
+ @Override
+ public void visit(Order dstOrder) {
+ deepEquals(this.srcOrder, dstOrder);
+ }
+}
diff --git a/src/main/java/li/strolch/model/visitor/ResourceDeepEqualsVisitor.java b/src/main/java/li/strolch/model/visitor/ResourceDeepEqualsVisitor.java
new file mode 100644
index 000000000..d74918a6f
--- /dev/null
+++ b/src/main/java/li/strolch/model/visitor/ResourceDeepEqualsVisitor.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.visitor;
+
+import li.strolch.model.Resource;
+import li.strolch.model.ResourceVisitor;
+
+/**
+ * @author Robert von Burg
+ */
+public class ResourceDeepEqualsVisitor extends StrolchElementDeepEqualsVisitor implements ResourceVisitor {
+
+ private Resource srcRes;
+
+ public ResourceDeepEqualsVisitor(Resource sourceRes) {
+ this.srcRes = sourceRes;
+ }
+
+ @Override
+ public void visit(Resource dstRes) {
+ deepEquals(this.srcRes, dstRes);
+ }
+}
diff --git a/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java b/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java
new file mode 100644
index 000000000..0b927fdcb
--- /dev/null
+++ b/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.visitor;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import li.strolch.model.GroupedParameterizedElement;
+import li.strolch.model.Locator;
+import li.strolch.model.Order;
+import li.strolch.model.ParameterBag;
+import li.strolch.model.Resource;
+import li.strolch.model.StrolchElement;
+import li.strolch.model.parameter.Parameter;
+
+/**
+ * @author Robert von Burg
+ *
+ */
+public class StrolchElementDeepEqualsVisitor {
+
+ private List mismatchedLocators;
+
+ public StrolchElementDeepEqualsVisitor() {
+ this.mismatchedLocators = new ArrayList<>();
+ }
+
+ /**
+ * @return the mismatchedLocators
+ */
+ public List getMismatchedLocators() {
+ return this.mismatchedLocators;
+ }
+
+ public boolean isEqual() {
+ return this.mismatchedLocators.isEmpty();
+ }
+
+ protected void deepEquals(StrolchElement srcElement, StrolchElement dstElement) {
+ if (!srcElement.getName().equals(dstElement.getName()))
+ this.mismatchedLocators.add(dstElement.getLocator());
+ if (!srcElement.getType().equals(dstElement.getType()))
+ this.mismatchedLocators.add(dstElement.getLocator());
+ }
+
+ protected void deepEquals(Order srcOrder, Order dstOrder) {
+ deepEquals((StrolchElement) srcOrder, (StrolchElement) dstOrder);
+ if (!srcOrder.getState().equals(dstOrder.getState()))
+ this.mismatchedLocators.add(dstOrder.getLocator());
+ if (!srcOrder.getDate().equals(dstOrder.getDate()))
+ this.mismatchedLocators.add(dstOrder.getLocator());
+
+ deepEquals((GroupedParameterizedElement) srcOrder, (GroupedParameterizedElement) dstOrder);
+ }
+
+ protected void deepEquals(Resource srcRes, Resource dstRes) {
+ deepEquals((StrolchElement) srcRes, (StrolchElement) dstRes);
+ deepEquals((GroupedParameterizedElement) srcRes, (GroupedParameterizedElement) dstRes);
+ }
+
+ protected void deepEquals(GroupedParameterizedElement srcElement, GroupedParameterizedElement dstElement) {
+ Set srcBagKeySet = srcElement.getParameterBagKeySet();
+ for (String bagKey : srcBagKeySet) {
+ ParameterBag srcBag = srcElement.getParameterBag(bagKey);
+
+ if (!dstElement.hasParameterBag(bagKey)) {
+ this.mismatchedLocators.add(srcBag.getLocator());
+ continue;
+ }
+
+ ParameterBag dstBag = dstElement.getParameterBag(bagKey);
+ deepEquals(srcBag, dstBag);
+ }
+
+ Set dstBagKeySet = dstElement.getParameterBagKeySet();
+ for (String bagKey : dstBagKeySet) {
+ if (!srcElement.hasParameterBag(bagKey)) {
+ ParameterBag dstBag = dstElement.getParameterBag(bagKey);
+ this.mismatchedLocators.add(dstBag.getLocator());
+ }
+ }
+ }
+
+ protected void deepEquals(ParameterBag srcBag, ParameterBag dstBag) {
+ deepEquals((StrolchElement) srcBag, (StrolchElement) dstBag);
+
+ Set srcParamKeySet = srcBag.getParameterKeySet();
+ for (String paramKey : srcParamKeySet) {
+ Parameter> srcParam = srcBag.getParameter(paramKey);
+ if (!dstBag.hasParameter(paramKey)) {
+ this.mismatchedLocators.add(srcParam.getLocator());
+ continue;
+ }
+
+ Parameter> dstParam = dstBag.getParameter(paramKey);
+ deepEquals(srcParam, dstParam);
+ }
+
+ Set dstParamKeySet = dstBag.getParameterKeySet();
+ for (String paramKey : dstParamKeySet) {
+ if (!srcBag.hasParameter(paramKey)) {
+ Parameter> dstParam = dstBag.getParameter(paramKey);
+ this.mismatchedLocators.add(dstParam.getLocator());
+ }
+ }
+ }
+
+ protected void deepEquals(Parameter> srcParam, Parameter> dstParam) {
+ deepEquals((StrolchElement) srcParam, (StrolchElement) dstParam);
+ if (!srcParam.getUom().equals(dstParam.getUom()))
+ this.mismatchedLocators.add(dstParam.getLocator());
+ if (!srcParam.getInterpretation().equals(dstParam.getInterpretation()))
+ this.mismatchedLocators.add(dstParam.getLocator());
+ if (srcParam.isHidden() != dstParam.isHidden())
+ this.mismatchedLocators.add(dstParam.getLocator());
+
+ if (!srcParam.getValue().equals(dstParam.getValue()))
+ this.mismatchedLocators.add(dstParam.getLocator());
+ }
+
+ public static boolean isEqual(Order srcOrder, Order dstOrder) {
+ OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(srcOrder);
+ visitor.visit(srcOrder);
+ return visitor.isEqual();
+ }
+
+ public static boolean isEqual(Resource srcRes, Resource dstRes) {
+ ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes);
+ visitor.visit(srcRes);
+ return visitor.isEqual();
+ }
+}
diff --git a/src/main/java/li/strolch/model/xml/OrderToDomVisitor.java b/src/main/java/li/strolch/model/xml/OrderToDomVisitor.java
new file mode 100644
index 000000000..941f7d616
--- /dev/null
+++ b/src/main/java/li/strolch/model/xml/OrderToDomVisitor.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.xml;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import li.strolch.model.Order;
+import li.strolch.model.OrderVisitor;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import ch.eitchnet.utils.helper.DomUtil;
+
+/**
+ * @author Robert von Burg
+ */
+public class OrderToDomVisitor implements OrderVisitor {
+
+ private Document document;
+
+ /**
+ * @return the document
+ */
+ public Document getDocument() {
+ return this.document;
+ }
+
+ @Override
+ public void visit(Order order) {
+ DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder();
+ Document document = documentBuilder.getDOMImplementation().createDocument(null, null, null);
+
+ Element orderDom = order.toDom(document);
+ document.appendChild(orderDom);
+ this.document = document;
+ }
+}
diff --git a/src/main/java/li/strolch/model/xml/OrderToSaxVisitor.java b/src/main/java/li/strolch/model/xml/OrderToSaxVisitor.java
new file mode 100644
index 000000000..428261ebe
--- /dev/null
+++ b/src/main/java/li/strolch/model/xml/OrderToSaxVisitor.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.xml;
+
+import java.text.MessageFormat;
+
+import li.strolch.model.Order;
+import li.strolch.model.OrderVisitor;
+import li.strolch.model.Tags;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Robert von Burg
+ */
+public class OrderToSaxVisitor extends StrolchElementToDomVisitor implements OrderVisitor {
+
+ public OrderToSaxVisitor(ContentHandler contentHandler) {
+ super(contentHandler);
+ }
+
+ @Override
+ public void visit(Order order) {
+ try {
+
+ this.contentHandler.startElement(null, null, Tags.ORDER, attributesFor(order));
+ toSax(order);
+ this.contentHandler.endElement(null, null, Tags.ORDER);
+
+ } catch (SAXException e) {
+ String msg = "Failed to transform Order {0} to XML due to {1}"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, order.getLocator(), e.getMessage());
+ throw new RuntimeException(msg, e);
+ }
+ }
+}
diff --git a/src/main/java/li/strolch/model/xml/ResourceToDomVisitor.java b/src/main/java/li/strolch/model/xml/ResourceToDomVisitor.java
new file mode 100644
index 000000000..8585ecddf
--- /dev/null
+++ b/src/main/java/li/strolch/model/xml/ResourceToDomVisitor.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.xml;
+
+import javax.xml.parsers.DocumentBuilder;
+
+import li.strolch.model.Resource;
+import li.strolch.model.ResourceVisitor;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import ch.eitchnet.utils.helper.DomUtil;
+
+/**
+ * @author Robert von Burg
+ */
+public class ResourceToDomVisitor implements ResourceVisitor {
+
+ private Document document;
+
+ /**
+ * @return the document
+ */
+ public Document getDocument() {
+ return this.document;
+ }
+
+ @Override
+ public void visit(Resource resource) {
+ DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder();
+ Document document = documentBuilder.getDOMImplementation().createDocument(null, null, null);
+
+ Element resourceDom = resource.toDom(document);
+ document.appendChild(resourceDom);
+ this.document = document;
+ }
+}
diff --git a/src/main/java/li/strolch/model/xml/ResourceToSaxVisitor.java b/src/main/java/li/strolch/model/xml/ResourceToSaxVisitor.java
new file mode 100644
index 000000000..3bafed894
--- /dev/null
+++ b/src/main/java/li/strolch/model/xml/ResourceToSaxVisitor.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.xml;
+
+import java.text.MessageFormat;
+
+import li.strolch.model.Resource;
+import li.strolch.model.ResourceVisitor;
+import li.strolch.model.Tags;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Robert von Burg
+ */
+public class ResourceToSaxVisitor extends StrolchElementToDomVisitor implements ResourceVisitor {
+
+ public ResourceToSaxVisitor(ContentHandler contentHandler) {
+ super(contentHandler);
+ }
+
+ @Override
+ public void visit(Resource res) {
+ try {
+
+ this.contentHandler.startElement(null, null, Tags.RESOURCE, attributesFor(res));
+ toSax(res);
+ this.contentHandler.endElement(null, null, Tags.RESOURCE);
+
+ } catch (SAXException e) {
+ String msg = "Failed to transform Resource {0} to XML due to {1}"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, res.getLocator(), e.getMessage());
+ throw new RuntimeException(msg, e);
+ }
+ }
+}
diff --git a/src/main/java/li/strolch/model/xml/SimpleStrolchElementListener.java b/src/main/java/li/strolch/model/xml/SimpleStrolchElementListener.java
new file mode 100644
index 000000000..79871b281
--- /dev/null
+++ b/src/main/java/li/strolch/model/xml/SimpleStrolchElementListener.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import li.strolch.model.Order;
+import li.strolch.model.Resource;
+
+/**
+ * @author Robert von Burg
+ */
+public class SimpleStrolchElementListener implements StrolchElementListener {
+
+ private List resources;
+ private List orders;
+
+ @Override
+ public void notifyResource(Resource resource) {
+ if (this.resources == null)
+ this.resources = new ArrayList<>();
+ this.resources.add(resource);
+ }
+
+ @Override
+ public void notifyOrder(Order order) {
+ if (this.orders == null)
+ this.orders = new ArrayList<>();
+ this.orders.add(order);
+ }
+
+ /**
+ * @return the resources
+ */
+ public List getResources() {
+ return this.resources;
+ }
+
+ /**
+ * @return the orders
+ */
+ public List getOrders() {
+ return this.orders;
+ }
+}
diff --git a/src/main/java/li/strolch/model/xml/StrolchElementToDomVisitor.java b/src/main/java/li/strolch/model/xml/StrolchElementToDomVisitor.java
new file mode 100644
index 000000000..dfd939880
--- /dev/null
+++ b/src/main/java/li/strolch/model/xml/StrolchElementToDomVisitor.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.xml;
+
+import java.util.Set;
+
+import li.strolch.model.GroupedParameterizedElement;
+import li.strolch.model.Order;
+import li.strolch.model.ParameterBag;
+import li.strolch.model.StrolchElement;
+import li.strolch.model.Tags;
+import li.strolch.model.parameter.Parameter;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.AttributesImpl;
+
+import ch.eitchnet.utils.iso8601.ISO8601FormatFactory;
+
+/**
+ * @author Robert von Burg
+ */
+public abstract class StrolchElementToDomVisitor {
+
+ protected ContentHandler contentHandler;
+
+ protected StrolchElementToDomVisitor(ContentHandler contentHandler) {
+ this.contentHandler = contentHandler;
+ }
+
+ protected AttributesImpl attributesFor(StrolchElement element) {
+ AttributesImpl attributes = new AttributesImpl();
+ attributes.addAttribute(null, null, Tags.ID, Tags.CDATA, element.getId());
+ attributes.addAttribute(null, null, Tags.NAME, Tags.CDATA, element.getName());
+ attributes.addAttribute(null, null, Tags.TYPE, Tags.CDATA, element.getType());
+ return attributes;
+ }
+
+ protected AttributesImpl attributesFor(Order order) {
+ AttributesImpl attributes = attributesFor((StrolchElement) order);
+ attributes.addAttribute(null, null, Tags.STATE, Tags.CDATA, order.getState().name());
+ attributes.addAttribute(null, null, Tags.DATE, Tags.CDATA,
+ ISO8601FormatFactory.getInstance().formatDate(order.getDate()));
+ return attributes;
+ }
+
+ protected AttributesImpl attributesFor(Parameter> parameter) {
+ AttributesImpl attributes = attributesFor((StrolchElement) parameter);
+ attributes.addAttribute(null, null, Tags.VALUE, Tags.CDATA, parameter.getValueAsString());
+
+ if (!Parameter.UOM_NONE.equals(parameter.getUom()))
+ attributes.addAttribute(null, null, Tags.UOM, Tags.CDATA, parameter.getUom());
+ if (!Parameter.INTERPRETATION_NONE.equals(parameter.getInterpretation()))
+ attributes.addAttribute(null, null, Tags.INTERPRETATION, Tags.CDATA, parameter.getInterpretation());
+ if (parameter.isHidden())
+ attributes.addAttribute(null, null, Tags.HIDDEN, Tags.CDATA, Boolean.toString(parameter.isHidden()));
+
+ return attributes;
+ }
+
+ protected void toSax(GroupedParameterizedElement parameterizedElement) throws SAXException {
+ Set bagKeySet = parameterizedElement.getParameterBagKeySet();
+ for (String bagKey : bagKeySet) {
+ ParameterBag parameterBag = parameterizedElement.getParameterBag(bagKey);
+ this.contentHandler.startElement(null, null, Tags.PARAMETER_BAG, attributesFor(parameterBag));
+
+ Set parameterKeySet = parameterBag.getParameterKeySet();
+ for (String paramKey : parameterKeySet) {
+ Parameter> parameter = parameterBag.getParameter(paramKey);
+ this.contentHandler.startElement(null, null, Tags.PARAMETER, attributesFor(parameter));
+ this.contentHandler.endElement(null, null, Tags.PARAMETER);
+ }
+
+ this.contentHandler.endElement(null, null, Tags.PARAMETER_BAG);
+ }
+ }
+}
diff --git a/src/main/java/li/strolch/model/xml/XmlModelDefaultHandler.java b/src/main/java/li/strolch/model/xml/XmlModelDefaultHandler.java
index 0195c476f..c47649f2a 100644
--- a/src/main/java/li/strolch/model/xml/XmlModelDefaultHandler.java
+++ b/src/main/java/li/strolch/model/xml/XmlModelDefaultHandler.java
@@ -15,16 +15,10 @@
*/
package li.strolch.model.xml;
-import java.io.File;
-import java.io.IOException;
import java.text.MessageFormat;
import java.util.Date;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import li.strolch.exception.StrolchException;
+import li.strolch.model.GroupedParameterizedElement;
import li.strolch.model.Order;
import li.strolch.model.ParameterBag;
import li.strolch.model.Resource;
@@ -54,20 +48,16 @@ import ch.eitchnet.utils.iso8601.ISO8601FormatFactory;
*/
public class XmlModelDefaultHandler extends DefaultHandler {
- private static final Logger logger = LoggerFactory.getLogger(XmlModelDefaultHandler.class);
+ protected static final Logger logger = LoggerFactory.getLogger(XmlModelDefaultHandler.class);
- private StrolchElementListener listener;
- private File modelFile;
+ protected StrolchElementListener listener;
+ protected XmlModelStatistics statistics;
- private Resource resource;
- private Order order;
+ private GroupedParameterizedElement parameterizedElement;
private ParameterBag pBag;
- private XmlModelStatistics statistics;
-
- public XmlModelDefaultHandler(StrolchElementListener listener, File modelFile) {
+ public XmlModelDefaultHandler(StrolchElementListener listener) {
this.listener = listener;
- this.modelFile = modelFile;
this.statistics = new XmlModelStatistics();
}
@@ -94,7 +84,7 @@ public class XmlModelDefaultHandler extends DefaultHandler {
String resName = attributes.getValue(Tags.NAME);
String resType = attributes.getValue(Tags.TYPE);
Resource resource = new Resource(resId, resName, resType);
- this.resource = resource;
+ this.parameterizedElement = resource;
break;
case Tags.ORDER:
@@ -112,7 +102,7 @@ public class XmlModelDefaultHandler extends DefaultHandler {
State orderState = State.valueOf(orderStateS);
order.setState(orderState);
}
- this.order = order;
+ this.parameterizedElement = order;
break;
case Tags.PARAMETER_BAG:
@@ -121,6 +111,7 @@ public class XmlModelDefaultHandler extends DefaultHandler {
String pBagType = attributes.getValue(Tags.TYPE);
ParameterBag pBag = new ParameterBag(pBagId, pBagName, pBagType);
this.pBag = pBag;
+ this.parameterizedElement.addParameterBag(pBag);
break;
case Tags.PARAMETER:
@@ -165,25 +156,6 @@ public class XmlModelDefaultHandler extends DefaultHandler {
this.pBag.addParameter(param);
break;
- case Tags.INCLUDE_FILE:
-
- String includeFileS = attributes.getValue(Tags.FILE);
- if (StringHelper.isEmpty(includeFileS))
- throw new IllegalArgumentException(MessageFormat.format(
- "The attribute {0} is missing for IncludeFile!", Tags.FILE)); //$NON-NLS-1$
- File includeFile = new File(this.modelFile.getParentFile(), includeFileS);
- if (!includeFile.exists() || !includeFile.canRead()) {
- String msg = "The IncludeFile does not exist, or is not readable. Source model: {0} with IncludeFile: {1}"; //$NON-NLS-1$
- msg = MessageFormat.format(msg, this.modelFile.getName(), includeFileS);
- throw new IllegalArgumentException(msg);
- }
-
- XmlModelDefaultHandler handler = new XmlModelDefaultHandler(this.listener, includeFile);
- handler.parseFile();
- this.statistics.nrOfOrders += handler.statistics.nrOfOrders;
- this.statistics.nrOfResources += handler.statistics.nrOfResources;
-
- break;
default:
throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$
}
@@ -196,14 +168,14 @@ public class XmlModelDefaultHandler extends DefaultHandler {
case Tags.STROLCH_MODEL:
break;
case Tags.RESOURCE:
- this.listener.notifyResource(this.resource);
+ this.listener.notifyResource((Resource) this.parameterizedElement);
this.statistics.nrOfResources++;
- this.resource = null;
+ this.parameterizedElement = null;
break;
case Tags.ORDER:
- this.listener.notifyOrder(this.order);
+ this.listener.notifyOrder((Order) this.parameterizedElement);
this.statistics.nrOfOrders++;
- this.order = null;
+ this.parameterizedElement = null;
break;
case Tags.PARAMETER_BAG:
this.pBag = null;
@@ -217,30 +189,6 @@ public class XmlModelDefaultHandler extends DefaultHandler {
}
}
- public void parseFile() {
-
- try {
- long startNanos = System.nanoTime();
- this.statistics.startTime = new Date();
-
- SAXParserFactory spf = SAXParserFactory.newInstance();
- SAXParser sp = spf.newSAXParser();
-
- sp.parse(this.modelFile, this);
-
- long endNanos = System.nanoTime();
- this.statistics.durationNanos = endNanos - startNanos;
- String msg = "SAX parsed model file {0} took {1}"; //$NON-NLS-1$
- logger.info(MessageFormat.format(msg, this.modelFile.getAbsolutePath(),
- StringHelper.formatNanoDuration(this.statistics.durationNanos)));
-
- } catch (ParserConfigurationException | SAXException | IOException e) {
-
- String msg = "Parsing failed due to internal error: {0}"; //$NON-NLS-1$
- throw new StrolchException(MessageFormat.format(msg, e.getMessage()), e);
- }
- }
-
public static class XmlModelStatistics {
public Date startTime;
public long durationNanos;
diff --git a/src/main/java/li/strolch/model/xml/XmlModelFileHandler.java b/src/main/java/li/strolch/model/xml/XmlModelFileHandler.java
new file mode 100644
index 000000000..d75b1261f
--- /dev/null
+++ b/src/main/java/li/strolch/model/xml/XmlModelFileHandler.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.Date;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import li.strolch.exception.StrolchException;
+import li.strolch.model.Tags;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import ch.eitchnet.utils.helper.StringHelper;
+
+/**
+ * @author Robert von Burg
+ *
+ */
+public class XmlModelFileHandler extends XmlModelDefaultHandler {
+
+ private File modelFile;
+
+ /**
+ * @param listener
+ * @param modelFile
+ */
+ public XmlModelFileHandler(StrolchElementListener listener, File modelFile) {
+ super(listener);
+ this.modelFile = modelFile;
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+
+ switch (qName) {
+
+ case Tags.INCLUDE_FILE:
+
+ String includeFileS = attributes.getValue(Tags.FILE);
+ if (StringHelper.isEmpty(includeFileS))
+ throw new IllegalArgumentException(MessageFormat.format(
+ "The attribute {0} is missing for IncludeFile!", Tags.FILE)); //$NON-NLS-1$
+ File includeFile = new File(this.modelFile.getParentFile(), includeFileS);
+ if (!includeFile.exists() || !includeFile.canRead()) {
+ String msg = "The IncludeFile does not exist, or is not readable. Source model: {0} with IncludeFile: {1}"; //$NON-NLS-1$
+ msg = MessageFormat.format(msg, this.modelFile.getName(), includeFileS);
+ throw new IllegalArgumentException(msg);
+ }
+
+ XmlModelFileHandler handler = new XmlModelFileHandler(this.listener, includeFile);
+ handler.parseFile();
+ this.statistics.nrOfOrders += handler.statistics.nrOfOrders;
+ this.statistics.nrOfResources += handler.statistics.nrOfResources;
+
+ break;
+ default:
+ super.startElement(uri, localName, qName, attributes);
+ }
+ }
+
+ public void parseFile() {
+
+ try {
+ long startNanos = System.nanoTime();
+ this.statistics.startTime = new Date();
+
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ SAXParser sp = spf.newSAXParser();
+
+ sp.parse(this.modelFile, this);
+
+ long endNanos = System.nanoTime();
+ this.statistics.durationNanos = endNanos - startNanos;
+ String msg = "SAX parsed model file {0} took {1}"; //$NON-NLS-1$
+ logger.info(MessageFormat.format(msg, this.modelFile.getAbsolutePath(),
+ StringHelper.formatNanoDuration(this.statistics.durationNanos)));
+
+ } catch (ParserConfigurationException | SAXException | IOException e) {
+
+ String msg = "Parsing failed due to internal error: {0}"; //$NON-NLS-1$
+ throw new StrolchException(MessageFormat.format(msg, e.getMessage()), e);
+ }
+ }
+}
diff --git a/src/test/java/li/strolch/model/ModelTest.java b/src/test/java/li/strolch/model/ModelTest.java
index cd2d4bc98..86f4cccd2 100644
--- a/src/test/java/li/strolch/model/ModelTest.java
+++ b/src/test/java/li/strolch/model/ModelTest.java
@@ -16,16 +16,13 @@
package li.strolch.model;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Date;
-import li.strolch.model.ModelGenerator;
-import li.strolch.model.Order;
-import li.strolch.model.ParameterBag;
-import li.strolch.model.Resource;
-import li.strolch.model.State;
import li.strolch.model.parameter.BooleanParameter;
import li.strolch.model.parameter.DateParameter;
import li.strolch.model.parameter.FloatParameter;
@@ -33,6 +30,8 @@ import li.strolch.model.parameter.IntegerParameter;
import li.strolch.model.parameter.LongParameter;
import li.strolch.model.parameter.StringListParameter;
import li.strolch.model.parameter.StringParameter;
+import li.strolch.model.visitor.OrderDeepEqualsVisitor;
+import li.strolch.model.visitor.ResourceDeepEqualsVisitor;
import org.junit.Test;
@@ -55,6 +54,39 @@ public class ModelTest {
validateBag(bag);
}
+ @Test
+ public void shouldPerformDeepResourceEquals() {
+ Resource srcRes = ModelGenerator.createResource("@res01", "Test resource", "MyType");
+ Resource dstRes = ModelGenerator.createResource("@res01", "Test resource", "MyType");
+ ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes);
+ visitor.visit(dstRes);
+ assertTrue("Same Resource should be deep equal!", visitor.isEqual());
+ }
+
+ @Test
+ public void shouldFailDeepResourceEquals1() {
+ Resource srcRes = ModelGenerator.createResource("@res01", "Test resource", "MyType");
+ Resource dstRes = ModelGenerator.createResource("@res01", "Test resource", "MyType");
+ ParameterBag bag = dstRes.getParameterBag(ModelGenerator.BAG_ID);
+ bag.setName("Bla bla");
+ FloatParameter fParam = bag.getParameter(ModelGenerator.PARAM_FLOAT_ID);
+ fParam.setValue(23434234.234);
+ fParam.setName("Ohla");
+ ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes);
+ visitor.visit(dstRes);
+ assertFalse("Resource should not be same if param is changed!", visitor.isEqual());
+ assertEquals("Three changes should be registered", 3, visitor.getMismatchedLocators().size());
+ }
+
+ @Test
+ public void shouldPerformDeepOrderEquals() {
+ Order srcOrder = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", new Date(), State.OPEN);
+ Order dstOrder = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", new Date(), State.OPEN);
+ OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(srcOrder);
+ visitor.visit(dstOrder);
+ assertTrue("Same Order should be deep equal!", visitor.isEqual());
+ }
+
public static void validateBag(ParameterBag bag) {
assertNotNull(bag);
diff --git a/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java b/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java
index 2326c7e1d..2a0ecb803 100644
--- a/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java
+++ b/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java
@@ -21,11 +21,9 @@ import java.io.File;
import java.util.HashMap;
import java.util.Map;
-import li.strolch.model.Order;
-import li.strolch.model.Resource;
import li.strolch.model.xml.StrolchElementListener;
-import li.strolch.model.xml.XmlModelDefaultHandler;
import li.strolch.model.xml.XmlModelDefaultHandler.XmlModelStatistics;
+import li.strolch.model.xml.XmlModelFileHandler;
import org.junit.Test;
import org.slf4j.Logger;
@@ -60,7 +58,7 @@ public class XmlModelDefaultHandlerTest {
orderMap.put(order.getId(), order);
}
};
- XmlModelDefaultHandler handler = new XmlModelDefaultHandler(listener, file);
+ XmlModelFileHandler handler = new XmlModelFileHandler(listener, file);
handler.parseFile();
assertEquals(3, resourceMap.size());
diff --git a/src/test/java/li/strolch/model/XmlToDomTest.java b/src/test/java/li/strolch/model/XmlToDomTest.java
new file mode 100644
index 000000000..76e543665
--- /dev/null
+++ b/src/test/java/li/strolch/model/XmlToDomTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Robert von Burg
+ *
+ * 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 li.strolch.model;
+
+import static org.junit.Assert.assertTrue;
+import li.strolch.model.visitor.StrolchElementDeepEqualsVisitor;
+import li.strolch.model.xml.OrderToDomVisitor;
+import li.strolch.model.xml.ResourceToDomVisitor;
+
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Robert von Burg
+ *
+ */
+@SuppressWarnings("nls")
+public class XmlToDomTest extends ModelTest {
+
+ @Test
+ public void shouldFormatAndParseOrder() {
+
+ Order order = ModelGenerator.createOrder("@1", "My Order 1", "MyOrder");
+
+ OrderToDomVisitor domVisitor = new OrderToDomVisitor();
+ domVisitor.visit(order);
+ Document document = domVisitor.getDocument();
+
+ Element rootElement = document.getDocumentElement();
+ Order parsedOrder = new Order(rootElement);
+
+ assertTrue("To DOM and back should equal same Order!",
+ StrolchElementDeepEqualsVisitor.isEqual(order, parsedOrder));
+ }
+
+ @Test
+ public void shouldFormatAndParseResource() {
+
+ Resource resource = ModelGenerator.createResource("@1", "My Resource 1", "MyResource");
+
+ ResourceToDomVisitor domVisitor = new ResourceToDomVisitor();
+ domVisitor.visit(resource);
+ Document document = domVisitor.getDocument();
+
+ Element rootElement = document.getDocumentElement();
+ Resource parsedResource = new Resource(rootElement);
+
+ assertTrue("To DOM and back should equal same Resource!",
+ StrolchElementDeepEqualsVisitor.isEqual(resource, parsedResource));
+ }
+}