From 453b6b5bcbebadc38d556b8b51e58f7b8b900a43 Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Thu, 21 Aug 2014 17:42:10 +0200 Subject: [PATCH] [Major] added missing parsing of StrolchTimedState and fixed locators Locators are now a bit different, to handle finding StrolchTimedState as well, the Locator has the form: Resource///State/ Resource///Bag// --- src/main/java/li/strolch/model/Locator.java | 76 +++++++--- .../java/li/strolch/model/ParameterBag.java | 9 ++ .../strolch/model/ParameterizedElement.java | 8 +- src/main/java/li/strolch/model/Resource.java | 25 +-- .../strolch/model/StrolchModelConstants.java | 11 ++ src/main/java/li/strolch/model/Tags.java | 1 + .../model/parameter/AbstractParameter.java | 21 ++- .../li/strolch/model/parameter/Parameter.java | 41 ++--- .../timedstate/AbstractStrolchTimedState.java | 142 +++++++++++++++++- .../model/timedstate/StrolchTimedState.java | 74 +++++++++ .../li/strolch/model/timevalue/IValue.java | 5 + .../strolch/model/timevalue/impl/AString.java | 6 + .../model/timevalue/impl/BooleanValue.java | 5 + .../model/timevalue/impl/FloatValue.java | 5 + .../model/timevalue/impl/IntegerValue.java | 5 + .../model/timevalue/impl/StringSetValue.java | 30 +++- .../StrolchElementDeepEqualsVisitor.java | 7 +- .../model/visitor/TimedStateVisitor.java | 39 +++++ .../model/xml/AbstractToSaxWriterVisitor.java | 118 ++++++++++----- .../model/xml/StrolchElementToSaxVisitor.java | 7 +- .../strolch/model/xml/XmlModelSaxReader.java | 77 ++++++++++ src/test/java/li/strolch/model/ModelTest.java | 124 +++++++++++---- 22 files changed, 685 insertions(+), 151 deletions(-) create mode 100644 src/main/java/li/strolch/model/visitor/TimedStateVisitor.java diff --git a/src/main/java/li/strolch/model/Locator.java b/src/main/java/li/strolch/model/Locator.java index 186bc6c0f..0dd9f093c 100644 --- a/src/main/java/li/strolch/model/Locator.java +++ b/src/main/java/li/strolch/model/Locator.java @@ -57,9 +57,11 @@ public class Locator { /** * Constructs a new {@link Locator} with the given list of path elements * - * @param pathElements the elements making up the {@link Locator} + * @param pathElements + * the elements making up the {@link Locator} * - * @throws StrolchException if the path is invalid, meaning has less than two elements in it + * @throws StrolchException + * if the path is invalid, meaning has less than two elements in it */ public Locator(List pathElements) throws StrolchException { if (pathElements == null || pathElements.isEmpty()) { @@ -68,12 +70,27 @@ public class Locator { this.pathElements = Collections.unmodifiableList(new ArrayList(pathElements)); } + /** + * Constructs a new {@link Locator} using the given path parts + * + * @param path + * the path to parse for instantiate this {@link Locator} with elements + * + * @throws StrolchException + * if the path is invalid, meaning has less than two elements in it + */ + public Locator(String... path) throws StrolchException { + this.pathElements = Collections.unmodifiableList(Arrays.asList(path)); + } + /** * Constructs a new {@link Locator} by parsing the given string path. * - * @param path the path to parse for instantiate this {@link Locator} with elements + * @param path + * the path to parse for instantiate this {@link Locator} with elements * - * @throws StrolchException if the path is invalid, meaning has less than two elements in it + * @throws StrolchException + * if the path is invalid, meaning has less than two elements in it */ public Locator(String path) throws StrolchException { this.pathElements = Collections.unmodifiableList(parsePath(path)); @@ -82,8 +99,10 @@ public class Locator { /** * Internal constructor to append a sub path to a constructor * - * @param path the base path of the locator - * @param subPath the additional path + * @param path + * the base path of the locator + * @param subPath + * the additional path */ private Locator(List path, List subPath) { List fullPath = new ArrayList(); @@ -95,8 +114,10 @@ public class Locator { /** * Internal constructor to append a element to a constructor * - * @param path the base path of the locator - * @param element the additional element + * @param path + * the base path of the locator + * @param element + * the additional element */ private Locator(List path, String element) { List fullPath = new ArrayList(); @@ -126,7 +147,8 @@ public class Locator { /** * Returns a new {@link Locator} where the given sub path is appended to the locator * - * @param subPathElements the sub path to append + * @param subPathElements + * the sub path to append * * @return the new locator */ @@ -137,7 +159,8 @@ public class Locator { /** * Returns a new {@link Locator} where the given element is appended to the locator * - * @param element the element to append + * @param element + * the element to append * * @return the new locator */ @@ -157,12 +180,13 @@ public class Locator { /** * Parses the given path to a {@link List} of path elements by splitting the string with the {@link #PATH_SEPARATOR} * - * @param path the path to parse + * @param path + * the path to parse * * @return the list of path elements for the list * - * @throws StrolchException if the path is empty, or does not contain at least 2 elements separated by - * {@link #PATH_SEPARATOR} + * @throws StrolchException + * if the path is empty, or does not contain at least 2 elements separated by {@link #PATH_SEPARATOR} */ private List parsePath(String path) throws StrolchException { if (StringHelper.isEmpty(path)) { @@ -175,11 +199,13 @@ public class Locator { /** * Formats the given list of path elements to a String representation of the {@link Locator} * - * @param pathElements the locator elements + * @param pathElements + * the locator elements * * @return a string representation of the path elements * - * @throws StrolchException if the path elements does not contain at least two items + * @throws StrolchException + * if the path elements does not contain at least two items */ private String formatPath(List pathElements) throws StrolchException { StringBuilder sb = new StringBuilder(); @@ -229,17 +255,30 @@ public class Locator { /** * Instantiates a new immutable {@link Locator} instance from the given string * - * @param locatorPath the path from which to instantiate the locator + * @param locatorPath + * the path from which to instantiate the locator * @return the immutable {@link Locator} instance */ public static Locator valueOf(String locatorPath) { return new Locator(locatorPath); } + /** + * Instantiates a new immutable {@link Locator} instance from the given path parts + * + * @param path + * the path from which to instantiate the locator + * @return the immutable {@link Locator} instance + */ + public static Locator valueOf(String... path) { + return new Locator(path); + } + /** * Creates a new {@link LocatorBuilder} instance and appends the given root element tag to it * - * @param rootElement the first element on the {@link Locator} + * @param rootElement + * the first element on the {@link Locator} * * @return a new {@link LocatorBuilder} instance with the given root element tag as the first element */ @@ -267,7 +306,8 @@ public class Locator { /** * Append an element to the path * - * @param element the element to add + * @param element + * the element to add * * @return this instance for chaining */ diff --git a/src/main/java/li/strolch/model/ParameterBag.java b/src/main/java/li/strolch/model/ParameterBag.java index bd3fca218..2baff9fda 100644 --- a/src/main/java/li/strolch/model/ParameterBag.java +++ b/src/main/java/li/strolch/model/ParameterBag.java @@ -15,6 +15,8 @@ */ package li.strolch.model; +import li.strolch.model.Locator.LocatorBuilder; + import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -59,6 +61,13 @@ public class ParameterBag extends ParameterizedElement { return clone; } + @Override + public void fillLocator(LocatorBuilder lb) { + this.parent.fillLocator(lb); + lb.append(Tags.BAG); + lb.append(this.id); + } + @Override public Element toDom(Document doc) { diff --git a/src/main/java/li/strolch/model/ParameterizedElement.java b/src/main/java/li/strolch/model/ParameterizedElement.java index 6a8e2b9cd..b73655b6c 100644 --- a/src/main/java/li/strolch/model/ParameterizedElement.java +++ b/src/main/java/li/strolch/model/ParameterizedElement.java @@ -15,8 +15,6 @@ */ package li.strolch.model; -import ch.eitchnet.utils.dbc.DBC; - import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; @@ -40,6 +38,7 @@ import li.strolch.model.parameter.StringParameter; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import ch.eitchnet.utils.dbc.DBC; import ch.eitchnet.utils.helper.StringHelper; /** @@ -194,10 +193,7 @@ public abstract class ParameterizedElement extends AbstractStrolchElement { } @Override - public void fillLocator(LocatorBuilder lb) { - this.parent.fillLocator(lb); - lb.append(this.id); - } + public abstract void fillLocator(LocatorBuilder lb); @Override public Locator getLocator() { diff --git a/src/main/java/li/strolch/model/Resource.java b/src/main/java/li/strolch/model/Resource.java index 54a3bd5dd..2860e06df 100644 --- a/src/main/java/li/strolch/model/Resource.java +++ b/src/main/java/li/strolch/model/Resource.java @@ -15,7 +15,6 @@ */ package li.strolch.model; -import ch.eitchnet.utils.dbc.DBC; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; @@ -24,6 +23,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; + import li.strolch.exception.StrolchException; import li.strolch.model.Locator.LocatorBuilder; import li.strolch.model.timedstate.BooleanTimedState; @@ -31,11 +31,15 @@ import li.strolch.model.timedstate.FloatTimedState; import li.strolch.model.timedstate.IntegerTimedState; import li.strolch.model.timedstate.StringSetTimedState; import li.strolch.model.timedstate.StrolchTimedState; +import li.strolch.model.timevalue.IValue; import li.strolch.model.visitor.StrolchRootElementVisitor; + import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import ch.eitchnet.utils.dbc.DBC; + /** * @author Robert von Burg */ @@ -43,7 +47,7 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot private static final long serialVersionUID = 0L; - private Map> timedStateMap; + private Map>> timedStateMap; /** * Empty constructor @@ -79,16 +83,16 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot DBC.PRE.assertNotEmpty("Type must be set on TimedState for resource with id " + id, typeS); if (typeS.equals(FloatTimedState.TYPE)) { - StrolchTimedState timedState = new FloatTimedState(timedStateElem); + FloatTimedState timedState = new FloatTimedState(timedStateElem); addTimedState(timedState); } else if (typeS.equals(IntegerTimedState.TYPE)) { - StrolchTimedState timedState = new IntegerTimedState(timedStateElem); + IntegerTimedState timedState = new IntegerTimedState(timedStateElem); addTimedState(timedState); } else if (typeS.equals(BooleanTimedState.TYPE)) { - StrolchTimedState timedState = new BooleanTimedState(timedStateElem); + BooleanTimedState timedState = new BooleanTimedState(timedStateElem); addTimedState(timedState); } else if (typeS.equals(StringSetTimedState.TYPE)) { - StrolchTimedState timedState = new StringSetTimedState(timedStateElem); + StringSetTimedState timedState = new StringSetTimedState(timedStateElem); addTimedState(timedState); } else { String msg = "What kind of TimedState is this: {0}"; //$NON-NLS-1$ @@ -98,16 +102,17 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot } } + @SuppressWarnings("unchecked") public void addTimedState(StrolchTimedState strolchTimedState) { if (this.timedStateMap == null) { this.timedStateMap = new HashMap<>(); } - this.timedStateMap.put(strolchTimedState.getId(), strolchTimedState); + this.timedStateMap.put(strolchTimedState.getId(), (StrolchTimedState>) strolchTimedState); strolchTimedState.setParent(this); } - @SuppressWarnings({"rawtypes", "unchecked"}) + @SuppressWarnings({ "rawtypes", "unchecked" }) public T getTimedState(String id) { if (this.timedStateMap == null) { return null; @@ -115,7 +120,7 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot return (T) this.timedStateMap.get(id); } - @SuppressWarnings({"unchecked", "rawtypes"}) + @SuppressWarnings({ "unchecked", "rawtypes" }) public T removeTimedState(String id) { if (this.timedStateMap == null) { return null; @@ -130,7 +135,7 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot return new HashSet<>(this.timedStateMap.keySet()); } - public List> getTimedStates() { + public List>> getTimedStates() { if (this.timedStateMap == null) { return Collections.emptyList(); } diff --git a/src/main/java/li/strolch/model/StrolchModelConstants.java b/src/main/java/li/strolch/model/StrolchModelConstants.java index ae993ddfb..9db2dd829 100644 --- a/src/main/java/li/strolch/model/StrolchModelConstants.java +++ b/src/main/java/li/strolch/model/StrolchModelConstants.java @@ -20,4 +20,15 @@ public class StrolchModelConstants { * to an {@link Order} */ public static final String INTERPRETATION_ORDER_REF = "Order-Ref"; //$NON-NLS-1$ + + + /** + * This interpretation value indicates that the {@link Parameter} has no defined interpretation + */ + public static final String INTERPRETATION_NONE = "None"; //$NON-NLS-1$ + + /** + * This uom value indicates that the {@link Parameter} has no defined uom + */ + public static final String UOM_NONE = "None"; //$NON-NLS-1$ } diff --git a/src/main/java/li/strolch/model/Tags.java b/src/main/java/li/strolch/model/Tags.java index eb79a8fc2..c6b0d6e27 100644 --- a/src/main/java/li/strolch/model/Tags.java +++ b/src/main/java/li/strolch/model/Tags.java @@ -40,4 +40,5 @@ public class Tags { public static final String INCLUDE_FILE = "IncludeFile"; public static final String FILE = "file"; + public static final String BAG = "Bag"; } diff --git a/src/main/java/li/strolch/model/parameter/AbstractParameter.java b/src/main/java/li/strolch/model/parameter/AbstractParameter.java index 95ea81de5..18296b782 100644 --- a/src/main/java/li/strolch/model/parameter/AbstractParameter.java +++ b/src/main/java/li/strolch/model/parameter/AbstractParameter.java @@ -15,6 +15,9 @@ */ package li.strolch.model.parameter; +import static li.strolch.model.StrolchModelConstants.INTERPRETATION_NONE; +import static li.strolch.model.StrolchModelConstants.UOM_NONE; + import java.text.MessageFormat; import li.strolch.exception.StrolchException; @@ -82,7 +85,7 @@ public abstract class AbstractParameter extends AbstractStrolchElement implem @Override public void setInterpretation(String interpretation) { if (StringHelper.isEmpty(interpretation)) { - this.interpretation = Parameter.INTERPRETATION_NONE; + this.interpretation = INTERPRETATION_NONE; } else { this.interpretation = interpretation; } @@ -96,7 +99,7 @@ public abstract class AbstractParameter extends AbstractStrolchElement implem @Override public void setUom(String uom) { if (StringHelper.isEmpty(uom)) { - this.uom = Parameter.UOM_NONE; + this.uom = UOM_NONE; } else { this.uom = uom; } @@ -134,10 +137,10 @@ public abstract class AbstractParameter extends AbstractStrolchElement implem element.setAttribute(Tags.VALUE, getValueAsString()); - if (!this.interpretation.equals(Parameter.INTERPRETATION_NONE)) { + if (!this.interpretation.equals(INTERPRETATION_NONE)) { element.setAttribute(Tags.INTERPRETATION, this.interpretation); } - if (!this.uom.equals(Parameter.UOM_NONE)) { + if (!this.uom.equals(UOM_NONE)) { element.setAttribute(Tags.UOM, this.uom); } if (this.hidden) { @@ -196,8 +199,8 @@ public abstract class AbstractParameter extends AbstractStrolchElement implem } @Override - protected void fillLocator(LocatorBuilder locatorBuilder) { - locatorBuilder.append(this.id); + protected void fillLocator(LocatorBuilder lb) { + lb.append(this.id); } @Override @@ -211,9 +214,11 @@ public abstract class AbstractParameter extends AbstractStrolchElement implem /** * Validates that the value is legal. This is the case when it is not null in this implementation * - * @param value the value to check for this parameter instance + * @param value + * the value to check for this parameter instance * - * @throws StrolchException if the value is null + * @throws StrolchException + * if the value is null */ protected void validateValue(T value) throws StrolchException { if (value == null) { diff --git a/src/main/java/li/strolch/model/parameter/Parameter.java b/src/main/java/li/strolch/model/parameter/Parameter.java index 00b55a53a..f55b99594 100644 --- a/src/main/java/li/strolch/model/parameter/Parameter.java +++ b/src/main/java/li/strolch/model/parameter/Parameter.java @@ -22,20 +22,9 @@ import li.strolch.model.visitor.ParameterVisitor; /** * @author Robert von Burg - * */ public interface Parameter extends StrolchElement { - /** - * This interpretation value indicates that the {@link Parameter} has no defined interpretation - */ - public static final String INTERPRETATION_NONE = "None"; //$NON-NLS-1$ - - /** - * This uom value indicates that the {@link Parameter} has no defined uom - */ - public static final String UOM_NONE = "None"; //$NON-NLS-1$ - /** * the value of the parameter as string * @@ -100,24 +89,11 @@ public interface Parameter extends StrolchElement { */ public void setIndex(int index); - /** - * The {@link ParameterizedElement} parent to which this {@link Parameter} belongs - * - * @return - */ - @Override - public ParameterizedElement getParent(); - - /** - * Sets the parent for this {@link Parameter} - */ - public void setParent(ParameterizedElement parent); - /** * Returns the interpretation of this {@link Parameter}. The interpretation semantic describes what the value of * this {@link Parameter} means. Currently there are three definitions, but any String value can be used: *
    - *
  • {@link Parameter#INTERPRETATION_NONE}
  • + *
  • {@link StrolchModelConstants#INTERPRETATION_NONE}
  • *
  • {@link StrolchModelConstants#INTERPRETATION_ORDER_REF}
  • *
  • {@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}
  • *
@@ -130,7 +106,7 @@ public interface Parameter extends StrolchElement { * Set the interpretation of this {@link Parameter}. The interpretation semantic describes what the value of this * {@link Parameter} means. Currently there are three definitions, but any String value can be used: *
    - *
  • {@link Parameter#INTERPRETATION_NONE}
  • + *
  • {@link StrolchModelConstants#INTERPRETATION_NONE}
  • *
  • {@link StrolchModelConstants#INTERPRETATION_ORDER_REF}
  • *
  • {@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}
  • *
@@ -139,6 +115,19 @@ public interface Parameter extends StrolchElement { */ public void setInterpretation(String interpretation); + /** + * The {@link ParameterizedElement} parent to which this {@link Parameter} belongs + * + * @return + */ + @Override + public ParameterizedElement getParent(); + + /** + * Sets the parent for this {@link Parameter} + */ + public void setParent(ParameterizedElement parent); + @Override public int hashCode(); diff --git a/src/main/java/li/strolch/model/timedstate/AbstractStrolchTimedState.java b/src/main/java/li/strolch/model/timedstate/AbstractStrolchTimedState.java index 30faffef5..f79cff7b4 100644 --- a/src/main/java/li/strolch/model/timedstate/AbstractStrolchTimedState.java +++ b/src/main/java/li/strolch/model/timedstate/AbstractStrolchTimedState.java @@ -15,6 +15,12 @@ */ package li.strolch.model.timedstate; +import static li.strolch.model.StrolchModelConstants.INTERPRETATION_NONE; +import static li.strolch.model.StrolchModelConstants.UOM_NONE; + +import java.text.MessageFormat; + +import li.strolch.exception.StrolchException; import li.strolch.model.AbstractStrolchElement; import li.strolch.model.Locator; import li.strolch.model.Locator.LocatorBuilder; @@ -26,6 +32,12 @@ import li.strolch.model.timevalue.ITimeValue; import li.strolch.model.timevalue.ITimeVariable; import li.strolch.model.timevalue.IValue; import li.strolch.model.timevalue.IValueChange; +import li.strolch.model.visitor.TimedStateVisitor; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; /** * @author Robert von Burg @@ -36,6 +48,11 @@ public abstract class AbstractStrolchTimedState extends Abstra private static final long serialVersionUID = 1L; + protected boolean hidden = false; + protected int index; + protected String interpretation = INTERPRETATION_NONE; + protected String uom = UOM_NONE; + protected Resource parent; protected ITimedState state; @@ -48,6 +65,54 @@ public abstract class AbstractStrolchTimedState extends Abstra this.state = new TimedState<>(); } + @Override + public boolean isHidden() { + return this.hidden; + } + + @Override + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + @Override + public String getInterpretation() { + return this.interpretation; + } + + @Override + public void setInterpretation(String interpretation) { + if (StringHelper.isEmpty(interpretation)) { + this.interpretation = INTERPRETATION_NONE; + } else { + this.interpretation = interpretation; + } + } + + @Override + public String getUom() { + return this.uom; + } + + @Override + public void setUom(String uom) { + if (StringHelper.isEmpty(uom)) { + this.uom = UOM_NONE; + } else { + this.uom = uom; + } + } + + @Override + public void setIndex(int index) { + this.index = index; + } + + @Override + public int getIndex() { + return this.index; + } + @Override public ITimeValue getNextMatch(Long time, T value) { return this.state.getNextMatch(time, value); @@ -89,9 +154,75 @@ public abstract class AbstractStrolchTimedState extends Abstra } @Override - protected void fillLocator(LocatorBuilder locatorBuilder) { - locatorBuilder.append(Tags.TIMED_STATE); - locatorBuilder.append(getId()); + public Element toDom(Document doc) { + Element element = doc.createElement(Tags.PARAMETER); + fillElement(element); + + if (!this.interpretation.equals(INTERPRETATION_NONE)) { + element.setAttribute(Tags.INTERPRETATION, this.interpretation); + } + if (!this.uom.equals(UOM_NONE)) { + element.setAttribute(Tags.UOM, this.uom); + } + if (this.hidden) { + element.setAttribute(Tags.HIDDEN, Boolean.toString(this.hidden)); + } + if (this.index != 0) { + element.setAttribute(Tags.INDEX, Integer.toString(this.index)); + } + + return element; + } + + @Override + public void fromDom(Element element) { + + super.fromDom(element); + + String typeS = element.getAttribute(Tags.TYPE); + if (StringHelper.isEmpty(typeS)) { + String msg = "Type must be set on element with id {0}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, this.id); + throw new StrolchException(msg); + } else if (!typeS.equals(getType())) { + String msg = "{0} must have type {1}, not: {2}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, getClass().getSimpleName(), getType(), typeS); + throw new StrolchException(msg); + } + + String interpretation = element.getAttribute(Tags.INTERPRETATION); + String hidden = element.getAttribute(Tags.HIDDEN); + String uom = element.getAttribute(Tags.UOM); + String index = element.getAttribute(Tags.INDEX); + + setInterpretation(interpretation); + setUom(uom); + + if (StringHelper.isEmpty(index)) { + this.index = 0; + } else { + this.index = Integer.valueOf(index); + } + + if (StringHelper.isEmpty(hidden)) { + setHidden(false); + } else { + if (hidden.equalsIgnoreCase(Boolean.TRUE.toString())) { + setHidden(true); + } else if (hidden.equalsIgnoreCase(Boolean.FALSE.toString())) { + setHidden(false); + } else { + String msg = "Boolean string must be either {0} or {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, Boolean.TRUE.toString(), Boolean.FALSE.toString()); + throw new StrolchException(msg); + } + } + } + + @Override + protected void fillLocator(LocatorBuilder lb) { + lb.append(Tags.STATE); + lb.append(this.id); } @Override @@ -107,6 +238,11 @@ public abstract class AbstractStrolchTimedState extends Abstra clone.state = this.state.getCopy(); } + @Override + public U accept(TimedStateVisitor visitor) { + return visitor.visitTimedState(this); + } + @SuppressWarnings("nls") @Override public String toString() { diff --git a/src/main/java/li/strolch/model/timedstate/StrolchTimedState.java b/src/main/java/li/strolch/model/timedstate/StrolchTimedState.java index f70d406c3..1b7942ddb 100644 --- a/src/main/java/li/strolch/model/timedstate/StrolchTimedState.java +++ b/src/main/java/li/strolch/model/timedstate/StrolchTimedState.java @@ -17,10 +17,13 @@ package li.strolch.model.timedstate; import li.strolch.model.Resource; import li.strolch.model.StrolchElement; +import li.strolch.model.StrolchModelConstants; +import li.strolch.model.parameter.Parameter; import li.strolch.model.timevalue.ITimeValue; import li.strolch.model.timevalue.ITimeVariable; import li.strolch.model.timevalue.IValue; import li.strolch.model.timevalue.IValueChange; +import li.strolch.model.visitor.TimedStateVisitor; /** * @author Robert von Burg @@ -28,6 +31,75 @@ import li.strolch.model.timevalue.IValueChange; @SuppressWarnings("rawtypes") public interface StrolchTimedState extends StrolchElement { + /** + * get the hidden attribute + * + * @return + */ + public boolean isHidden(); + + /** + * set the hidden attribute + * + * @param hidden + */ + public void setHidden(boolean hidden); + + /** + * Get the UOM of this {@link Parameter} + * + * @return + */ + public String getUom(); + + /** + * Set the UOM of this {@link Parameter} + * + * @param uom + */ + public void setUom(String uom); + + /** + * Returns the index of this {@link Parameter}. This can be used to sort the parameters in a UI + * + * @return the index of this {@link Parameter}. This can be used to sort the parameters in a UI + */ + public int getIndex(); + + /** + * Set the index of this {@link Parameter}. This can be used to sort the parameters in a UI + * + * @param index + * the index to set + */ + public void setIndex(int index); + + /** + * Returns the interpretation of this {@link Parameter}. The interpretation semantic describes what the value of + * this {@link Parameter} means. Currently there are three definitions, but any String value can be used: + *
    + *
  • {@link StrolchModelConstants#INTERPRETATION_NONE}
  • + *
  • {@link StrolchModelConstants#INTERPRETATION_ORDER_REF}
  • + *
  • {@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}
  • + *
+ * + * @return string value + */ + public String getInterpretation(); + + /** + * Set the interpretation of this {@link Parameter}. The interpretation semantic describes what the value of this + * {@link Parameter} means. Currently there are three definitions, but any String value can be used: + *
    + *
  • {@link StrolchModelConstants#INTERPRETATION_NONE}
  • + *
  • {@link StrolchModelConstants#INTERPRETATION_ORDER_REF}
  • + *
  • {@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}
  • + *
+ * + * @param interpretation + */ + public void setInterpretation(String interpretation); + public ITimeValue getNextMatch(Long time, T value); public ITimeValue getPreviousMatch(Long time, T value); @@ -39,4 +111,6 @@ public interface StrolchTimedState extends StrolchElement { public ITimeVariable getTimeEvolution(); public void setParent(Resource aThis); + + public U accept(TimedStateVisitor visitor); } diff --git a/src/main/java/li/strolch/model/timevalue/IValue.java b/src/main/java/li/strolch/model/timevalue/IValue.java index 94f1d6074..701d62d8d 100644 --- a/src/main/java/li/strolch/model/timevalue/IValue.java +++ b/src/main/java/li/strolch/model/timevalue/IValue.java @@ -49,4 +49,9 @@ public interface IValue { * @return a copy of this */ IValue getCopy(); + + /** + * @return this value in string representation + */ + String getValueAsString(); } diff --git a/src/main/java/li/strolch/model/timevalue/impl/AString.java b/src/main/java/li/strolch/model/timevalue/impl/AString.java index 5626bef3a..fc2835b74 100644 --- a/src/main/java/li/strolch/model/timevalue/impl/AString.java +++ b/src/main/java/li/strolch/model/timevalue/impl/AString.java @@ -17,6 +17,8 @@ package li.strolch.model.timevalue.impl; import java.io.Serializable; +import ch.eitchnet.utils.dbc.DBC; + /** * Wrapper for java.util.String object defining a inverse to support algebraic operations. * @@ -30,11 +32,15 @@ public class AString implements Serializable { private final boolean inverse; public AString(final String string) { + DBC.PRE.assertNotNull("Value may not be null!", string); + DBC.PRE.assertFalse("Comma not allowed in value!", string.contains(",")); this.string = string; this.inverse = false; } public AString(final String string, final boolean inverse) { + DBC.PRE.assertNotNull("Value may not be null!", string); + DBC.PRE.assertFalse("Comma not allowed in value!", string.contains(",")); this.string = string; this.inverse = inverse; } diff --git a/src/main/java/li/strolch/model/timevalue/impl/BooleanValue.java b/src/main/java/li/strolch/model/timevalue/impl/BooleanValue.java index 10bc9cbe0..f52a1c794 100644 --- a/src/main/java/li/strolch/model/timevalue/impl/BooleanValue.java +++ b/src/main/java/li/strolch/model/timevalue/impl/BooleanValue.java @@ -65,6 +65,11 @@ public class BooleanValue implements IValue, Serializable { public BooleanValue getInverse() { return new BooleanValue(!getValue()); } + + @Override + public String getValueAsString() { + return this.value.toString(); + } @SuppressWarnings("nls") @Override diff --git a/src/main/java/li/strolch/model/timevalue/impl/FloatValue.java b/src/main/java/li/strolch/model/timevalue/impl/FloatValue.java index 452686870..deaddc02d 100644 --- a/src/main/java/li/strolch/model/timevalue/impl/FloatValue.java +++ b/src/main/java/li/strolch/model/timevalue/impl/FloatValue.java @@ -64,6 +64,11 @@ public class FloatValue implements IValue, Serializable { return this.value; } + @Override + public String getValueAsString() { + return this.value.toString(); + } + @SuppressWarnings("nls") @Override public String toString() { diff --git a/src/main/java/li/strolch/model/timevalue/impl/IntegerValue.java b/src/main/java/li/strolch/model/timevalue/impl/IntegerValue.java index da7936f64..4f90363e2 100644 --- a/src/main/java/li/strolch/model/timevalue/impl/IntegerValue.java +++ b/src/main/java/li/strolch/model/timevalue/impl/IntegerValue.java @@ -65,6 +65,11 @@ public class IntegerValue implements IValue, Serializable { public IntegerValue getInverse() { return new IntegerValue(-getValue()); } + + @Override + public String getValueAsString() { + return this.value.toString(); + } @SuppressWarnings("nls") @Override diff --git a/src/main/java/li/strolch/model/timevalue/impl/StringSetValue.java b/src/main/java/li/strolch/model/timevalue/impl/StringSetValue.java index 76bb82284..b6eb46df4 100644 --- a/src/main/java/li/strolch/model/timevalue/impl/StringSetValue.java +++ b/src/main/java/li/strolch/model/timevalue/impl/StringSetValue.java @@ -15,15 +15,17 @@ */ package li.strolch.model.timevalue.impl; -import ch.eitchnet.utils.helper.StringHelper; import java.io.Serializable; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; + import li.strolch.exception.StrolchException; import li.strolch.model.timevalue.ITimeValue; import li.strolch.model.timevalue.IValue; +import ch.eitchnet.utils.dbc.DBC; +import ch.eitchnet.utils.helper.StringHelper; /** * {@link IValue} implementation to work with String valued {@link ITimeValue} objects. Since a java.util.String object @@ -44,12 +46,7 @@ public class StringSetValue implements IValue>, Serializable { } public StringSetValue(final Set aStrings) { - // assert no null values in set - for (AString aString : aStrings) { - if (StringHelper.isEmpty(aString.getString())) { - throw new StrolchException("StringSetValue may not contain null values in set!"); - } - } + DBC.PRE.assertNotNull("Value may not be null!", aStrings); this.aStrings = aStrings; } @@ -105,12 +102,29 @@ public class StringSetValue implements IValue>, Serializable { return new StringSetValue(new HashSet<>(this.aStrings)); } + @Override + public String getValueAsString() { + if (this.aStrings.isEmpty()) + return StringHelper.EMPTY; + if (this.aStrings.size() == 1) + return this.aStrings.iterator().next().getString(); + + StringBuilder sb = new StringBuilder(); + Iterator iter = aStrings.iterator(); + while (iter.hasNext()) { + sb.append(iter.next()); + if (iter.hasNext()) + sb.append(", "); + } + return sb.toString(); + } + @SuppressWarnings("nls") @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("StringSetValue [aStrings="); - sb.append(this.aStrings); + sb.append(getValueAsString()); sb.append("]"); return sb.toString(); } diff --git a/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java b/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java index b03d470b2..2e8b1b038 100644 --- a/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java +++ b/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java @@ -18,6 +18,7 @@ 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; @@ -78,21 +79,21 @@ public class StrolchElementDeepEqualsVisitor { Set srcTimedStateKeySet = srcRes.getTimedStateKeySet(); for (String timedStateKey : srcTimedStateKeySet) { - StrolchTimedState srcTimedState = srcRes.getTimedState(timedStateKey); + StrolchTimedState srcTimedState = srcRes.getTimedState(timedStateKey); if (!dstRes.hasTimedState(timedStateKey)) { this.mismatchedLocators.add(srcTimedState.getLocator()); continue; } - StrolchTimedState dstTimedState = dstRes.getTimedState(timedStateKey); + StrolchTimedState dstTimedState = dstRes.getTimedState(timedStateKey); deepEquals(srcTimedState, dstTimedState); } Set dstTimedStateKeySet = dstRes.getTimedStateKeySet(); for (String timedStateKey : dstTimedStateKeySet) { if (!srcRes.hasTimedState(timedStateKey)) { - StrolchTimedState dstTimedState = dstRes.getTimedState(timedStateKey); + StrolchTimedState dstTimedState = dstRes.getTimedState(timedStateKey); this.mismatchedLocators.add(dstTimedState.getLocator()); } } diff --git a/src/main/java/li/strolch/model/visitor/TimedStateVisitor.java b/src/main/java/li/strolch/model/visitor/TimedStateVisitor.java new file mode 100644 index 000000000..072afc482 --- /dev/null +++ b/src/main/java/li/strolch/model/visitor/TimedStateVisitor.java @@ -0,0 +1,39 @@ +/* + * 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.timedstate.BooleanTimedState; +import li.strolch.model.timedstate.FloatTimedState; +import li.strolch.model.timedstate.IntegerTimedState; +import li.strolch.model.timedstate.StringSetTimedState; +import li.strolch.model.timedstate.StrolchTimedState; + +/** + * @author Robert von Burg + */ +public interface TimedStateVisitor { + + public T visitTimedState(StrolchTimedState timedState); + + public T visitBooleanState(BooleanTimedState state); + + public T visitFloatState(FloatTimedState state); + + public T visitIntegerState(IntegerTimedState state); + + public T visitStringState(StringSetTimedState state); + +} diff --git a/src/main/java/li/strolch/model/xml/AbstractToSaxWriterVisitor.java b/src/main/java/li/strolch/model/xml/AbstractToSaxWriterVisitor.java index eae45ec9a..5a53a9497 100644 --- a/src/main/java/li/strolch/model/xml/AbstractToSaxWriterVisitor.java +++ b/src/main/java/li/strolch/model/xml/AbstractToSaxWriterVisitor.java @@ -15,22 +15,32 @@ */ package li.strolch.model.xml; +import static li.strolch.model.StrolchModelConstants.INTERPRETATION_NONE; +import static li.strolch.model.StrolchModelConstants.UOM_NONE; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; +import java.util.SortedSet; import java.util.TreeSet; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import li.strolch.model.GroupedParameterizedElement; +import li.strolch.model.Order; import li.strolch.model.ParameterBag; import li.strolch.model.ParameterizedElement; +import li.strolch.model.Resource; import li.strolch.model.StrolchElement; import li.strolch.model.Tags; import li.strolch.model.parameter.Parameter; +import li.strolch.model.timedstate.StrolchTimedState; +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.ITimeVariable; +import li.strolch.model.timevalue.IValue; import ch.eitchnet.utils.helper.StringHelper; /** @@ -44,12 +54,52 @@ public abstract class AbstractToSaxWriterVisitor { this.writer = writer; } - protected void writeElement(String tag, GroupedParameterizedElement element) throws XMLStreamException { - boolean isEmpty = !element.hasParameterBags(); - writeStartStrolchElement(tag, isEmpty, element); - if (!isEmpty) { - writeParameterBags(element); + protected void writeElement(String tag, Order order) throws XMLStreamException { + boolean empty = !order.hasParameterBags(); + writeElement(tag, empty, (GroupedParameterizedElement) order); + if (!empty) this.writer.writeEndElement(); + } + + protected void writeElement(String tag, Resource resource) throws XMLStreamException { + boolean empty = !resource.hasParameterBags() && !resource.hasTimedStates(); + writeElement(tag, empty, (GroupedParameterizedElement) resource); + + if (resource.hasTimedStates()) + writeTimedStates(resource); + + if (!empty) + this.writer.writeEndElement(); + } + + /** + * @param resource + * @throws XMLStreamException + */ + private void writeTimedStates(Resource resource) throws XMLStreamException { + List>> timedStates = resource.getTimedStates(); + for (StrolchTimedState> timedState : timedStates) { + ITimeVariable> timeEvolution = timedState.getTimeEvolution(); + SortedSet>> values = timeEvolution.getValues(); + + writeStartStrolchElement(Tags.TIMED_STATE, !values.isEmpty(), timedState); + + for (ITimeValue> timeValue : values) { + writer.writeEmptyElement(Tags.VALUE); + writer.writeAttribute(Tags.TIME, timeValue.getTime().toString()); + writer.writeAttribute(Tags.VALUE, timeValue.getValue().getValueAsString()); + } + + if (!values.isEmpty()) + writer.writeEndElement(); + } + } + + protected void writeElement(String tag, boolean empty, GroupedParameterizedElement element) + throws XMLStreamException { + writeStartStrolchElement(tag, empty, element); + if (!empty) { + writeParameterBags(element); } } @@ -68,35 +118,6 @@ public abstract class AbstractToSaxWriterVisitor { this.writer.writeAttribute(Tags.TYPE, element.getType()); } - protected void writeParameters(ParameterizedElement element) throws XMLStreamException { - - List> parameters = new ArrayList<>(element.getParameters()); - Collections.sort(parameters, new Comparator>() { - @Override - public int compare(Parameter o1, Parameter o2) { - return Integer.valueOf(o1.getIndex()).compareTo(o2.getIndex()); - } - }); - for (Parameter parameter : parameters) { - writeStartStrolchElement(Tags.PARAMETER, true, parameter); - - if (!Parameter.INTERPRETATION_NONE.equals(parameter.getInterpretation())) { - this.writer.writeAttribute(Tags.INTERPRETATION, parameter.getInterpretation()); - } - if (!Parameter.UOM_NONE.equals(parameter.getUom())) { - this.writer.writeAttribute(Tags.UOM, parameter.getUom()); - } - if (parameter.isHidden()) { - this.writer.writeAttribute(Tags.HIDDEN, Boolean.toString(parameter.isHidden())); - } - if (parameter.getIndex() != 0) { - this.writer.writeAttribute(Tags.INDEX, Integer.toString(parameter.getIndex())); - } - - this.writer.writeAttribute(Tags.VALUE, parameter.getValueAsString()); - } - } - protected void writeParameterBags(GroupedParameterizedElement element) throws XMLStreamException { Set bagKeySet = new TreeSet<>(element.getParameterBagKeySet()); for (String bagKey : bagKeySet) { @@ -109,4 +130,33 @@ public abstract class AbstractToSaxWriterVisitor { } } } + + protected void writeParameters(ParameterizedElement element) throws XMLStreamException { + + List> parameters = new ArrayList<>(element.getParameters()); + Collections.sort(parameters, new Comparator>() { + @Override + public int compare(Parameter o1, Parameter o2) { + return Integer.valueOf(o1.getIndex()).compareTo(o2.getIndex()); + } + }); + for (Parameter parameter : parameters) { + writeStartStrolchElement(Tags.PARAMETER, true, parameter); + + if (!INTERPRETATION_NONE.equals(parameter.getInterpretation())) { + this.writer.writeAttribute(Tags.INTERPRETATION, parameter.getInterpretation()); + } + if (!UOM_NONE.equals(parameter.getUom())) { + this.writer.writeAttribute(Tags.UOM, parameter.getUom()); + } + if (parameter.isHidden()) { + this.writer.writeAttribute(Tags.HIDDEN, Boolean.toString(parameter.isHidden())); + } + if (parameter.getIndex() != 0) { + this.writer.writeAttribute(Tags.INDEX, Integer.toString(parameter.getIndex())); + } + + this.writer.writeAttribute(Tags.VALUE, parameter.getValueAsString()); + } + } } diff --git a/src/main/java/li/strolch/model/xml/StrolchElementToSaxVisitor.java b/src/main/java/li/strolch/model/xml/StrolchElementToSaxVisitor.java index f777ce169..6f14e598b 100644 --- a/src/main/java/li/strolch/model/xml/StrolchElementToSaxVisitor.java +++ b/src/main/java/li/strolch/model/xml/StrolchElementToSaxVisitor.java @@ -15,6 +15,9 @@ */ package li.strolch.model.xml; +import static li.strolch.model.StrolchModelConstants.INTERPRETATION_NONE; +import static li.strolch.model.StrolchModelConstants.UOM_NONE; + import java.util.Set; import li.strolch.model.GroupedParameterizedElement; @@ -61,10 +64,10 @@ public abstract class StrolchElementToSaxVisitor { AttributesImpl attributes = attributesFor((StrolchElement) parameter); attributes.addAttribute(null, null, Tags.VALUE, Tags.CDATA, parameter.getValueAsString()); - if (!Parameter.UOM_NONE.equals(parameter.getUom())) { + if (!UOM_NONE.equals(parameter.getUom())) { attributes.addAttribute(null, null, Tags.UOM, Tags.CDATA, parameter.getUom()); } - if (!Parameter.INTERPRETATION_NONE.equals(parameter.getInterpretation())) { + if (!INTERPRETATION_NONE.equals(parameter.getInterpretation())) { attributes.addAttribute(null, null, Tags.INTERPRETATION, Tags.CDATA, parameter.getInterpretation()); } if (parameter.isHidden()) { diff --git a/src/main/java/li/strolch/model/xml/XmlModelSaxReader.java b/src/main/java/li/strolch/model/xml/XmlModelSaxReader.java index 06fe0901b..70287df8f 100644 --- a/src/main/java/li/strolch/model/xml/XmlModelSaxReader.java +++ b/src/main/java/li/strolch/model/xml/XmlModelSaxReader.java @@ -17,6 +17,8 @@ package li.strolch.model.xml; import java.text.MessageFormat; import java.util.Date; +import java.util.HashSet; +import java.util.Set; import li.strolch.exception.StrolchException; import li.strolch.model.GroupedParameterizedElement; @@ -34,6 +36,17 @@ import li.strolch.model.parameter.LongParameter; import li.strolch.model.parameter.Parameter; import li.strolch.model.parameter.StringListParameter; import li.strolch.model.parameter.StringParameter; +import li.strolch.model.timedstate.BooleanTimedState; +import li.strolch.model.timedstate.FloatTimedState; +import li.strolch.model.timedstate.IntegerTimedState; +import li.strolch.model.timedstate.StringSetTimedState; +import li.strolch.model.timedstate.StrolchTimedState; +import li.strolch.model.timevalue.IValue; +import li.strolch.model.timevalue.impl.AString; +import li.strolch.model.timevalue.impl.BooleanValue; +import li.strolch.model.timevalue.impl.FloatValue; +import li.strolch.model.timevalue.impl.IntegerValue; +import li.strolch.model.timevalue.impl.StringSetValue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,6 +69,8 @@ public class XmlModelSaxReader extends DefaultHandler { private GroupedParameterizedElement parameterizedElement; private ParameterBag pBag; + private StrolchTimedState> state; + private String stateType; public XmlModelSaxReader(StrolchElementListener listener) { this.listener = listener; @@ -165,6 +180,63 @@ public class XmlModelSaxReader extends DefaultHandler { } break; + case Tags.TIMED_STATE: + String stateId = attributes.getValue(Tags.ID); + String stateName = attributes.getValue(Tags.NAME); + this.stateType = attributes.getValue(Tags.TYPE); + + switch (this.stateType) { + case FloatTimedState.TYPE: + this.state = new FloatTimedState(stateId, stateName); + break; + case IntegerTimedState.TYPE: + this.state = new IntegerTimedState(stateId, stateName); + break; + case BooleanTimedState.TYPE: + this.state = new BooleanTimedState(stateId, stateName); + break; + case StringSetTimedState.TYPE: + this.state = new StringSetTimedState(stateId, stateName); + break; + default: + break; + } + + break; + + case Tags.VALUE: + String valueTime = attributes.getValue(Tags.TIME); + String valueValue = attributes.getValue(Tags.VALUE); + switch (this.stateType) { + case FloatTimedState.TYPE: + ((FloatTimedState) this.state).getTimeEvolution().setValueAt(Long.valueOf(valueTime), + new FloatValue(valueValue)); + break; + case IntegerTimedState.TYPE: + ((IntegerTimedState) this.state).getTimeEvolution().setValueAt(Long.valueOf(valueTime), + new IntegerValue(valueValue)); + break; + case BooleanTimedState.TYPE: + ((BooleanTimedState) this.state).getTimeEvolution().setValueAt(Long.valueOf(valueTime), + new BooleanValue(valueValue)); + break; + case StringSetTimedState.TYPE: + + Set value = new HashSet<>(); + String[] values = valueValue.split(","); + for (String s : values) { + value.add(new AString(s.trim())); + } + + StringSetValue stringSetValue = new StringSetValue(value); + ((StringSetTimedState) this.state).getTimeEvolution().setValueAt(Long.valueOf(valueTime), + stringSetValue); + break; + default: + break; + } + break; + default: throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$ } @@ -193,6 +265,11 @@ public class XmlModelSaxReader extends DefaultHandler { break; case Tags.INCLUDE_FILE: break; + case Tags.TIMED_STATE: + ((Resource) this.parameterizedElement).addTimedState(state); + break; + case Tags.VALUE: + break; default: throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$ } diff --git a/src/test/java/li/strolch/model/ModelTest.java b/src/test/java/li/strolch/model/ModelTest.java index 391398e7a..0a512ba56 100644 --- a/src/test/java/li/strolch/model/ModelTest.java +++ b/src/test/java/li/strolch/model/ModelTest.java @@ -15,6 +15,7 @@ */ package li.strolch.model; +import static li.strolch.model.ModelGenerator.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -22,7 +23,7 @@ import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Date; - +import static li.strolch.model.Tags.*; import li.strolch.model.parameter.BooleanParameter; import li.strolch.model.parameter.DateParameter; import li.strolch.model.parameter.FloatParameter; @@ -31,6 +32,9 @@ import li.strolch.model.parameter.LongParameter; import li.strolch.model.parameter.StringListParameter; import li.strolch.model.parameter.StringParameter; import li.strolch.model.timedstate.BooleanTimedState; +import li.strolch.model.timedstate.FloatTimedState; +import li.strolch.model.timedstate.IntegerTimedState; +import li.strolch.model.timedstate.StringSetTimedState; import li.strolch.model.timevalue.impl.BooleanValue; import li.strolch.model.timevalue.impl.ValueChange; import li.strolch.model.visitor.OrderDeepEqualsVisitor; @@ -44,23 +48,44 @@ public class ModelTest { @Test public void shouldCreateResource() { - Resource resource = ModelGenerator.createResource("@res01", "Test resource", "MyType"); - ParameterBag bag = resource.getParameterBag(ModelGenerator.BAG_ID); + Resource resource = createResource("@res01", "Test resource", "MyType"); + ParameterBag bag = resource.getParameterBag(BAG_ID); validateBag(bag); + validateStates(resource); } @Test public void shouldCreateOrder() { - Order order = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", new Date(), State.OPEN); - ParameterBag bag = order.getParameterBag(ModelGenerator.BAG_ID); + Order order = createOrder("@ord01", "Test Order", "MyType", new Date(), State.OPEN); + ParameterBag bag = order.getParameterBag(BAG_ID); validateBag(bag); } + @Test + public void shouldCreateLocators() { + + Resource resource = createResource("@res01", "Test resource", "MyType"); + assertEquals(Locator.valueOf(RESOURCE, "MyType", "@res01"), resource.getLocator()); + ParameterBag bag = resource.getParameterBag(BAG_ID); + assertEquals(Locator.valueOf(RESOURCE, "MyType", "@res01", BAG, BAG_ID), bag.getLocator()); + StringParameter sP = bag.getParameter(PARAM_STRING_ID); + assertEquals(Locator.valueOf(RESOURCE, "MyType", "@res01", BAG, BAG_ID, PARAM_STRING_ID), sP.getLocator()); + FloatTimedState floatS = resource.getTimedState(STATE_FLOAT_ID); + assertEquals(Locator.valueOf(RESOURCE, "MyType", "@res01", STATE, STATE_FLOAT_ID), floatS.getLocator()); + + Order order = createOrder("@ord01", "Test Order", "MyType", new Date(), State.OPEN); + assertEquals(Locator.valueOf(ORDER, "MyType", "@ord01"), order.getLocator()); + bag = order.getParameterBag(BAG_ID); + assertEquals(Locator.valueOf(ORDER, "MyType", "@ord01", BAG, BAG_ID), bag.getLocator()); + sP = bag.getParameter(PARAM_STRING_ID); + assertEquals(Locator.valueOf(ORDER, "MyType", "@ord01", BAG, BAG_ID, PARAM_STRING_ID), sP.getLocator()); + } + @Test public void shouldPerformDeepResourceEquals() { - Resource srcRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); - Resource dstRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); + Resource srcRes = createResource("@res01", "Test resource", "MyType"); + Resource dstRes = createResource("@res01", "Test resource", "MyType"); ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); visitor.visit(dstRes); assertTrue("Same Resource should be deep equal!", visitor.isEqual()); @@ -68,11 +93,11 @@ public class ModelTest { @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); + Resource srcRes = createResource("@res01", "Test resource", "MyType"); + Resource dstRes = createResource("@res01", "Test resource", "MyType"); + ParameterBag bag = dstRes.getParameterBag(BAG_ID); bag.setName("Bla bla"); - FloatParameter fParam = bag.getParameter(ModelGenerator.PARAM_FLOAT_ID); + FloatParameter fParam = bag.getParameter(PARAM_FLOAT_ID); fParam.setValue(23434234.234); fParam.setName("Ohla"); ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); @@ -83,9 +108,9 @@ public class ModelTest { @Test public void shouldFailDeepResourceEquals2() { - Resource srcRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); - Resource dstRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); - BooleanTimedState timedState = dstRes.getTimedState(ModelGenerator.STATE_BOOLEAN_ID); + Resource srcRes = createResource("@res01", "Test resource", "MyType"); + Resource dstRes = createResource("@res01", "Test resource", "MyType"); + BooleanTimedState timedState = dstRes.getTimedState(STATE_BOOLEAN_ID); timedState.applyChange(new ValueChange<>(System.currentTimeMillis(), new BooleanValue(Boolean.TRUE))); timedState.setName("Ohla"); ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); @@ -97,8 +122,8 @@ public class ModelTest { @Test public void shouldPerformDeepOrderEquals() { Date date = new Date(); - Order srcOrder = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", date, State.OPEN); - Order dstOrder = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", date, State.OPEN); + Order srcOrder = createOrder("@ord01", "Test Order", "MyType", date, State.OPEN); + Order dstOrder = createOrder("@ord01", "Test Order", "MyType", date, State.OPEN); OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(srcOrder); visitor.visit(dstOrder); assertTrue("Same Order should be deep equal: " + visitor.getMismatchedLocators(), visitor.isEqual()); @@ -108,45 +133,78 @@ public class ModelTest { assertNotNull(bag); - assertEquals(ModelGenerator.BAG_ID, bag.getId()); - assertEquals(ModelGenerator.BAG_NAME, bag.getName()); - assertEquals(ModelGenerator.BAG_TYPE, bag.getType()); + assertEquals(BAG_ID, bag.getId()); + assertEquals(BAG_NAME, bag.getName()); + assertEquals(BAG_TYPE, bag.getType()); validateParams(bag); } public static void validateParams(ParameterBag bag) { - BooleanParameter boolParam = bag.getParameter(ModelGenerator.PARAM_BOOLEAN_ID); - assertNotNull("Boolean Param missing with id " + ModelGenerator.PARAM_BOOLEAN_ID, boolParam); + BooleanParameter boolParam = bag.getParameter(PARAM_BOOLEAN_ID); + assertNotNull("Boolean Param missing with id " + PARAM_BOOLEAN_ID, boolParam); assertEquals(true, boolParam.getValue().booleanValue()); - FloatParameter floatParam = bag.getParameter(ModelGenerator.PARAM_FLOAT_ID); - assertNotNull("Float Param missing with id " + ModelGenerator.PARAM_FLOAT_ID, floatParam); + FloatParameter floatParam = bag.getParameter(PARAM_FLOAT_ID); + assertNotNull("Float Param missing with id " + PARAM_FLOAT_ID, floatParam); assertEquals(44.3, floatParam.getValue().doubleValue(), 0.0001); - IntegerParameter integerParam = bag.getParameter(ModelGenerator.PARAM_INTEGER_ID); - assertNotNull("Integer Param missing with id " + ModelGenerator.PARAM_INTEGER_ID, integerParam); + IntegerParameter integerParam = bag.getParameter(PARAM_INTEGER_ID); + assertNotNull("Integer Param missing with id " + PARAM_INTEGER_ID, integerParam); assertEquals(77, integerParam.getValue().intValue()); - LongParameter longParam = bag.getParameter(ModelGenerator.PARAM_LONG_ID); - assertNotNull("Long Param missing with id " + ModelGenerator.PARAM_LONG_ID, longParam); + LongParameter longParam = bag.getParameter(PARAM_LONG_ID); + assertNotNull("Long Param missing with id " + PARAM_LONG_ID, longParam); assertEquals(4453234566L, longParam.getValue().longValue()); - StringParameter stringParam = bag.getParameter(ModelGenerator.PARAM_STRING_ID); - assertNotNull("String Param missing with id " + ModelGenerator.PARAM_STRING_ID, stringParam); + StringParameter stringParam = bag.getParameter(PARAM_STRING_ID); + assertNotNull("String Param missing with id " + PARAM_STRING_ID, stringParam); assertEquals("Strolch", stringParam.getValue()); - DateParameter dateParam = bag.getParameter(ModelGenerator.PARAM_DATE_ID); - assertNotNull("Date Param missing with id " + ModelGenerator.PARAM_DATE_ID, dateParam); + DateParameter dateParam = bag.getParameter(PARAM_DATE_ID); + assertNotNull("Date Param missing with id " + PARAM_DATE_ID, dateParam); assertEquals(1354295525628L, dateParam.getValue().getTime()); - StringListParameter stringListP = bag.getParameter(ModelGenerator.PARAM_LIST_STRING_ID); - assertNotNull("StringList Param missing with id " + ModelGenerator.PARAM_LIST_STRING_ID, stringListP); + StringListParameter stringListP = bag.getParameter(PARAM_LIST_STRING_ID); + assertNotNull("StringList Param missing with id " + PARAM_LIST_STRING_ID, stringListP); ArrayList stringList = new ArrayList<>(); stringList.add("Hello"); stringList.add("World"); assertEquals(stringList, stringListP.getValue()); } + + /** + * @param resource + */ + private void validateStates(Resource resource) { + BooleanTimedState booleanState = resource.getTimedState(STATE_BOOLEAN_ID); + assertNotNull("Boolean State missing with id " + STATE_BOOLEAN_ID, booleanState); + assertEquals(STATE_BOOLEAN_TIME_0, booleanState.getStateAt(STATE_TIME_0).getValue().getValue()); + assertEquals(STATE_BOOLEAN_TIME_10, booleanState.getStateAt(STATE_TIME_10).getValue().getValue()); + assertEquals(STATE_BOOLEAN_TIME_20, booleanState.getStateAt(STATE_TIME_20).getValue().getValue()); + assertEquals(STATE_BOOLEAN_TIME_30, booleanState.getStateAt(STATE_TIME_30).getValue().getValue()); + + FloatTimedState floatState = resource.getTimedState(STATE_FLOAT_ID); + assertNotNull("Float State missing with id " + STATE_FLOAT_ID, floatState); + assertEquals(STATE_FLOAT_TIME_0, floatState.getStateAt(STATE_TIME_0).getValue().getValue()); + assertEquals(STATE_FLOAT_TIME_10, floatState.getStateAt(STATE_TIME_10).getValue().getValue()); + assertEquals(STATE_FLOAT_TIME_20, floatState.getStateAt(STATE_TIME_20).getValue().getValue()); + assertEquals(STATE_FLOAT_TIME_30, floatState.getStateAt(STATE_TIME_30).getValue().getValue()); + + IntegerTimedState integerState = resource.getTimedState(STATE_INTEGER_ID); + assertNotNull("Integer State missing with id " + STATE_INTEGER_ID, integerState); + assertEquals(STATE_INTEGER_TIME_0, integerState.getStateAt(STATE_TIME_0).getValue().getValue()); + assertEquals(STATE_INTEGER_TIME_10, integerState.getStateAt(STATE_TIME_10).getValue().getValue()); + assertEquals(STATE_INTEGER_TIME_20, integerState.getStateAt(STATE_TIME_20).getValue().getValue()); + assertEquals(STATE_INTEGER_TIME_30, integerState.getStateAt(STATE_TIME_30).getValue().getValue()); + + StringSetTimedState stringState = resource.getTimedState(STATE_STRING_ID); + assertNotNull("String State missing with id " + STATE_STRING_ID, stringState); + assertEquals(STATE_STRING_TIME_0, stringState.getStateAt(STATE_TIME_0).getValue().getValueAsString()); + assertEquals(STATE_STRING_TIME_10, stringState.getStateAt(STATE_TIME_10).getValue().getValueAsString()); + assertEquals(STATE_STRING_TIME_20, stringState.getStateAt(STATE_TIME_20).getValue().getValueAsString()); + assertEquals(STATE_STRING_TIME_30, stringState.getStateAt(STATE_TIME_30).getValue().getValueAsString()); + } }