[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/<type>/<id>/State/<id>
Resource/<type>/<id>/Bag/<id>/<param_id>
This commit is contained in:
Robert von Burg 2014-08-21 17:42:10 +02:00
parent 647de2b392
commit 453b6b5bcb
22 changed files with 685 additions and 151 deletions

View File

@ -57,9 +57,11 @@ public class Locator {
/** /**
* Constructs a new {@link Locator} with the given list of path elements * 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<String> pathElements) throws StrolchException { public Locator(List<String> pathElements) throws StrolchException {
if (pathElements == null || pathElements.isEmpty()) { if (pathElements == null || pathElements.isEmpty()) {
@ -68,12 +70,27 @@ public class Locator {
this.pathElements = Collections.unmodifiableList(new ArrayList<String>(pathElements)); this.pathElements = Collections.unmodifiableList(new ArrayList<String>(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. * 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 { public Locator(String path) throws StrolchException {
this.pathElements = Collections.unmodifiableList(parsePath(path)); this.pathElements = Collections.unmodifiableList(parsePath(path));
@ -82,8 +99,10 @@ public class Locator {
/** /**
* Internal constructor to append a sub path to a constructor * Internal constructor to append a sub path to a constructor
* *
* @param path the base path of the locator * @param path
* @param subPath the additional path * the base path of the locator
* @param subPath
* the additional path
*/ */
private Locator(List<String> path, List<String> subPath) { private Locator(List<String> path, List<String> subPath) {
List<String> fullPath = new ArrayList<String>(); List<String> fullPath = new ArrayList<String>();
@ -95,8 +114,10 @@ public class Locator {
/** /**
* Internal constructor to append a element to a constructor * Internal constructor to append a element to a constructor
* *
* @param path the base path of the locator * @param path
* @param element the additional element * the base path of the locator
* @param element
* the additional element
*/ */
private Locator(List<String> path, String element) { private Locator(List<String> path, String element) {
List<String> fullPath = new ArrayList<String>(); List<String> fullPath = new ArrayList<String>();
@ -126,7 +147,8 @@ public class Locator {
/** /**
* Returns a new {@link Locator} where the given sub path is appended to the 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 * @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 * 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 * @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} * 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 * @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 * @throws StrolchException
* {@link #PATH_SEPARATOR} * if the path is empty, or does not contain at least 2 elements separated by {@link #PATH_SEPARATOR}
*/ */
private List<String> parsePath(String path) throws StrolchException { private List<String> parsePath(String path) throws StrolchException {
if (StringHelper.isEmpty(path)) { 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} * 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 * @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<String> pathElements) throws StrolchException { private String formatPath(List<String> pathElements) throws StrolchException {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -229,17 +255,30 @@ public class Locator {
/** /**
* Instantiates a new immutable {@link Locator} instance from the given string * 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 * @return the immutable {@link Locator} instance
*/ */
public static Locator valueOf(String locatorPath) { public static Locator valueOf(String locatorPath) {
return new Locator(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 * 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 * @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 * Append an element to the path
* *
* @param element the element to add * @param element
* the element to add
* *
* @return this instance for chaining * @return this instance for chaining
*/ */

View File

@ -15,6 +15,8 @@
*/ */
package li.strolch.model; package li.strolch.model;
import li.strolch.model.Locator.LocatorBuilder;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
@ -59,6 +61,13 @@ public class ParameterBag extends ParameterizedElement {
return clone; return clone;
} }
@Override
public void fillLocator(LocatorBuilder lb) {
this.parent.fillLocator(lb);
lb.append(Tags.BAG);
lb.append(this.id);
}
@Override @Override
public Element toDom(Document doc) { public Element toDom(Document doc) {

View File

@ -15,8 +15,6 @@
*/ */
package li.strolch.model; package li.strolch.model;
import ch.eitchnet.utils.dbc.DBC;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -40,6 +38,7 @@ import li.strolch.model.parameter.StringParameter;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import ch.eitchnet.utils.dbc.DBC;
import ch.eitchnet.utils.helper.StringHelper; import ch.eitchnet.utils.helper.StringHelper;
/** /**
@ -194,10 +193,7 @@ public abstract class ParameterizedElement extends AbstractStrolchElement {
} }
@Override @Override
public void fillLocator(LocatorBuilder lb) { public abstract void fillLocator(LocatorBuilder lb);
this.parent.fillLocator(lb);
lb.append(this.id);
}
@Override @Override
public Locator getLocator() { public Locator getLocator() {

View File

@ -15,7 +15,6 @@
*/ */
package li.strolch.model; package li.strolch.model;
import ch.eitchnet.utils.dbc.DBC;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -24,6 +23,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import li.strolch.exception.StrolchException; import li.strolch.exception.StrolchException;
import li.strolch.model.Locator.LocatorBuilder; import li.strolch.model.Locator.LocatorBuilder;
import li.strolch.model.timedstate.BooleanTimedState; 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.IntegerTimedState;
import li.strolch.model.timedstate.StringSetTimedState; import li.strolch.model.timedstate.StringSetTimedState;
import li.strolch.model.timedstate.StrolchTimedState; import li.strolch.model.timedstate.StrolchTimedState;
import li.strolch.model.timevalue.IValue;
import li.strolch.model.visitor.StrolchRootElementVisitor; import li.strolch.model.visitor.StrolchRootElementVisitor;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
import org.w3c.dom.NodeList; import org.w3c.dom.NodeList;
import ch.eitchnet.utils.dbc.DBC;
/** /**
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*/ */
@ -43,7 +47,7 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot
private static final long serialVersionUID = 0L; private static final long serialVersionUID = 0L;
private Map<String, StrolchTimedState<?>> timedStateMap; private Map<String, StrolchTimedState<IValue<?>>> timedStateMap;
/** /**
* Empty constructor * 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); DBC.PRE.assertNotEmpty("Type must be set on TimedState for resource with id " + id, typeS);
if (typeS.equals(FloatTimedState.TYPE)) { if (typeS.equals(FloatTimedState.TYPE)) {
StrolchTimedState timedState = new FloatTimedState(timedStateElem); FloatTimedState timedState = new FloatTimedState(timedStateElem);
addTimedState(timedState); addTimedState(timedState);
} else if (typeS.equals(IntegerTimedState.TYPE)) { } else if (typeS.equals(IntegerTimedState.TYPE)) {
StrolchTimedState timedState = new IntegerTimedState(timedStateElem); IntegerTimedState timedState = new IntegerTimedState(timedStateElem);
addTimedState(timedState); addTimedState(timedState);
} else if (typeS.equals(BooleanTimedState.TYPE)) { } else if (typeS.equals(BooleanTimedState.TYPE)) {
StrolchTimedState timedState = new BooleanTimedState(timedStateElem); BooleanTimedState timedState = new BooleanTimedState(timedStateElem);
addTimedState(timedState); addTimedState(timedState);
} else if (typeS.equals(StringSetTimedState.TYPE)) { } else if (typeS.equals(StringSetTimedState.TYPE)) {
StrolchTimedState timedState = new StringSetTimedState(timedStateElem); StringSetTimedState timedState = new StringSetTimedState(timedStateElem);
addTimedState(timedState); addTimedState(timedState);
} else { } else {
String msg = "What kind of TimedState is this: {0}"; //$NON-NLS-1$ 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) { public void addTimedState(StrolchTimedState<?> strolchTimedState) {
if (this.timedStateMap == null) { if (this.timedStateMap == null) {
this.timedStateMap = new HashMap<>(); this.timedStateMap = new HashMap<>();
} }
this.timedStateMap.put(strolchTimedState.getId(), strolchTimedState); this.timedStateMap.put(strolchTimedState.getId(), (StrolchTimedState<IValue<?>>) strolchTimedState);
strolchTimedState.setParent(this); strolchTimedState.setParent(this);
} }
@SuppressWarnings({"rawtypes", "unchecked"}) @SuppressWarnings({ "rawtypes", "unchecked" })
public <T extends StrolchTimedState> T getTimedState(String id) { public <T extends StrolchTimedState> T getTimedState(String id) {
if (this.timedStateMap == null) { if (this.timedStateMap == null) {
return null; return null;
@ -115,7 +120,7 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot
return (T) this.timedStateMap.get(id); return (T) this.timedStateMap.get(id);
} }
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({ "unchecked", "rawtypes" })
public <T extends StrolchTimedState> T removeTimedState(String id) { public <T extends StrolchTimedState> T removeTimedState(String id) {
if (this.timedStateMap == null) { if (this.timedStateMap == null) {
return null; return null;
@ -130,7 +135,7 @@ public class Resource extends GroupedParameterizedElement implements StrolchRoot
return new HashSet<>(this.timedStateMap.keySet()); return new HashSet<>(this.timedStateMap.keySet());
} }
public List<StrolchTimedState<?>> getTimedStates() { public List<StrolchTimedState<IValue<?>>> getTimedStates() {
if (this.timedStateMap == null) { if (this.timedStateMap == null) {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -20,4 +20,15 @@ public class StrolchModelConstants {
* to an {@link Order} * to an {@link Order}
*/ */
public static final String INTERPRETATION_ORDER_REF = "Order-Ref"; //$NON-NLS-1$ 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$
} }

View File

@ -40,4 +40,5 @@ public class Tags {
public static final String INCLUDE_FILE = "IncludeFile"; public static final String INCLUDE_FILE = "IncludeFile";
public static final String FILE = "file"; public static final String FILE = "file";
public static final String BAG = "Bag";
} }

View File

@ -15,6 +15,9 @@
*/ */
package li.strolch.model.parameter; 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 java.text.MessageFormat;
import li.strolch.exception.StrolchException; import li.strolch.exception.StrolchException;
@ -82,7 +85,7 @@ public abstract class AbstractParameter<T> extends AbstractStrolchElement implem
@Override @Override
public void setInterpretation(String interpretation) { public void setInterpretation(String interpretation) {
if (StringHelper.isEmpty(interpretation)) { if (StringHelper.isEmpty(interpretation)) {
this.interpretation = Parameter.INTERPRETATION_NONE; this.interpretation = INTERPRETATION_NONE;
} else { } else {
this.interpretation = interpretation; this.interpretation = interpretation;
} }
@ -96,7 +99,7 @@ public abstract class AbstractParameter<T> extends AbstractStrolchElement implem
@Override @Override
public void setUom(String uom) { public void setUom(String uom) {
if (StringHelper.isEmpty(uom)) { if (StringHelper.isEmpty(uom)) {
this.uom = Parameter.UOM_NONE; this.uom = UOM_NONE;
} else { } else {
this.uom = uom; this.uom = uom;
} }
@ -134,10 +137,10 @@ public abstract class AbstractParameter<T> extends AbstractStrolchElement implem
element.setAttribute(Tags.VALUE, getValueAsString()); element.setAttribute(Tags.VALUE, getValueAsString());
if (!this.interpretation.equals(Parameter.INTERPRETATION_NONE)) { if (!this.interpretation.equals(INTERPRETATION_NONE)) {
element.setAttribute(Tags.INTERPRETATION, this.interpretation); 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); element.setAttribute(Tags.UOM, this.uom);
} }
if (this.hidden) { if (this.hidden) {
@ -196,8 +199,8 @@ public abstract class AbstractParameter<T> extends AbstractStrolchElement implem
} }
@Override @Override
protected void fillLocator(LocatorBuilder locatorBuilder) { protected void fillLocator(LocatorBuilder lb) {
locatorBuilder.append(this.id); lb.append(this.id);
} }
@Override @Override
@ -211,9 +214,11 @@ public abstract class AbstractParameter<T> extends AbstractStrolchElement implem
/** /**
* Validates that the value is legal. This is the case when it is not null in this implementation * 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 { protected void validateValue(T value) throws StrolchException {
if (value == null) { if (value == null) {

View File

@ -22,20 +22,9 @@ import li.strolch.model.visitor.ParameterVisitor;
/** /**
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
*
*/ */
public interface Parameter<T> extends StrolchElement { public interface Parameter<T> 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 * the value of the parameter as string
* *
@ -100,24 +89,11 @@ public interface Parameter<T> extends StrolchElement {
*/ */
public void setIndex(int index); 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 * 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: * this {@link Parameter} means. Currently there are three definitions, but any String value can be used:
* <ul> * <ul>
* <li>{@link Parameter#INTERPRETATION_NONE}</li> * <li>{@link StrolchModelConstants#INTERPRETATION_NONE}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_ORDER_REF}</li> * <li>{@link StrolchModelConstants#INTERPRETATION_ORDER_REF}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}</li> * <li>{@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}</li>
* </ul> * </ul>
@ -130,7 +106,7 @@ public interface Parameter<T> extends StrolchElement {
* Set the interpretation of this {@link Parameter}. The interpretation semantic describes what the value of this * 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} means. Currently there are three definitions, but any String value can be used:
* <ul> * <ul>
* <li>{@link Parameter#INTERPRETATION_NONE}</li> * <li>{@link StrolchModelConstants#INTERPRETATION_NONE}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_ORDER_REF}</li> * <li>{@link StrolchModelConstants#INTERPRETATION_ORDER_REF}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}</li> * <li>{@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}</li>
* </ul> * </ul>
@ -139,6 +115,19 @@ public interface Parameter<T> extends StrolchElement {
*/ */
public void setInterpretation(String interpretation); 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 @Override
public int hashCode(); public int hashCode();

View File

@ -15,6 +15,12 @@
*/ */
package li.strolch.model.timedstate; 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.AbstractStrolchElement;
import li.strolch.model.Locator; import li.strolch.model.Locator;
import li.strolch.model.Locator.LocatorBuilder; 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.ITimeVariable;
import li.strolch.model.timevalue.IValue; import li.strolch.model.timevalue.IValue;
import li.strolch.model.timevalue.IValueChange; 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 <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
@ -36,6 +48,11 @@ public abstract class AbstractStrolchTimedState<T extends IValue> extends Abstra
private static final long serialVersionUID = 1L; 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 Resource parent;
protected ITimedState<T> state; protected ITimedState<T> state;
@ -48,6 +65,54 @@ public abstract class AbstractStrolchTimedState<T extends IValue> extends Abstra
this.state = new TimedState<>(); 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 @Override
public ITimeValue<T> getNextMatch(Long time, T value) { public ITimeValue<T> getNextMatch(Long time, T value) {
return this.state.getNextMatch(time, value); return this.state.getNextMatch(time, value);
@ -89,9 +154,75 @@ public abstract class AbstractStrolchTimedState<T extends IValue> extends Abstra
} }
@Override @Override
protected void fillLocator(LocatorBuilder locatorBuilder) { public Element toDom(Document doc) {
locatorBuilder.append(Tags.TIMED_STATE); Element element = doc.createElement(Tags.PARAMETER);
locatorBuilder.append(getId()); 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 @Override
@ -107,6 +238,11 @@ public abstract class AbstractStrolchTimedState<T extends IValue> extends Abstra
clone.state = this.state.getCopy(); clone.state = this.state.getCopy();
} }
@Override
public <U> U accept(TimedStateVisitor visitor) {
return visitor.visitTimedState(this);
}
@SuppressWarnings("nls") @SuppressWarnings("nls")
@Override @Override
public String toString() { public String toString() {

View File

@ -17,10 +17,13 @@ package li.strolch.model.timedstate;
import li.strolch.model.Resource; import li.strolch.model.Resource;
import li.strolch.model.StrolchElement; 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.ITimeValue;
import li.strolch.model.timevalue.ITimeVariable; import li.strolch.model.timevalue.ITimeVariable;
import li.strolch.model.timevalue.IValue; import li.strolch.model.timevalue.IValue;
import li.strolch.model.timevalue.IValueChange; import li.strolch.model.timevalue.IValueChange;
import li.strolch.model.visitor.TimedStateVisitor;
/** /**
* @author Robert von Burg <eitch@eitchnet.ch> * @author Robert von Burg <eitch@eitchnet.ch>
@ -28,6 +31,75 @@ import li.strolch.model.timevalue.IValueChange;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public interface StrolchTimedState<T extends IValue> extends StrolchElement { public interface StrolchTimedState<T extends IValue> 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:
* <ul>
* <li>{@link StrolchModelConstants#INTERPRETATION_NONE}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_ORDER_REF}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}</li>
* </ul>
*
* @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:
* <ul>
* <li>{@link StrolchModelConstants#INTERPRETATION_NONE}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_ORDER_REF}</li>
* <li>{@link StrolchModelConstants#INTERPRETATION_RESOURCE_REF}</li>
* </ul>
*
* @param interpretation
*/
public void setInterpretation(String interpretation);
public ITimeValue<T> getNextMatch(Long time, T value); public ITimeValue<T> getNextMatch(Long time, T value);
public ITimeValue<T> getPreviousMatch(Long time, T value); public ITimeValue<T> getPreviousMatch(Long time, T value);
@ -39,4 +111,6 @@ public interface StrolchTimedState<T extends IValue> extends StrolchElement {
public ITimeVariable<T> getTimeEvolution(); public ITimeVariable<T> getTimeEvolution();
public void setParent(Resource aThis); public void setParent(Resource aThis);
public <U> U accept(TimedStateVisitor visitor);
} }

View File

@ -49,4 +49,9 @@ public interface IValue<T> {
* @return a copy of this * @return a copy of this
*/ */
IValue<T> getCopy(); IValue<T> getCopy();
/**
* @return this value in string representation
*/
String getValueAsString();
} }

View File

@ -17,6 +17,8 @@ package li.strolch.model.timevalue.impl;
import java.io.Serializable; import java.io.Serializable;
import ch.eitchnet.utils.dbc.DBC;
/** /**
* Wrapper for java.util.String object defining a inverse to support algebraic operations. * 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; private final boolean inverse;
public AString(final String string) { 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.string = string;
this.inverse = false; this.inverse = false;
} }
public AString(final String string, final boolean inverse) { 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.string = string;
this.inverse = inverse; this.inverse = inverse;
} }

View File

@ -65,6 +65,11 @@ public class BooleanValue implements IValue<Boolean>, Serializable {
public BooleanValue getInverse() { public BooleanValue getInverse() {
return new BooleanValue(!getValue()); return new BooleanValue(!getValue());
} }
@Override
public String getValueAsString() {
return this.value.toString();
}
@SuppressWarnings("nls") @SuppressWarnings("nls")
@Override @Override

View File

@ -64,6 +64,11 @@ public class FloatValue implements IValue<Double>, Serializable {
return this.value; return this.value;
} }
@Override
public String getValueAsString() {
return this.value.toString();
}
@SuppressWarnings("nls") @SuppressWarnings("nls")
@Override @Override
public String toString() { public String toString() {

View File

@ -65,6 +65,11 @@ public class IntegerValue implements IValue<Integer>, Serializable {
public IntegerValue getInverse() { public IntegerValue getInverse() {
return new IntegerValue(-getValue()); return new IntegerValue(-getValue());
} }
@Override
public String getValueAsString() {
return this.value.toString();
}
@SuppressWarnings("nls") @SuppressWarnings("nls")
@Override @Override

View File

@ -15,15 +15,17 @@
*/ */
package li.strolch.model.timevalue.impl; package li.strolch.model.timevalue.impl;
import ch.eitchnet.utils.helper.StringHelper;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import li.strolch.exception.StrolchException; import li.strolch.exception.StrolchException;
import li.strolch.model.timevalue.ITimeValue; import li.strolch.model.timevalue.ITimeValue;
import li.strolch.model.timevalue.IValue; 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 * {@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<Set<AString>>, Serializable {
} }
public StringSetValue(final Set<AString> aStrings) { public StringSetValue(final Set<AString> aStrings) {
// assert no null values in set DBC.PRE.assertNotNull("Value may not be null!", aStrings);
for (AString aString : aStrings) {
if (StringHelper.isEmpty(aString.getString())) {
throw new StrolchException("StringSetValue may not contain null values in set!");
}
}
this.aStrings = aStrings; this.aStrings = aStrings;
} }
@ -105,12 +102,29 @@ public class StringSetValue implements IValue<Set<AString>>, Serializable {
return new StringSetValue(new HashSet<>(this.aStrings)); 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<AString> iter = aStrings.iterator();
while (iter.hasNext()) {
sb.append(iter.next());
if (iter.hasNext())
sb.append(", ");
}
return sb.toString();
}
@SuppressWarnings("nls") @SuppressWarnings("nls")
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("StringSetValue [aStrings="); sb.append("StringSetValue [aStrings=");
sb.append(this.aStrings); sb.append(getValueAsString());
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
} }

View File

@ -18,6 +18,7 @@ package li.strolch.model.visitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import li.strolch.model.GroupedParameterizedElement; import li.strolch.model.GroupedParameterizedElement;
import li.strolch.model.Locator; import li.strolch.model.Locator;
import li.strolch.model.Order; import li.strolch.model.Order;
@ -78,21 +79,21 @@ public class StrolchElementDeepEqualsVisitor {
Set<String> srcTimedStateKeySet = srcRes.getTimedStateKeySet(); Set<String> srcTimedStateKeySet = srcRes.getTimedStateKeySet();
for (String timedStateKey : srcTimedStateKeySet) { for (String timedStateKey : srcTimedStateKeySet) {
StrolchTimedState srcTimedState = srcRes.getTimedState(timedStateKey); StrolchTimedState<?> srcTimedState = srcRes.getTimedState(timedStateKey);
if (!dstRes.hasTimedState(timedStateKey)) { if (!dstRes.hasTimedState(timedStateKey)) {
this.mismatchedLocators.add(srcTimedState.getLocator()); this.mismatchedLocators.add(srcTimedState.getLocator());
continue; continue;
} }
StrolchTimedState dstTimedState = dstRes.getTimedState(timedStateKey); StrolchTimedState<?> dstTimedState = dstRes.getTimedState(timedStateKey);
deepEquals(srcTimedState, dstTimedState); deepEquals(srcTimedState, dstTimedState);
} }
Set<String> dstTimedStateKeySet = dstRes.getTimedStateKeySet(); Set<String> dstTimedStateKeySet = dstRes.getTimedStateKeySet();
for (String timedStateKey : dstTimedStateKeySet) { for (String timedStateKey : dstTimedStateKeySet) {
if (!srcRes.hasTimedState(timedStateKey)) { if (!srcRes.hasTimedState(timedStateKey)) {
StrolchTimedState dstTimedState = dstRes.getTimedState(timedStateKey); StrolchTimedState<?> dstTimedState = dstRes.getTimedState(timedStateKey);
this.mismatchedLocators.add(dstTimedState.getLocator()); this.mismatchedLocators.add(dstTimedState.getLocator());
} }
} }

View File

@ -0,0 +1,39 @@
/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* 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 <eitch@eitchnet.ch>
*/
public interface TimedStateVisitor {
public <T> T visitTimedState(StrolchTimedState<?> timedState);
public <T> T visitBooleanState(BooleanTimedState state);
public <T> T visitFloatState(FloatTimedState state);
public <T> T visitIntegerState(IntegerTimedState state);
public <T> T visitStringState(StringSetTimedState state);
}

View File

@ -15,22 +15,32 @@
*/ */
package li.strolch.model.xml; 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.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter; import javax.xml.stream.XMLStreamWriter;
import li.strolch.model.GroupedParameterizedElement; import li.strolch.model.GroupedParameterizedElement;
import li.strolch.model.Order;
import li.strolch.model.ParameterBag; import li.strolch.model.ParameterBag;
import li.strolch.model.ParameterizedElement; import li.strolch.model.ParameterizedElement;
import li.strolch.model.Resource;
import li.strolch.model.StrolchElement; import li.strolch.model.StrolchElement;
import li.strolch.model.Tags; import li.strolch.model.Tags;
import li.strolch.model.parameter.Parameter; 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; import ch.eitchnet.utils.helper.StringHelper;
/** /**
@ -44,12 +54,52 @@ public abstract class AbstractToSaxWriterVisitor {
this.writer = writer; this.writer = writer;
} }
protected void writeElement(String tag, GroupedParameterizedElement element) throws XMLStreamException { protected void writeElement(String tag, Order order) throws XMLStreamException {
boolean isEmpty = !element.hasParameterBags(); boolean empty = !order.hasParameterBags();
writeStartStrolchElement(tag, isEmpty, element); writeElement(tag, empty, (GroupedParameterizedElement) order);
if (!isEmpty) { if (!empty)
writeParameterBags(element);
this.writer.writeEndElement(); 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<StrolchTimedState<IValue<?>>> timedStates = resource.getTimedStates();
for (StrolchTimedState<IValue<?>> timedState : timedStates) {
ITimeVariable<IValue<?>> timeEvolution = timedState.getTimeEvolution();
SortedSet<ITimeValue<IValue<?>>> values = timeEvolution.getValues();
writeStartStrolchElement(Tags.TIMED_STATE, !values.isEmpty(), timedState);
for (ITimeValue<IValue<?>> 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()); this.writer.writeAttribute(Tags.TYPE, element.getType());
} }
protected void writeParameters(ParameterizedElement element) throws XMLStreamException {
List<Parameter<?>> parameters = new ArrayList<>(element.getParameters());
Collections.sort(parameters, new Comparator<Parameter<?>>() {
@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 { protected void writeParameterBags(GroupedParameterizedElement element) throws XMLStreamException {
Set<String> bagKeySet = new TreeSet<>(element.getParameterBagKeySet()); Set<String> bagKeySet = new TreeSet<>(element.getParameterBagKeySet());
for (String bagKey : bagKeySet) { for (String bagKey : bagKeySet) {
@ -109,4 +130,33 @@ public abstract class AbstractToSaxWriterVisitor {
} }
} }
} }
protected void writeParameters(ParameterizedElement element) throws XMLStreamException {
List<Parameter<?>> parameters = new ArrayList<>(element.getParameters());
Collections.sort(parameters, new Comparator<Parameter<?>>() {
@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());
}
}
} }

View File

@ -15,6 +15,9 @@
*/ */
package li.strolch.model.xml; 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 java.util.Set;
import li.strolch.model.GroupedParameterizedElement; import li.strolch.model.GroupedParameterizedElement;
@ -61,10 +64,10 @@ public abstract class StrolchElementToSaxVisitor {
AttributesImpl attributes = attributesFor((StrolchElement) parameter); AttributesImpl attributes = attributesFor((StrolchElement) parameter);
attributes.addAttribute(null, null, Tags.VALUE, Tags.CDATA, parameter.getValueAsString()); 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()); 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()); attributes.addAttribute(null, null, Tags.INTERPRETATION, Tags.CDATA, parameter.getInterpretation());
} }
if (parameter.isHidden()) { if (parameter.isHidden()) {

View File

@ -17,6 +17,8 @@ package li.strolch.model.xml;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import li.strolch.exception.StrolchException; import li.strolch.exception.StrolchException;
import li.strolch.model.GroupedParameterizedElement; 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.Parameter;
import li.strolch.model.parameter.StringListParameter; import li.strolch.model.parameter.StringListParameter;
import li.strolch.model.parameter.StringParameter; 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.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -56,6 +69,8 @@ public class XmlModelSaxReader extends DefaultHandler {
private GroupedParameterizedElement parameterizedElement; private GroupedParameterizedElement parameterizedElement;
private ParameterBag pBag; private ParameterBag pBag;
private StrolchTimedState<? extends IValue<?>> state;
private String stateType;
public XmlModelSaxReader(StrolchElementListener listener) { public XmlModelSaxReader(StrolchElementListener listener) {
this.listener = listener; this.listener = listener;
@ -165,6 +180,63 @@ public class XmlModelSaxReader extends DefaultHandler {
} }
break; 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<AString> 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: default:
throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$ throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$
} }
@ -193,6 +265,11 @@ public class XmlModelSaxReader extends DefaultHandler {
break; break;
case Tags.INCLUDE_FILE: case Tags.INCLUDE_FILE:
break; break;
case Tags.TIMED_STATE:
((Resource) this.parameterizedElement).addTimedState(state);
break;
case Tags.VALUE:
break;
default: default:
throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$ throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$
} }

View File

@ -15,6 +15,7 @@
*/ */
package li.strolch.model; package li.strolch.model;
import static li.strolch.model.ModelGenerator.*;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -22,7 +23,7 @@ import static org.junit.Assert.assertTrue;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import static li.strolch.model.Tags.*;
import li.strolch.model.parameter.BooleanParameter; import li.strolch.model.parameter.BooleanParameter;
import li.strolch.model.parameter.DateParameter; import li.strolch.model.parameter.DateParameter;
import li.strolch.model.parameter.FloatParameter; 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.StringListParameter;
import li.strolch.model.parameter.StringParameter; import li.strolch.model.parameter.StringParameter;
import li.strolch.model.timedstate.BooleanTimedState; 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.BooleanValue;
import li.strolch.model.timevalue.impl.ValueChange; import li.strolch.model.timevalue.impl.ValueChange;
import li.strolch.model.visitor.OrderDeepEqualsVisitor; import li.strolch.model.visitor.OrderDeepEqualsVisitor;
@ -44,23 +48,44 @@ public class ModelTest {
@Test @Test
public void shouldCreateResource() { public void shouldCreateResource() {
Resource resource = ModelGenerator.createResource("@res01", "Test resource", "MyType"); Resource resource = createResource("@res01", "Test resource", "MyType");
ParameterBag bag = resource.getParameterBag(ModelGenerator.BAG_ID); ParameterBag bag = resource.getParameterBag(BAG_ID);
validateBag(bag); validateBag(bag);
validateStates(resource);
} }
@Test @Test
public void shouldCreateOrder() { public void shouldCreateOrder() {
Order order = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", new Date(), State.OPEN); Order order = createOrder("@ord01", "Test Order", "MyType", new Date(), State.OPEN);
ParameterBag bag = order.getParameterBag(ModelGenerator.BAG_ID); ParameterBag bag = order.getParameterBag(BAG_ID);
validateBag(bag); 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 @Test
public void shouldPerformDeepResourceEquals() { public void shouldPerformDeepResourceEquals() {
Resource srcRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); Resource srcRes = createResource("@res01", "Test resource", "MyType");
Resource dstRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); Resource dstRes = createResource("@res01", "Test resource", "MyType");
ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes);
visitor.visit(dstRes); visitor.visit(dstRes);
assertTrue("Same Resource should be deep equal!", visitor.isEqual()); assertTrue("Same Resource should be deep equal!", visitor.isEqual());
@ -68,11 +93,11 @@ public class ModelTest {
@Test @Test
public void shouldFailDeepResourceEquals1() { public void shouldFailDeepResourceEquals1() {
Resource srcRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); Resource srcRes = createResource("@res01", "Test resource", "MyType");
Resource dstRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); Resource dstRes = createResource("@res01", "Test resource", "MyType");
ParameterBag bag = dstRes.getParameterBag(ModelGenerator.BAG_ID); ParameterBag bag = dstRes.getParameterBag(BAG_ID);
bag.setName("Bla bla"); bag.setName("Bla bla");
FloatParameter fParam = bag.getParameter(ModelGenerator.PARAM_FLOAT_ID); FloatParameter fParam = bag.getParameter(PARAM_FLOAT_ID);
fParam.setValue(23434234.234); fParam.setValue(23434234.234);
fParam.setName("Ohla"); fParam.setName("Ohla");
ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes);
@ -83,9 +108,9 @@ public class ModelTest {
@Test @Test
public void shouldFailDeepResourceEquals2() { public void shouldFailDeepResourceEquals2() {
Resource srcRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); Resource srcRes = createResource("@res01", "Test resource", "MyType");
Resource dstRes = ModelGenerator.createResource("@res01", "Test resource", "MyType"); Resource dstRes = createResource("@res01", "Test resource", "MyType");
BooleanTimedState timedState = dstRes.getTimedState(ModelGenerator.STATE_BOOLEAN_ID); BooleanTimedState timedState = dstRes.getTimedState(STATE_BOOLEAN_ID);
timedState.applyChange(new ValueChange<>(System.currentTimeMillis(), new BooleanValue(Boolean.TRUE))); timedState.applyChange(new ValueChange<>(System.currentTimeMillis(), new BooleanValue(Boolean.TRUE)));
timedState.setName("Ohla"); timedState.setName("Ohla");
ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes);
@ -97,8 +122,8 @@ public class ModelTest {
@Test @Test
public void shouldPerformDeepOrderEquals() { public void shouldPerformDeepOrderEquals() {
Date date = new Date(); Date date = new Date();
Order srcOrder = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", date, State.OPEN); Order srcOrder = createOrder("@ord01", "Test Order", "MyType", date, State.OPEN);
Order dstOrder = ModelGenerator.createOrder("@ord01", "Test Order", "MyType", date, State.OPEN); Order dstOrder = createOrder("@ord01", "Test Order", "MyType", date, State.OPEN);
OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(srcOrder); OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(srcOrder);
visitor.visit(dstOrder); visitor.visit(dstOrder);
assertTrue("Same Order should be deep equal: " + visitor.getMismatchedLocators(), visitor.isEqual()); assertTrue("Same Order should be deep equal: " + visitor.getMismatchedLocators(), visitor.isEqual());
@ -108,45 +133,78 @@ public class ModelTest {
assertNotNull(bag); assertNotNull(bag);
assertEquals(ModelGenerator.BAG_ID, bag.getId()); assertEquals(BAG_ID, bag.getId());
assertEquals(ModelGenerator.BAG_NAME, bag.getName()); assertEquals(BAG_NAME, bag.getName());
assertEquals(ModelGenerator.BAG_TYPE, bag.getType()); assertEquals(BAG_TYPE, bag.getType());
validateParams(bag); validateParams(bag);
} }
public static void validateParams(ParameterBag bag) { public static void validateParams(ParameterBag bag) {
BooleanParameter boolParam = bag.getParameter(ModelGenerator.PARAM_BOOLEAN_ID); BooleanParameter boolParam = bag.getParameter(PARAM_BOOLEAN_ID);
assertNotNull("Boolean Param missing with id " + ModelGenerator.PARAM_BOOLEAN_ID, boolParam); assertNotNull("Boolean Param missing with id " + PARAM_BOOLEAN_ID, boolParam);
assertEquals(true, boolParam.getValue().booleanValue()); assertEquals(true, boolParam.getValue().booleanValue());
FloatParameter floatParam = bag.getParameter(ModelGenerator.PARAM_FLOAT_ID); FloatParameter floatParam = bag.getParameter(PARAM_FLOAT_ID);
assertNotNull("Float Param missing with id " + ModelGenerator.PARAM_FLOAT_ID, floatParam); assertNotNull("Float Param missing with id " + PARAM_FLOAT_ID, floatParam);
assertEquals(44.3, floatParam.getValue().doubleValue(), 0.0001); assertEquals(44.3, floatParam.getValue().doubleValue(), 0.0001);
IntegerParameter integerParam = bag.getParameter(ModelGenerator.PARAM_INTEGER_ID); IntegerParameter integerParam = bag.getParameter(PARAM_INTEGER_ID);
assertNotNull("Integer Param missing with id " + ModelGenerator.PARAM_INTEGER_ID, integerParam); assertNotNull("Integer Param missing with id " + PARAM_INTEGER_ID, integerParam);
assertEquals(77, integerParam.getValue().intValue()); assertEquals(77, integerParam.getValue().intValue());
LongParameter longParam = bag.getParameter(ModelGenerator.PARAM_LONG_ID); LongParameter longParam = bag.getParameter(PARAM_LONG_ID);
assertNotNull("Long Param missing with id " + ModelGenerator.PARAM_LONG_ID, longParam); assertNotNull("Long Param missing with id " + PARAM_LONG_ID, longParam);
assertEquals(4453234566L, longParam.getValue().longValue()); assertEquals(4453234566L, longParam.getValue().longValue());
StringParameter stringParam = bag.getParameter(ModelGenerator.PARAM_STRING_ID); StringParameter stringParam = bag.getParameter(PARAM_STRING_ID);
assertNotNull("String Param missing with id " + ModelGenerator.PARAM_STRING_ID, stringParam); assertNotNull("String Param missing with id " + PARAM_STRING_ID, stringParam);
assertEquals("Strolch", stringParam.getValue()); assertEquals("Strolch", stringParam.getValue());
DateParameter dateParam = bag.getParameter(ModelGenerator.PARAM_DATE_ID); DateParameter dateParam = bag.getParameter(PARAM_DATE_ID);
assertNotNull("Date Param missing with id " + ModelGenerator.PARAM_DATE_ID, dateParam); assertNotNull("Date Param missing with id " + PARAM_DATE_ID, dateParam);
assertEquals(1354295525628L, dateParam.getValue().getTime()); assertEquals(1354295525628L, dateParam.getValue().getTime());
StringListParameter stringListP = bag.getParameter(ModelGenerator.PARAM_LIST_STRING_ID); StringListParameter stringListP = bag.getParameter(PARAM_LIST_STRING_ID);
assertNotNull("StringList Param missing with id " + ModelGenerator.PARAM_LIST_STRING_ID, stringListP); assertNotNull("StringList Param missing with id " + PARAM_LIST_STRING_ID, stringListP);
ArrayList<String> stringList = new ArrayList<>(); ArrayList<String> stringList = new ArrayList<>();
stringList.add("Hello"); stringList.add("Hello");
stringList.add("World"); stringList.add("World");
assertEquals(stringList, stringListP.getValue()); 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());
}
} }