diff --git a/li.strolch.model/.gitignore b/li.strolch.model/.gitignore new file mode 100644 index 000000000..fd1deeecb --- /dev/null +++ b/li.strolch.model/.gitignore @@ -0,0 +1,16 @@ +/.settings +/.classpath +/.project +/target +/target +/target +/target +/target +/target +/target +/target +/target +/target +/target +/target +/target diff --git a/li.strolch.model/LICENSE b/li.strolch.model/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/li.strolch.model/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/li.strolch.model/README.md b/li.strolch.model/README.md new file mode 100644 index 000000000..34313a285 --- /dev/null +++ b/li.strolch.model/README.md @@ -0,0 +1,6 @@ +li.strolch.model +================ + +[![Build Status](http://jenkins.eitchnet.ch/buildStatus/icon?job=li.strolch.model)](http://jenkins.eitchnet.ch/view/strolch/job/li.strolch.model/) + +Strolch is a generic framework for building parameterized models for modification at runtime written in Java \ No newline at end of file diff --git a/li.strolch.model/pom.xml b/li.strolch.model/pom.xml new file mode 100644 index 000000000..e34d5eefe --- /dev/null +++ b/li.strolch.model/pom.xml @@ -0,0 +1,78 @@ + + 4.0.0 + + + li.strolch + li.strolch.parent + 1.0.0-SNAPSHOT + ../li.strolch.parent/pom.xml + + + li.strolch.model + jar + li.strolch.model + https://github.com/eitchnet/li.strolch.model + + 2012 + + + Github Issues + https://github.com/eitchnet/li.strolch.model/issues + + + + scm:git:https://github.com/eitchnet/li.strolch.model.git + scm:git:git@github.com:eitch/li.strolch.model.git + https://github.com/eitchnet/li.strolch.model + + + + + ch.eitchnet + ch.eitchnet.utils + + + ch.eitchnet + ch.eitchnet.privilege + + + + + + + src/main/resources + true + + **/componentVersion.properties + + + + + + org.codehaus.mojo + buildnumber-maven-plugin + + + org.apache.maven.plugins + maven-eclipse-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-jar-plugin + + + org.apache.maven.plugins + maven-site-plugin + + + + diff --git a/li.strolch.model/src/main/java/li/strolch/exception/StrolchException.java b/li.strolch.model/src/main/java/li/strolch/exception/StrolchException.java new file mode 100644 index 000000000..67c43b706 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/exception/StrolchException.java @@ -0,0 +1,40 @@ +/* + * 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.exception; + +/** + * @author Robert von Burg + * + */ +public class StrolchException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + /** + * @param message + * @param cause + */ + public StrolchException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + */ + public StrolchException(String message) { + super(message); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/AbstractStrolchElement.java b/li.strolch.model/src/main/java/li/strolch/model/AbstractStrolchElement.java new file mode 100644 index 000000000..44783903d --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/AbstractStrolchElement.java @@ -0,0 +1,179 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.text.MessageFormat; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Locator.LocatorBuilder; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + */ +public abstract class AbstractStrolchElement implements StrolchElement { + + private static final long serialVersionUID = 0L; + + protected long dbid = Long.MAX_VALUE; + protected String id; + protected String name; + + /** + * Empty constructor + */ + public AbstractStrolchElement() { + // + } + + /** + * Default constructor + * + * @param id + * id of this {@link StrolchElement} + * @param name + * name of this {@link StrolchElement} + */ + public AbstractStrolchElement(String id, String name) { + setId(id); + setName(name); + } + + @Override + public long getDbid() { + return this.dbid; + } + + @Override + public void setDbid(long dbid) { + this.dbid = dbid; + } + + @Override + public String getId() { + return this.id; + } + + @Override + public void setId(String id) { + if (StringHelper.isEmpty(id)) { + String msg = "The id may never be empty for {0}"; + msg = MessageFormat.format(msg, getClass().getSimpleName()); + throw new StrolchException(msg); + } + this.id = id; + } + + @Override + public String getName() { + return this.name; + } + + @Override + public void setName(String name) { + if (StringHelper.isEmpty(name)) { + String msg = "The name may never be empty for {0} {1}"; + msg = MessageFormat.format(msg, getClass().getSimpleName(), getLocator()); + throw new StrolchException(msg); + } + this.name = name; + } + + /** + * Used to build a {@link Locator} for this {@link StrolchElement}. It must be implemented by the concrete + * implemented as parents must first add their {@link Locator} information + * + * @param locatorBuilder + * the {@link LocatorBuilder} to which the {@link StrolchElement} must add its locator information + */ + protected abstract void fillLocator(LocatorBuilder locatorBuilder); + + /** + * fills the {@link StrolchElement} clone with the id, name and type + * + * @param clone + */ + protected void fillClone(StrolchElement clone) { + clone.setId(getId()); + clone.setName(getName()); + } + + protected void fillElement(Element element) { + element.setAttribute(Tags.ID, getId()); + element.setAttribute(Tags.NAME, getName()); + element.setAttribute(Tags.TYPE, getType()); + } + + /** + * Builds the fields of this {@link StrolchElement} from a {@link Element} + * + * @param element + */ + protected void fromDom(Element element) { + String id = element.getAttribute(Tags.ID); + String name = element.getAttribute(Tags.NAME); + + if (id != null && name != null) { + setId(id); + setName(name); + } else { + String msg = "Check the values of the element: {0} either id or name attribute is null!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, element.getNodeName()); + throw new StrolchException(msg); + } + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + AbstractStrolchElement other = (AbstractStrolchElement) obj; + if (this.id == null) { + if (other.id != null) { + return false; + } + } else if (!this.id.equals(other.id)) { + return false; + } + return true; + } + + @Override + public int compareTo(StrolchElement o) { + return getId().compareTo(o.getId()); + } + + @Override + public abstract String toString(); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/GroupedParameterizedElement.java b/li.strolch.model/src/main/java/li/strolch/model/GroupedParameterizedElement.java new file mode 100644 index 000000000..44a70636b --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/GroupedParameterizedElement.java @@ -0,0 +1,300 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.text.MessageFormat; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import li.strolch.exception.StrolchException; +import li.strolch.model.parameter.Parameter; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + */ +public abstract class GroupedParameterizedElement extends AbstractStrolchElement { + + private static final long serialVersionUID = 0L; + + protected Map parameterBagMap; + protected String type; + + /** + * Empty constructor + */ + protected GroupedParameterizedElement() { + // + } + + /** + * Default Constructor + * + * @param id + * @param name + * @param type + */ + protected GroupedParameterizedElement(String id, String name, String type) { + super(id, name); + setType(type); + } + + @Override + public String getType() { + return this.type; + } + + /** + * Sets the type of this {@link GroupedParameterizedElement} + * + * @param type + * the type to set + */ + public void setType(String type) { + if (StringHelper.isEmpty(type)) { + String msg = "Type may not be empty on element {0}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, getLocator()); + throw new StrolchException(msg); + } + + this.type = type; + } + + /** + * Returns the {@link Parameter} with the given key from the {@link ParameterBag} with the given bagKey, or null if + * the {@link Parameter} or the {@link ParameterBag} does not exist + * + * @param bagKey + * the key of the {@link ParameterBag} from which the {@link Parameter} is to be returned + * @param paramKey + * the key of the {@link Parameter} which is to be returned + * + * @return the found {@link Parameter} or null if it was not found + */ + public T getParameter(String bagKey, String paramKey) { + if (this.parameterBagMap == null) { + return null; + } + ParameterBag bag = this.parameterBagMap.get(bagKey); + if (bag == null) { + return null; + } + + return bag.getParameter(paramKey); + } + + /** + * Adds a new {@link Parameter} to the {@link ParameterBag} with the given key + * + * @param bagKey + * the key of the {@link ParameterBag} to which the {@link Parameter} should be added + * @param parameter + * the {@link Parameter} to be added to the {@link ParameterBag} + * + * @throws StrolchException + * if the {@link ParameterBag} does not exist + */ + public void addParameter(String bagKey, Parameter parameter) throws StrolchException { + if (this.parameterBagMap == null) { + this.parameterBagMap = new HashMap(); + } + ParameterBag bag = this.parameterBagMap.get(bagKey); + if (bag == null) { + String msg = "No parameter bag exists with key {0}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, bagKey); + throw new StrolchException(msg); + } + + bag.addParameter(parameter); + } + + /** + * Removes the {@link Parameter} with the given paramKey from the {@link ParameterBag} with the given bagKey + * + * @param bagKey + * the key of the {@link ParameterBag} from which the {@link Parameter} is to be removed + * @param paramKey + * the key of the {@link Parameter} which is to be removed + * + * @return the removed {@link Parameter} or null if it did not exist + */ + public Parameter removeParameter(String bagKey, String paramKey) { + if (this.parameterBagMap == null) { + return null; + } + ParameterBag bag = this.parameterBagMap.get(bagKey); + if (bag == null) { + return null; + } + + return bag.removeParameter(paramKey); + } + + /** + * Returns the {@link ParameterBag} with the given key, or null if it does not exist + * + * @param key + * the key of the {@link ParameterBag} to return + * + * @return the {@link ParameterBag} with the given key, or null if it does not exist + */ + public ParameterBag getParameterBag(String key) { + if (this.parameterBagMap == null) { + return null; + } + return this.parameterBagMap.get(key); + } + + /** + * Adds the given {@link ParameterBag} to this {@link GroupedParameterizedElement} + * + * @param bag + * the {@link ParameterBag} to add + */ + public void addParameterBag(ParameterBag bag) { + if (this.parameterBagMap == null) { + this.parameterBagMap = new HashMap(); + } + + if (this.parameterBagMap.containsKey(bag.getId())) { + String msg = "A ParameterBag already exists with id {0} on {1}"; + throw new StrolchException(MessageFormat.format(msg, bag.getId(), getLocator())); + } + this.parameterBagMap.put(bag.getId(), bag); + bag.setParent(this); + } + + /** + * Removes the {@link ParameterBag} with the given key + * + * @param key + * the key of the {@link ParameterBag} to remove + * + * @return the removed {@link ParameterBag}, or null if it does not exist + */ + public ParameterBag removeParameterBag(String key) { + if (this.parameterBagMap == null) { + return null; + } + return this.parameterBagMap.remove(key); + } + + /** + * Returns true if this {@link GroupedParameterizedElement} has any {@link ParameterBag ParameterBag} + * + * @return true if this {@link GroupedParameterizedElement} has any {@link ParameterBag ParameterBag} + */ + public boolean hasParameterBags() { + return this.parameterBagMap != null && !this.parameterBagMap.isEmpty(); + } + + /** + * Returns true if the {@link ParameterBag} with the given key exists on this {@link GroupedParameterizedElement}. + * + * @param bagKey + * the key of the {@link ParameterBag} which is to be checked for existence + * @return true if the {@link ParameterBag} with the given key exists on this {@link GroupedParameterizedElement}. + */ + public boolean hasParameterBag(String bagKey) { + return this.parameterBagMap != null && this.parameterBagMap.containsKey(bagKey); + } + + /** + * Returns true if the {@link Parameter} with the given paramKey exists on the {@link ParameterBag} with the given + * bagKey + * + * @param bagKey + * the key of the {@link ParameterBag} on which to find the {@link Parameter} + * @param paramKey + * the key of the {@link Parameter} to be found + * + * @return true if the {@link Parameter} with the given paramKey exists on the {@link ParameterBag} with the given + * bagKey. False is returned if the {@link ParameterBag} does not exist, or the {@link Parameter} does not + * exist on the {@link ParameterBag} + */ + public boolean hasParameter(String bagKey, String paramKey) { + if (this.parameterBagMap == null) { + return false; + } + ParameterBag bag = this.parameterBagMap.get(bagKey); + if (bag == null) { + return false; + } + + return bag.hasParameter(paramKey); + } + + /** + * Returns the {@link Set} of keys for the {@link ParameterBag}s on this {@link GroupedParameterizedElement} + * + * @return the {@link Set} of keys for the {@link ParameterBag}s on this {@link GroupedParameterizedElement} + */ + public Set getParameterBagKeySet() { + if (this.parameterBagMap == null) { + return Collections.emptySet(); + } + return new HashSet(this.parameterBagMap.keySet()); + } + + @Override + public void fromDom(Element element) { + super.fromDom(element); + + String type = element.getAttribute(Tags.TYPE); + setType(type); + + NodeList bags = element.getElementsByTagName(Tags.PARAMETER_BAG); + for (int i = 0; i < bags.getLength(); i++) { + Element bagElement = (Element) bags.item(i); + ParameterBag bag = new ParameterBag(bagElement); + addParameterBag(bag); + } + } + + @Override + protected void fillElement(Element element) { + super.fillElement(element); + + if (this.parameterBagMap != null) { + for (ParameterBag bag : this.parameterBagMap.values()) { + element.appendChild(bag.toDom(element.getOwnerDocument())); + } + } + } + + /** + * Fills {@link GroupedParameterizedElement} properties of this clone + * + * @param clone + */ + protected void fillClone(GroupedParameterizedElement clone) { + super.fillClone(clone); + clone.setType(getType()); + + if (this.parameterBagMap != null) { + for (ParameterBag bag : this.parameterBagMap.values()) { + clone.addParameterBag(bag.getClone()); + } + } + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/Locator.java b/li.strolch.model/src/main/java/li/strolch/model/Locator.java new file mode 100644 index 000000000..5e60f9852 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/Locator.java @@ -0,0 +1,368 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import li.strolch.exception.StrolchException; +import ch.eitchnet.utils.helper.StringHelper; + +/** + *

+ * The {@link Locator} is an immutable object and is used to fully qualify the location of an object in the model. It + * consists of a {@link List} of Strings which starting from the first value, defining the root, with the last item + * defining the objects id. + *

+ * + *

+ * When the {@link Locator} is formatted to a String, it resembles the same format as is used in Unix based files + * systems, with slashes (/), separating the different list values + *

+ * + *

+ * A {@link Locator} is always immutable, modifications return a new instance + *

+ * + * @author Robert von Burg + */ +public class Locator { + + /** + * The separator used when formatting a {@link Locator} object ot a string + */ + public static final String PATH_SEPARATOR = "/"; //$NON-NLS-1$ + + /** + * {@link List} of path elements, with the first being the top level or root element + */ + private final List pathElements; + + /** + * Constructs a new {@link Locator} with the given list of path elements + * + * @param pathElements + * the elements making up the {@link Locator} + * + * @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()) { + throw new StrolchException("The path elements may not be null and must contain at least 1 item"); //$NON-NLS-1$ + } + 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 + * + * @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)); + } + + /** + * Internal constructor to append a sub path to a constructor + * + * @param path + * the base path of the locator + * @param subPath + * the additional path + */ + private Locator(List path, List subPath) { + List fullPath = new ArrayList(); + fullPath.addAll(path); + fullPath.addAll(subPath); + this.pathElements = Collections.unmodifiableList(fullPath); + } + + /** + * Internal constructor to append a element to a constructor + * + * @param path + * the base path of the locator + * @param element + * the additional element + */ + private Locator(List path, String element) { + List fullPath = new ArrayList(); + fullPath.addAll(path); + fullPath.add(element); + this.pathElements = Collections.unmodifiableList(fullPath); + } + + /** + * Returns the immutable list of path elements making up this locator + * + * @return the pathElements + */ + public List getPathElements() { + return this.pathElements; + } + + /** + * Returns the number of elements which this {@link Locator} contains + * + * @return the number of elements which this {@link Locator} contains + */ + public int getSize() { + return this.pathElements.size(); + } + + /** + * Returns a new {@link Locator} where the given sub path is appended to the locator + * + * @param subPathElements + * the sub path to append + * + * @return the new locator + */ + public Locator append(List subPathElements) { + return new Locator(this.pathElements, subPathElements); + } + + /** + * Returns a new {@link Locator} where the given element is appended to the locator + * + * @param element + * the element to append + * + * @return the new locator + */ + public Locator append(String element) { + return new Locator(this.pathElements, element); + } + + /** + * Returns the string representation of this {@link Locator} by using the {@link #PATH_SEPARATOR} to separate the + * values + */ + @Override + public String toString() { + return formatPath(this.pathElements); + } + + /** + * 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 + * + * @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} + */ + private List parsePath(String path) throws StrolchException { + if (StringHelper.isEmpty(path)) { + throw new StrolchException("A path may not be empty!"); //$NON-NLS-1$ + } + String[] elements = path.split(Locator.PATH_SEPARATOR); + return Arrays.asList(elements); + } + + /** + * Formats the given list of path elements to a String representation of the {@link Locator} + * + * @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 + */ + private String formatPath(List pathElements) throws StrolchException { + StringBuilder sb = new StringBuilder(); + + Iterator iter = pathElements.iterator(); + while (iter.hasNext()) { + String element = iter.next(); + sb.append(element); + if (iter.hasNext()) { + sb.append(Locator.PATH_SEPARATOR); + } + } + + return sb.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.pathElements == null) ? 0 : this.pathElements.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Locator other = (Locator) obj; + if (this.pathElements == null) { + if (other.pathElements != null) { + return false; + } + } else if (!this.pathElements.equals(other.pathElements)) { + return false; + } + return true; + } + + /** + * Instantiates a new immutable {@link Locator} instance from the given string + * + * @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 elements to it + * + * @param path + * the first element on the {@link Locator} + * + * @return a new {@link LocatorBuilder} instance with the given root element tag as the first element + */ + public static LocatorBuilder newBuilder(String... path) { + return new LocatorBuilder().append(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} + * + * @return a new {@link LocatorBuilder} instance with the given root element tag as the first element + */ + public static LocatorBuilder newBuilder(String rootElement) { + return new LocatorBuilder().append(rootElement); + } + + /** + * {@link LocatorBuilder} is used to build {@link Locator}s where a deep hierarchy is to be created. The + * {@link #append(String)} method returns itself for chain building + * + * @author Robert von Burg + */ + public static class LocatorBuilder { + + private final List pathElements; + + /** + * Default constructor + */ + public LocatorBuilder() { + this.pathElements = new ArrayList(); + } + + /** + * Append the given elements to the path + * + * @param path + * the path elements to add + * + * @return this instance for chaining + */ + public LocatorBuilder append(String... path) { + for (String element : path) { + this.pathElements.add(element); + } + return this; + } + + /** + * Append an element to the path + * + * @param element + * the element to add + * + * @return this instance for chaining + */ + public LocatorBuilder append(String element) { + this.pathElements.add(element); + return this; + } + + /** + * Remove the last element from the path + * + * @return this instance for chaining + */ + public LocatorBuilder removeLast() { + this.pathElements.remove(this.pathElements.size() - 1); + return this; + } + + /** + * Creates an immutable {@link Locator} instance with the current elements + * + * @return a new {@link Locator} instance + */ + public Locator build() { + if (this.pathElements.isEmpty()) { + throw new StrolchException("The path elements must contain at least 1 item"); //$NON-NLS-1$ + } + return new Locator(this.pathElements); + } + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java b/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java new file mode 100644 index 000000000..701b9a248 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java @@ -0,0 +1,404 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.Set; + +import li.strolch.model.audit.AccessType; +import li.strolch.model.audit.Audit; +import li.strolch.model.parameter.BooleanParameter; +import li.strolch.model.parameter.DateParameter; +import li.strolch.model.parameter.FloatParameter; +import li.strolch.model.parameter.IntegerParameter; +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.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 li.strolch.model.timevalue.impl.ValueChange; +import ch.eitchnet.utils.helper.StringHelper; + +/** + * Class which can be used to generate objects which implement {@link StrolchElement}. These generated classes can then + * be used in test classes etc. + * + * @author Robert von Burg + */ +@SuppressWarnings("nls") +public class ModelGenerator { + + public static final String PARAM_BOOLEAN_ID = "@param1"; + public static final String PARAM_BOOLEAN_NAME = "Boolean Param"; + + public static final String PARAM_FLOAT_ID = "@param2"; + public static final String PARAM_FLOAT_NAME = "Float Param"; + + public static final String PARAM_INTEGER_ID = "@param3"; + public static final String PARAM_INTEGER_NAME = "Integer Param"; + + public static final String PARAM_LONG_ID = "@param4"; + public static final String PARAM_LONG_NAME = "Long Param"; + + public static final String PARAM_STRING_ID = "@param5"; + public static final String PARAM_STRING_NAME = "String Param"; + + public static final String PARAM_DATE_ID = "@param6"; + public static final String PARAM_DATE_NAME = "Date Param"; + + public static final String PARAM_LIST_STRING_ID = "@param7"; + public static final String PARAM_LIST_STRING_NAME = "StringList Param"; + + public static final String STATE_FLOAT_ID = "@state1"; + public static final String STATE_FLOAT_NAME = "Float State"; + + public static final String STATE_INTEGER_ID = "@state2"; + public static final String STATE_INTEGER_NAME = "Float State"; + + public static final String STATE_STRING_ID = "@state3"; + public static final String STATE_STRING_NAME = "Float State"; + + public static final String STATE_BOOLEAN_ID = "@state4"; + public static final String STATE_BOOLEAN_NAME = "Float State"; + + public static final long STATE_TIME_0 = 0L; + public static final long STATE_TIME_10 = 10L; + public static final long STATE_TIME_20 = 20L; + public static final long STATE_TIME_30 = 30L; + + public static final Double STATE_FLOAT_TIME_0 = 0.0D; + public static final Double STATE_FLOAT_TIME_10 = 10.0D; + public static final Double STATE_FLOAT_TIME_20 = 20.0D; + public static final Double STATE_FLOAT_TIME_30 = 30.0D; + + public static final Integer STATE_INTEGER_TIME_0 = 0; + public static final Integer STATE_INTEGER_TIME_10 = 10; + public static final Integer STATE_INTEGER_TIME_20 = 20; + public static final Integer STATE_INTEGER_TIME_30 = 30; + + public static final String STATE_STRING_TIME_0 = "empty"; + public static final String STATE_STRING_TIME_10 = "a"; + public static final String STATE_STRING_TIME_20 = "b"; + public static final String STATE_STRING_TIME_30 = "c"; + + public static final Boolean STATE_BOOLEAN_TIME_0 = Boolean.FALSE; + public static final Boolean STATE_BOOLEAN_TIME_10 = Boolean.TRUE; + public static final Boolean STATE_BOOLEAN_TIME_20 = Boolean.FALSE; + public static final Boolean STATE_BOOLEAN_TIME_30 = Boolean.TRUE; + + public static final String BAG_ID = "@bag01"; + public static final String BAG_NAME = "Test Bag"; + public static final String BAG_TYPE = "TestBag"; + + /** + * Creates an {@link Resource} with the given values and adds a {@link ParameterBag} by calling + * {@link #createParameterBag(String, String, String)} + * + * @param id + * the id of the {@link Resource} + * @param name + * the name of the {@link Resource} + * @param type + * the type of the {@link Resource} + * + * @return the newly created {@link Resource} + */ + public static Resource createResource(String id, String name, String type) { + Resource resource = new Resource(id, name, type); + ParameterBag bag = createParameterBag(BAG_ID, BAG_NAME, BAG_TYPE); + resource.addParameterBag(bag); + addTimedStates(resource); + + return resource; + } + + /** + * Creates {@link StrolchTimedState} instances and adds them to the {@link Resource} + * + * @param resource + * the resource to which to addd the newly created {@link StrolchTimedState} + */ + public static void addTimedStates(Resource resource) { + + // float state + FloatTimedState floatTimedState = new FloatTimedState(STATE_FLOAT_ID, STATE_FLOAT_NAME); + floatTimedState.applyChange(new ValueChange<>(STATE_TIME_0, new FloatValue(STATE_FLOAT_TIME_0))); + FloatValue floatValueChange = new FloatValue(STATE_FLOAT_TIME_10); + floatTimedState.applyChange(new ValueChange<>(STATE_TIME_10, floatValueChange)); + floatTimedState.applyChange(new ValueChange<>(STATE_TIME_20, floatValueChange)); + floatTimedState.applyChange(new ValueChange<>(STATE_TIME_30, floatValueChange)); + resource.addTimedState(floatTimedState); + + // integer state + IntegerTimedState integerTimedState = new IntegerTimedState(STATE_INTEGER_ID, STATE_INTEGER_NAME); + integerTimedState.applyChange(new ValueChange<>(STATE_TIME_0, new IntegerValue(STATE_INTEGER_TIME_0))); + IntegerValue integerValueChange = new IntegerValue(STATE_INTEGER_TIME_10); + integerTimedState.applyChange(new ValueChange<>(STATE_TIME_10, integerValueChange)); + integerTimedState.applyChange(new ValueChange<>(STATE_TIME_20, integerValueChange)); + integerTimedState.applyChange(new ValueChange<>(STATE_TIME_30, integerValueChange)); + resource.addTimedState(integerTimedState); + + // boolean state + BooleanTimedState booleanTimedState = new BooleanTimedState(STATE_BOOLEAN_ID, STATE_BOOLEAN_NAME); + booleanTimedState.applyChange(new ValueChange<>(STATE_TIME_0, new BooleanValue(STATE_BOOLEAN_TIME_0))); + BooleanValue booleanValueChange = new BooleanValue(STATE_BOOLEAN_TIME_10); + booleanTimedState.applyChange(new ValueChange<>(STATE_TIME_10, booleanValueChange)); + booleanValueChange = booleanValueChange.getInverse(); + booleanTimedState.applyChange(new ValueChange<>(STATE_TIME_20, booleanValueChange)); + booleanValueChange = booleanValueChange.getInverse(); + booleanTimedState.applyChange(new ValueChange<>(STATE_TIME_30, booleanValueChange)); + resource.addTimedState(booleanTimedState); + + // string state + StringSetTimedState stringTimedState = new StringSetTimedState(STATE_STRING_ID, STATE_STRING_NAME); + StringSetValue change = new StringSetValue(asSet(STATE_STRING_TIME_0)); + stringTimedState.applyChange(new ValueChange<>(STATE_TIME_0, change)); + change = change.getInverse(); + change.add(asSet(STATE_STRING_TIME_10)); + stringTimedState.applyChange(new ValueChange<>(STATE_TIME_10, change)); + removeInverted(change.getValue()); + change = change.getInverse(); + change.add(asSet(STATE_STRING_TIME_20)); + stringTimedState.applyChange(new ValueChange<>(STATE_TIME_20, change)); + removeInverted(change.getValue()); + change = change.getInverse(); + change.add(asSet(STATE_STRING_TIME_30)); + stringTimedState.applyChange(new ValueChange<>(STATE_TIME_30, change)); + resource.addTimedState(stringTimedState); + } + + private static Set asSet(String value) { + HashSet hashSet = new HashSet<>(); + hashSet.add(new AString(value)); + return hashSet; + } + + private static void removeInverted(Set set) { + for (Iterator iter = set.iterator(); iter.hasNext();) { + AString aString = iter.next(); + if (aString.isInverse()) { + iter.remove(); + } + } + } + + /** + * Creates a list of {@link Resource Resources} with the given values and adds a {@link ParameterBag} by calling + * {@link #createParameterBag(String, String, String)} + * + * @param idStart + * id range start + * @param count + * the number of elements to create + * @param idPrefix + * the prefix to generate IDs for the {@link Resource Resources} + * @param name + * the name of the {@link Resource} + * @param type + * the type of the {@link Resource} + * + * @return the list of newly created {@link Resource Resources} + */ + public static List createResources(int idStart, int count, String idPrefix, String name, String type) { + List resources = new ArrayList<>(); + for (int i = 0; i < count; i++) { + String id = StringHelper.normalizeLength(String.valueOf((i + idStart)), 8, true, '0'); + resources.add(createResource(idPrefix + id, name + " " + i, type)); + } + return resources; + } + + /** + * Creates an {@link Order} with the given values and adds a {@link ParameterBag} by calling + * {@link #createParameterBag(String, String, String)} + * + * @param id + * the id of the {@link Order} + * @param name + * the name of the {@link Order} + * @param type + * the type of the {@link Order} + * + * @return the newly created {@link Order} + */ + public static Order createOrder(String id, String name, String type) { + return createOrder(id, name, type, new Date(), State.CREATED); + } + + /** + * Creates an {@link Order} with the given values and adds a {@link ParameterBag} by calling + * {@link #createParameterBag(String, String, String)} + * + * @param id + * the id of the {@link Order} + * @param name + * the name of the {@link Order} + * @param type + * the type of the {@link Order} + * @param date + * the date of the {@link Order} + * @param state + * the {@link State} of the {@link Order} + * + * @return the newly created {@link Order} + */ + public static Order createOrder(String id, String name, String type, Date date, State state) { + + Order order = new Order(id, name, type, date, state); + ParameterBag bag = createParameterBag(BAG_ID, BAG_NAME, BAG_TYPE); + order.addParameterBag(bag); + + return order; + } + + /** + * Creates a list of {@link Order Orders} with the given values and adds a {@link ParameterBag} by calling + * {@link #createParameterBag(String, String, String)} + * + * @param idStart + * id range start + * @param count + * the number of elements to create + * @param idPrefix + * the prefix to generate IDs for the {@link Order Orders} + * @param name + * the name of the {@link Order} + * @param type + * the type of the {@link Order} + * + * @return the list of newly created {@link Order Orders} + */ + public static List createOrders(int idStart, int count, String idPrefix, String name, String type) { + List orders = new ArrayList<>(); + for (int i = 0; i < count; i++) { + String id = StringHelper.normalizeLength(String.valueOf((i + idStart)), 8, true, '0'); + orders.add(createOrder(idPrefix + id, name + " " + i, type)); + } + return orders; + } + + /** + * Creates a {@link ParameterBag} with the given values and calls {@link #addAllParameters(ParameterBag)} to add + * {@link Parameter}s + * + * @param id + * the id of the {@link ParameterBag} + * @param name + * the name of the {@link ParameterBag} + * @param type + * the type of the {@link ParameterBag} + * + * @return the newly created {@link ParameterBag} + */ + public static ParameterBag createParameterBag(String id, String name, String type) { + + ParameterBag bag = new ParameterBag(id, name, type); + addAllParameters(bag); + return bag; + } + + /** + * Adds the following {@link Parameter}s to the given {@link ParameterBag}: + *
    + *
  • BooleanParameter - true
  • + *
  • FloatParameter - 44.3
  • + *
  • IntegerParameter - 77
  • + *
  • LongParameter - 4453234566L
  • + *
  • StringParameter - "Strolch"
  • + *
  • DateParameter - 1354295525628L
  • + *
  • StringListParameter - Hello, World
  • + *
+ * + * @param bag + */ + public static void addAllParameters(ParameterBag bag) { + + BooleanParameter boolParam = new BooleanParameter(PARAM_BOOLEAN_ID, PARAM_BOOLEAN_NAME, true); + boolParam.setIndex(1); + bag.addParameter(boolParam); + + FloatParameter floatParam = new FloatParameter(PARAM_FLOAT_ID, PARAM_FLOAT_NAME, 44.3); + floatParam.setIndex(2); + bag.addParameter(floatParam); + + IntegerParameter integerParam = new IntegerParameter(PARAM_INTEGER_ID, PARAM_INTEGER_NAME, 77); + integerParam.setIndex(3); + bag.addParameter(integerParam); + + LongParameter longParam = new LongParameter(PARAM_LONG_ID, PARAM_LONG_NAME, 4453234566L); + longParam.setIndex(4); + bag.addParameter(longParam); + + StringParameter stringParam = new StringParameter(PARAM_STRING_ID, PARAM_STRING_NAME, "Strolch"); + stringParam.setIndex(5); + bag.addParameter(stringParam); + + DateParameter dateParam = new DateParameter(PARAM_DATE_ID, PARAM_DATE_NAME, new Date(1354295525628L)); + dateParam.setIndex(6); + bag.addParameter(dateParam); + + ArrayList stringList = new ArrayList(); + stringList.add("Hello"); + stringList.add("World"); + StringListParameter stringListP = new StringListParameter(PARAM_LIST_STRING_ID, PARAM_LIST_STRING_NAME, + stringList); + stringListP.setIndex(7); + bag.addParameter(stringListP); + } + + private static String randomValue(Random rand, String[] values) { + return values[rand.nextInt(values.length)]; + } + + public static Audit randomAudit() { + + Random rand = new Random(234234L); + String[] usernames = new String[] { "bob", "alice", "jenny" }; + String[] firstnames = new String[] { "Bob", "Alice", "Jenny" }; + String[] lastnames = new String[] { "Richards", "Kennedy", "Davids" }; + String[] types = new String[] { Tags.RESOURCE, Tags.ORDER, Tags.AUDIT }; + String[] actions = new String[] { "AddResourceService", "UpdateResourceService", "RemoveResourceService", + "AddOrderService", "UpdateOrderService", "RemoveOrderService" }; + + Audit audit = new Audit(); + audit.setId(StringHelper.getUniqueIdLong()); + audit.setUsername(randomValue(rand, usernames)); + audit.setFirstname(randomValue(rand, firstnames)); + audit.setLastname(randomValue(rand, lastnames)); + audit.setDate(new Date(rand.nextInt(5000))); + audit.setElementType(randomValue(rand, types)); + audit.setElementAccessed(StringHelper.getUniqueId()); + audit.setNewVersion(new Date(rand.nextInt(5000))); + audit.setAction(randomValue(rand, actions)); + audit.setAccessType(AccessType.values()[rand.nextInt(AccessType.values().length)]); + + return audit; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/ModelStatistics.java b/li.strolch.model/src/main/java/li/strolch/model/ModelStatistics.java new file mode 100644 index 000000000..32315e47e --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/ModelStatistics.java @@ -0,0 +1,49 @@ +package li.strolch.model; + +import static ch.eitchnet.utils.helper.StringHelper.NULL; + +import java.util.Date; + +import ch.eitchnet.utils.helper.StringHelper; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +public class ModelStatistics { + + public Date startTime; + public long durationNanos; + public long nrOfResources; + public long nrOfOrders; + + /** + * @return the nrOfOrders + */ + public long getNrOfOrders() { + return this.nrOfOrders; + } + + /** + * @return the nrOfResources + */ + public long getNrOfResources() { + return this.nrOfResources; + } + + public long getNrOfElements() { + return this.nrOfOrders + this.nrOfResources; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName() + " [startTime="); + builder.append(this.startTime == null ? NULL : ISO8601FormatFactory.getInstance().formatDate(this.startTime)); + builder.append(", durationNanos="); + builder.append(StringHelper.formatNanoDuration(this.durationNanos)); + builder.append(", nrOfResources="); + builder.append(this.nrOfResources); + builder.append(", nrOfOrders="); + builder.append(this.nrOfOrders); + builder.append("]"); + return builder.toString(); + } +} \ No newline at end of file diff --git a/li.strolch.model/src/main/java/li/strolch/model/Order.java b/li.strolch.model/src/main/java/li/strolch/model/Order.java new file mode 100644 index 000000000..3b8fb11eb --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/Order.java @@ -0,0 +1,208 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.util.Date; + +import li.strolch.model.Locator.LocatorBuilder; +import li.strolch.model.visitor.StrolchRootElementVisitor; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * The Order is an object used in the EDF to transfer data from one range to another. Orders are not to be thought of as + * Resources. Resources are supposed to be thought of as things i.e. a table, a machine and so forth, where a order is + * to be thought of as an object for doing something. + * + * In this sense, orders do not need to be verified, so all verifier chracteristics are disabled and the + * getVerifier()-method will return the null reference + * + * @author Robert von Burg + */ +public class Order extends GroupedParameterizedElement implements StrolchRootElement { + + private static final long serialVersionUID = 0L; + + private Date date; + private State state; + + /** + * Empty constructor + */ + public Order() { + // + } + + /** + * Default Constructor + * + * @param id + * @param name + * @param type + */ + public Order(String id, String name, String type) { + super(id, name, type); + + setState(State.CREATED); + setDate(new Date()); + } + + /** + * Extended Constructor for date and {@link State} + * + * @param id + * @param name + * @param type + * @param date + * @param state + */ + public Order(String id, String name, String type, Date date, State state) { + super(id, name, type); + + setState(state); + setDate(date); + } + + /** + * DOM Constructor + * + * @param element + */ + public Order(Element element) { + super.fromDom(element); + + String date = element.getAttribute(Tags.DATE); + String state = element.getAttribute(Tags.STATE); + + if (StringHelper.isEmpty(date)) { + setDate(ISO8601FormatFactory.getInstance().getDateFormat().parse("-")); //$NON-NLS-1$ + } else { + setDate(ISO8601FormatFactory.getInstance().getDateFormat().parse(date)); + } + + if (state == null || state.isEmpty()) { + setState(State.CREATED); + } else { + setState(State.valueOf(state)); + } + } + + /** + * @return the date + */ + public Date getDate() { + return this.date; + } + + /** + * @param date + * the date to set + */ + public void setDate(Date date) { + this.date = date; + } + + /** + * @return the state + */ + public State getState() { + return this.state; + } + + /** + * @param state + * the state to set + */ + public void setState(State state) { + this.state = state; + } + + @Override + public Element toDom(Document doc) { + + Element orderElement = doc.createElement(Tags.ORDER); + fillElement(orderElement); + + orderElement.setAttribute(Tags.DATE, ISO8601FormatFactory.getInstance().formatDate(this.date)); + orderElement.setAttribute(Tags.STATE, this.state.toString()); + + return orderElement; + } + + @Override + public Order getClone() { + Order clone = new Order(); + + super.fillClone(clone); + + clone.setDate(this.date); + clone.setState(this.state); + + return clone; + } + + @Override + protected void fillLocator(LocatorBuilder lb) { + lb.append(Tags.ORDER).append(getType()).append(getId()); + } + + @Override + public Locator getLocator() { + LocatorBuilder lb = new LocatorBuilder(); + fillLocator(lb); + return lb.build(); + } + + @Override + public StrolchElement getParent() { + return null; + } + + @Override + public Order getRootElement() { + return this; + } + + @Override + public T accept(StrolchRootElementVisitor visitor) { + return visitor.visitOrder(this); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + + StringBuilder builder = new StringBuilder(); + + builder.append("Order [id="); + builder.append(this.id); + builder.append(", name="); + builder.append(this.name); + builder.append(", type="); + builder.append(this.type); + builder.append(", state="); + builder.append(this.state); + builder.append(", date="); + builder.append(ISO8601FormatFactory.getInstance().formatDate(this.date)); + builder.append("]"); + + return builder.toString(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/OrderVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/OrderVisitor.java new file mode 100644 index 000000000..efcaf0684 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/OrderVisitor.java @@ -0,0 +1,27 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import li.strolch.model.visitor.StrolchElementVisitor; + +/** + * @author Robert von Burg + */ +public interface OrderVisitor extends StrolchElementVisitor { + + @Override + public U visit(Order element); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/ParameterBag.java b/li.strolch.model/src/main/java/li/strolch/model/ParameterBag.java new file mode 100644 index 000000000..2baff9fda --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/ParameterBag.java @@ -0,0 +1,80 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import li.strolch.model.Locator.LocatorBuilder; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * @author Robert von Burg + */ +public class ParameterBag extends ParameterizedElement { + + private static final long serialVersionUID = 1L; + + /** + * Empty Constructor + */ + public ParameterBag() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + * @param type + */ + public ParameterBag(String id, String name, String type) { + super(id, name, type); + } + + /** + * DOM Constructor + * + * @param bagElement + */ + public ParameterBag(Element bagElement) { + super.fromDom(bagElement); + } + + @Override + public ParameterBag getClone() { + ParameterBag clone = new ParameterBag(); + super.fillClone(clone); + 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) { + + Element element = doc.createElement(Tags.PARAMETER_BAG); + + fillElement(element); + + return element; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/ParameterizedElement.java b/li.strolch.model/src/main/java/li/strolch/model/ParameterizedElement.java new file mode 100644 index 000000000..ac6270fbe --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/ParameterizedElement.java @@ -0,0 +1,308 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +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.parameter.BooleanParameter; +import li.strolch.model.parameter.DateParameter; +import li.strolch.model.parameter.FloatParameter; +import li.strolch.model.parameter.IntegerParameter; +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 org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import ch.eitchnet.utils.dbc.DBC; +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + */ +public abstract class ParameterizedElement extends AbstractStrolchElement { + + private static final long serialVersionUID = 0L; + + protected GroupedParameterizedElement parent; + protected Map> parameterMap; + protected String type; + + /** + * Empty Constructor + */ + protected ParameterizedElement() { + // + } + + /** + * Default Constructor + * + * @param id + * @param name + * @param type + */ + public ParameterizedElement(String id, String name, String type) { + setId(id); + setName(name); + setType(type); + } + + @Override + public String getType() { + return this.type; + } + + /** + * Sets the type of this {@link ParameterizedElement} + * + * @param type + * the type to set + */ + public void setType(String type) { + if (StringHelper.isEmpty(type)) { + String msg = "Type may not be empty on element {0}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, getLocator()); + throw new StrolchException(msg); + } + + this.type = type; + } + + /** + * Returns the {@link Parameter} with the given id, or null if it does not exist + * + * @param key + * the id of the parameter to return + * + * @return the {@link Parameter} with the given id, or null if it does not exist + */ + @SuppressWarnings("unchecked") + public T getParameter(String key) { + if (this.parameterMap == null) { + return null; + } + return (T) this.parameterMap.get(key); + } + + /** + * Adds the given {@link Parameter} to the {@link ParameterizedElement} + * + * @param parameter + * the {@link Parameter} to add + */ + public void addParameter(Parameter parameter) { + if (this.parameterMap == null) { + this.parameterMap = new HashMap>(); + } + + if (this.parameterMap.containsKey(parameter.getId())) { + String msg = "A Parameter already exists with id {0} on {1}"; + throw new StrolchException(MessageFormat.format(msg, parameter.getId(), getLocator())); + } + this.parameterMap.put(parameter.getId(), parameter); + parameter.setParent(this); + } + + /** + * Removes the {@link Parameter} with the given key + * + * @param key + * the key of the {@link Parameter} to remove + * + * @return the removed {@link Parameter}, or null if it does not exist + */ + @SuppressWarnings("unchecked") + public Parameter removeParameter(String key) { + if (this.parameterMap == null) { + return null; + } + return (Parameter) this.parameterMap.remove(key); + } + + /** + * Returns a list of all the {@link Parameter}s in this {@link ParameterizedElement} + * + * @return a list of all the {@link Parameter}s in this {@link ParameterizedElement} + */ + public List> getParameters() { + if (this.parameterMap == null) { + return Collections.emptyList(); + } + return new ArrayList>(this.parameterMap.values()); + } + + /** + * Returns true, if the this {@link ParameterizedElement} has any {@link Parameter Parameters}, false otherwise + * + * @return true, if the this {@link ParameterizedElement} has any {@link Parameter Parameters}, false otherwise + */ + public boolean hasParameters() { + return this.parameterMap != null && !this.parameterMap.isEmpty(); + } + + /** + * Returns true, if the {@link Parameter} exists with the given key, false otherwise + * + * @param key + * the key of the {@link Parameter} to check for + * + * @return true, if the {@link Parameter} exists with the given key, false otherwise + */ + public boolean hasParameter(String key) { + if (this.parameterMap == null) { + return false; + } + return this.parameterMap.containsKey(key); + } + + /** + * Returns a {@link Set} of all the {@link Parameter} keys in this {@link ParameterizedElement} + * + * @return a {@link Set} of all the {@link Parameter} keys in this {@link ParameterizedElement} + */ + public Set getParameterKeySet() { + if (this.parameterMap == null) { + return Collections.emptySet(); + } + return new HashSet(this.parameterMap.keySet()); + } + + @Override + public abstract void fillLocator(LocatorBuilder lb); + + @Override + public Locator getLocator() { + LocatorBuilder lb = new LocatorBuilder(); + fillLocator(lb); + return lb.build(); + } + + @Override + protected void fromDom(Element element) { + super.fromDom(element); + + String type = element.getAttribute(Tags.TYPE); + setType(type); + + // add all the parameters + NodeList parameterElements = element.getElementsByTagName(Tags.PARAMETER); + for (int i = 0; i < parameterElements.getLength(); i++) { + Element paramElement = (Element) parameterElements.item(i); + String paramtype = paramElement.getAttribute(Tags.TYPE); + + DBC.PRE.assertNotEmpty("Type must be set on Parameter for bag with id " + this.id, paramtype); + + if (paramtype.equals(StringParameter.TYPE)) { + StringParameter param = new StringParameter(paramElement); + addParameter(param); + } else if (paramtype.equals(IntegerParameter.TYPE)) { + IntegerParameter param = new IntegerParameter(paramElement); + addParameter(param); + } else if (paramtype.equals(FloatParameter.TYPE)) { + FloatParameter param = new FloatParameter(paramElement); + addParameter(param); + } else if (paramtype.equals(LongParameter.TYPE)) { + LongParameter param = new LongParameter(paramElement); + addParameter(param); + } else if (paramtype.equals(DateParameter.TYPE)) { + DateParameter param = new DateParameter(paramElement); + addParameter(param); + } else if (paramtype.equals(BooleanParameter.TYPE)) { + BooleanParameter param = new BooleanParameter(paramElement); + addParameter(param); + } else if (paramtype.equals(StringListParameter.TYPE)) { + StringListParameter param = new StringListParameter(paramElement); + addParameter(param); + } else { + String msg = "What kind of parameter is this: {0}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, paramtype); + throw new StrolchException(msg); + } + } + } + + @Override + protected void fillElement(Element element) { + super.fillElement(element); + + if (this.parameterMap != null) { + for (Parameter parameter : this.parameterMap.values()) { + element.appendChild(parameter.toDom(element.getOwnerDocument())); + } + } + } + + @Override + protected void fillClone(StrolchElement clone) { + super.fillClone(clone); + ParameterizedElement peClone = (ParameterizedElement) clone; + peClone.setType(this.type); + if (this.parameterMap != null) { + for (Parameter param : this.parameterMap.values()) { + peClone.addParameter(param.getClone()); + } + } + } + + @Override + public GroupedParameterizedElement getParent() { + return this.parent; + } + + /** + * Set the parent for this {@link ParameterizedElement} + * + * @param parent + * the parent to set + */ + public void setParent(GroupedParameterizedElement parent) { + this.parent = parent; + } + + @Override + public StrolchRootElement getRootElement() { + return this.parent.getRootElement(); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + + StringBuilder builder = new StringBuilder(); + + builder.append("ParameterizedElement [id="); + builder.append(this.id); + builder.append(", name="); + builder.append(this.name); + builder.append(", type="); + builder.append(this.type); + builder.append("]"); + + return builder.toString(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/Resource.java b/li.strolch.model/src/main/java/li/strolch/model/Resource.java new file mode 100644 index 000000000..1a535a4b6 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/Resource.java @@ -0,0 +1,221 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +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; +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 + */ +public class Resource extends GroupedParameterizedElement implements StrolchRootElement { + + private static final long serialVersionUID = 0L; + + private Map>> timedStateMap; + + /** + * Empty constructor + */ + public Resource() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + * @param type + */ + public Resource(String id, String name, String type) { + super(id, name, type); + } + + /** + * DOM Constructor + * + * @param element + */ + public Resource(Element element) { + super.fromDom(element); + + NodeList timedStateElems = element.getElementsByTagName(Tags.TIMED_STATE); + for (int i = 0; i < timedStateElems.getLength(); i++) { + Element timedStateElem = (Element) timedStateElems.item(i); + String typeS = timedStateElem.getAttribute(Tags.TYPE); + + DBC.PRE.assertNotEmpty("Type must be set on TimedState for resource with id " + this.id, typeS); + + if (typeS.equals(FloatTimedState.TYPE)) { + FloatTimedState timedState = new FloatTimedState(timedStateElem); + addTimedState(timedState); + } else if (typeS.equals(IntegerTimedState.TYPE)) { + IntegerTimedState timedState = new IntegerTimedState(timedStateElem); + addTimedState(timedState); + } else if (typeS.equals(BooleanTimedState.TYPE)) { + BooleanTimedState timedState = new BooleanTimedState(timedStateElem); + addTimedState(timedState); + } else if (typeS.equals(StringSetTimedState.TYPE)) { + StringSetTimedState timedState = new StringSetTimedState(timedStateElem); + addTimedState(timedState); + } else { + String msg = "What kind of TimedState is this: {0}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, typeS); + throw new StrolchException(msg); + } + } + } + + @SuppressWarnings("unchecked") + public void addTimedState(StrolchTimedState strolchTimedState) { + if (this.timedStateMap == null) { + this.timedStateMap = new HashMap<>(); + } + + this.timedStateMap.put(strolchTimedState.getId(), (StrolchTimedState>) strolchTimedState); + strolchTimedState.setParent(this); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public T getTimedState(String id) { + if (this.timedStateMap == null) { + return null; + } + return (T) this.timedStateMap.get(id); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public T removeTimedState(String id) { + if (this.timedStateMap == null) { + return null; + } + return (T) this.timedStateMap.remove(id); + } + + public Set getTimedStateKeySet() { + if (this.timedStateMap == null) { + return Collections.emptySet(); + } + return new HashSet<>(this.timedStateMap.keySet()); + } + + public List>> getTimedStates() { + if (this.timedStateMap == null) { + return Collections.emptyList(); + } + return new ArrayList<>(this.timedStateMap.values()); + } + + public boolean hasTimedStates() { + return this.timedStateMap != null && !this.timedStateMap.isEmpty(); + } + + public boolean hasTimedState(String id) { + return this.timedStateMap != null && this.timedStateMap.containsKey(id); + } + + @Override + public Element toDom(Document doc) { + + Element element = doc.createElement(Tags.RESOURCE); + fillElement(element); + + if (this.timedStateMap != null) { + for (StrolchTimedState state : this.timedStateMap.values()) { + Element timedStateElem = state.toDom(element.getOwnerDocument()); + element.appendChild(timedStateElem); + } + } + + return element; + } + + @Override + public Resource getClone() { + Resource clone = new Resource(); + + super.fillClone(clone); + + return clone; + } + + @Override + public void fillLocator(LocatorBuilder lb) { + lb.append(Tags.RESOURCE).append(getType()).append(getId()); + } + + @Override + public Locator getLocator() { + LocatorBuilder lb = new LocatorBuilder(); + fillLocator(lb); + return lb.build(); + } + + @Override + public StrolchElement getParent() { + return null; + } + + @Override + public Resource getRootElement() { + return this; + } + + @Override + public T accept(StrolchRootElementVisitor visitor) { + return visitor.visitResource(this); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + + StringBuilder builder = new StringBuilder(); + + builder.append("Resource [id="); + builder.append(this.id); + builder.append(", name="); + builder.append(this.name); + builder.append(", type="); + builder.append(this.type); + builder.append("]"); + + return builder.toString(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/ResourceVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/ResourceVisitor.java new file mode 100644 index 000000000..67c014fc1 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/ResourceVisitor.java @@ -0,0 +1,28 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import li.strolch.model.visitor.StrolchElementVisitor; + +/** + * @author Robert von Burg + * @param + */ +public interface ResourceVisitor extends StrolchElementVisitor { + + @Override + public U visit(Resource element); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/State.java b/li.strolch.model/src/main/java/li/strolch/model/State.java new file mode 100644 index 000000000..9bf386425 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/State.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +/** + * @author Robert von Burg + */ +public enum State { + + CREATED("Created"), //$NON-NLS-1$ + OPEN("Open"), //$NON-NLS-1$ + EXECUTION("Execution"), //$NON-NLS-1$ + CLOSED("Closed"); //$NON-NLS-1$ + + private String state; + + /** + * @param state + */ + private State(String state) { + this.state = state; + } + + /** + * @return + */ + public String getStateName() { + return this.state; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/StrolchElement.java b/li.strolch.model/src/main/java/li/strolch/model/StrolchElement.java new file mode 100644 index 000000000..1fb148ffc --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/StrolchElement.java @@ -0,0 +1,116 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import java.io.Serializable; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * @author Robert von Burg + */ +public interface StrolchElement extends Serializable, Comparable { + + /** + * Return the {@link Locator} for this element + * + * @return the {@link Locator} for this element + */ + public Locator getLocator(); + + /** + * Set the semi unique id of this {@link StrolchElement}. This value should be unique under all concrete + * implementations of this interface + * + * @param id + */ + public void setId(String id); + + /** + * Returns the semi unique id of this {@link StrolchElement}. This value should be unique under all concrete + * implementations of this interface + * + * @return + */ + public String getId(); + + /** + * Set the name of this {@link StrolchElement} + * + * @param name + */ + public void setName(String name); + + /** + * Returns the name of this {@link StrolchElement} + * + * @return + */ + public String getName(); + + /** + * Set the currently set long value which defines the primary key for use in RDBM-Systems + * + * @param dbid + */ + public void setDbid(long dbid); + + /** + * Returns the currently set long value which defines the primary key for use in RDBM-Systems + * + * @return + */ + public long getDbid(); + + /** + * Returns an {@link Element} object which is an XML representation of this object + * + * @param doc + * the document to which this element is being written. The client must not append to the document, the + * caller will perform this as needed + * + * @return + */ + public Element toDom(Document doc); + + /** + * Returns the type of this {@link StrolchElement} + * + * @return + */ + public String getType(); + + public StrolchElement getParent(); + + public StrolchRootElement getRootElement(); + + /** + * Return a clone of this {@link StrolchElement} + * + * @return + */ + public StrolchElement getClone(); + + @Override + public int hashCode(); + + @Override + public boolean equals(Object obj); + + @Override + public int compareTo(StrolchElement o); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/StrolchModelConstants.java b/li.strolch.model/src/main/java/li/strolch/model/StrolchModelConstants.java new file mode 100644 index 000000000..5b9caedf2 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/StrolchModelConstants.java @@ -0,0 +1,33 @@ +package li.strolch.model; + +import li.strolch.model.parameter.Parameter; + +public class StrolchModelConstants { + + /** + * The type to set on {@link StrolchRootElement StrolchRootElements} when defining a template for a type of element + */ + public static final String TEMPLATE = "Template"; //$NON-NLS-1$ + + /** + * This interpretation value indicates that the value of the {@link Parameter} should be understood as a reference + * to a {@link Resource} + */ + public static final String INTERPRETATION_RESOURCE_REF = "Resource-Ref"; //$NON-NLS-1$ + + /** + * This interpretation value indicates that the value of the {@link Parameter} should be understood as a reference + * 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/li.strolch.model/src/main/java/li/strolch/model/StrolchRootElement.java b/li.strolch.model/src/main/java/li/strolch/model/StrolchRootElement.java new file mode 100644 index 000000000..7b99b045d --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/StrolchRootElement.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import li.strolch.model.visitor.StrolchRootElementVisitor; + +/** + * Root element for all top level {@link StrolchElement}. These are elements which have no parent, e.g. {@link Resource + * Resources} and {@link Order Orders} + * + * @author Robert von Burg + */ +public interface StrolchRootElement extends StrolchElement { + + public T accept(StrolchRootElementVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/Tags.java b/li.strolch.model/src/main/java/li/strolch/model/Tags.java new file mode 100644 index 000000000..b4fb9d22c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/Tags.java @@ -0,0 +1,60 @@ +/* + * 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; + +@SuppressWarnings("nls") +public class Tags { + + public static final String CDATA = "CDATA"; + public static final String ID = "Id"; + public static final String NAME = "Name"; + public static final String TYPE = "Type"; + public static final String DATE = "Date"; + public static final String STATE = "State"; + public static final String VALUE = "Value"; + public static final String TIME = "Time"; + public static final String INTERPRETATION = "Interpretation"; + public static final String UOM = "Uom"; + public static final String HIDDEN = "Hidden"; + public static final String INDEX = "Index"; + public static final String PARAMETER = "Parameter"; + public static final String TIMED_STATE = "TimedState"; + public static final String PARAMETERIZED_ELEMENT = "ParameterizedElement"; + public static final String RESOURCE = "Resource"; + public static final String ORDER = "Order"; + public static final String PARAMETER_BAG = "ParameterBag"; + public static final String STROLCH_MODEL = "StrolchModel"; + public static final String INCLUDE_FILE = "IncludeFile"; + public static final String FILE = "file"; + public static final String BAG = "Bag"; + public static final String AUDIT = "Audit"; + + public class Audit { + public static final String ID = Tags.ID; + + public static final String USERNAME = "Username"; + public static final String FIRSTNAME = "Firstname"; + public static final String LASTNAME = "Lastname"; + public static final String DATE = "Date"; + + public static final String ELEMENT_TYPE = "ElementType"; + public static final String ELEMENT_ACCESSED = "ElementAccessed"; + public static final String NEW_VERSION = "NewVersion"; + + public static final String ACTION = "Action"; + public static final String ACCESS_TYPE = "AccessType"; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AccessType.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AccessType.java new file mode 100644 index 000000000..9c26d7846 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AccessType.java @@ -0,0 +1,27 @@ +/* + * 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.audit; + +import li.strolch.model.StrolchRootElement; + +/** + * Defines the type of access performed on a {@link StrolchRootElement} + * + * @author Robert von Burg + */ +public enum AccessType { + READ, CREATE, UPDATE, DELETE; +} \ No newline at end of file diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/ActionSelection.java b/li.strolch.model/src/main/java/li/strolch/model/audit/ActionSelection.java new file mode 100644 index 000000000..6a85a9627 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/ActionSelection.java @@ -0,0 +1,63 @@ +/* + * 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.audit; + +import li.strolch.model.query.StringSelection; +import ch.eitchnet.utils.StringMatchMode; + +/** + * @author Robert von Burg + */ +public class ActionSelection extends AuditSelection { + + private StringSelection actionSelection; + private AccessType[] accessTypes; + + public ActionSelection(AuditQuery query) { + super(query); + } + + public ActionSelection actions(StringMatchMode matchMode, String... actions) { + this.actionSelection = new StringSelection(matchMode, actions); + return this; + } + + public ActionSelection accessTypes(AccessType... accessTypes) { + this.accessTypes = accessTypes; + return this; + } + + public AccessType[] getAccessTypes() { + return this.accessTypes; + } + + public StringSelection getActionSelection() { + return this.actionSelection; + } + + public boolean isWildcardActionType() { + return this.accessTypes == null || this.accessTypes.length == 0; + } + + public boolean isWildcardAction() { + return this.actionSelection == null || this.actionSelection.isWildCard(); + } + + @Override + public void accept(AuditQueryVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/Audit.java b/li.strolch.model/src/main/java/li/strolch/model/audit/Audit.java new file mode 100644 index 000000000..d07111fb4 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/Audit.java @@ -0,0 +1,233 @@ +/* + * 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.audit; + +import java.io.Serializable; +import java.util.Date; + +import li.strolch.model.StrolchRootElement; + +/** + * Used to log/audit access to {@link StrolchRootElement} + * + * @author Robert von Burg + */ +public class Audit implements Comparable, Serializable { + + private static final long serialVersionUID = 1L; + + private Long id; + private String username; + private String firstname; + private String lastname; + private Date date; + + private String elementType; + private String elementAccessed; + private Date newVersion; + + private String action; + private AccessType accessType; + + /** + * @return the id + */ + public Long getId() { + return this.id; + } + + /** + * @param id + * the id to set + */ + public void setId(long id) { + this.id = id; + } + + /** + * @return the username + */ + public String getUsername() { + return this.username; + } + + /** + * @param username + * the username to set + */ + public void setUsername(String username) { + this.username = username; + } + + /** + * @return the firstname + */ + public String getFirstname() { + return this.firstname; + } + + /** + * @param firstname + * the firstname to set + */ + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + /** + * @return the lastname + */ + public String getLastname() { + return this.lastname; + } + + /** + * @param lastname + * the lastname to set + */ + public void setLastname(String lastname) { + this.lastname = lastname; + } + + /** + * @return the date + */ + public Date getDate() { + return this.date; + } + + /** + * @param date + * the date to set + */ + public void setDate(Date date) { + this.date = date; + } + + /** + * @return the elementType + */ + public String getElementType() { + return this.elementType; + } + + /** + * @param elementType + * the elementType to set + */ + public void setElementType(String elementType) { + this.elementType = elementType; + } + + /** + * @return the elementAccessed + */ + public String getElementAccessed() { + return this.elementAccessed; + } + + /** + * @param elementAccessed + * the elementAccessed to set + */ + public void setElementAccessed(String elementAccessed) { + this.elementAccessed = elementAccessed; + } + + /** + * @return the newVersion + */ + public Date getNewVersion() { + return this.newVersion; + } + + /** + * @param newVersion + * the newVersion to set + */ + public void setNewVersion(Date newVersion) { + this.newVersion = newVersion; + } + + /** + * @return the action + */ + public String getAction() { + return this.action; + } + + /** + * @param action + * the action to set + */ + public void setAction(String action) { + this.action = action; + } + + /** + * @return the accessType + */ + public AccessType getAccessType() { + return this.accessType; + } + + /** + * @param accessType + * the accessType to set + */ + public void setAccessType(AccessType accessType) { + this.accessType = accessType; + } + + public U accept(AuditVisitor visitor) { + return visitor.visitAudit(this); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Audit other = (Audit) obj; + if (this.id == null) { + if (other.id != null) { + return false; + } + } else if (!this.id.equals(other.id)) { + return false; + } + return true; + } + + @Override + public int compareTo(Audit o) { + return getId().compareTo(o.getId()); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditFromDomReader.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditFromDomReader.java new file mode 100644 index 000000000..123d5903c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditFromDomReader.java @@ -0,0 +1,100 @@ +/* + * 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.audit; + +import java.text.MessageFormat; + +import li.strolch.model.Tags; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import ch.eitchnet.utils.dbc.DBC; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +public class AuditFromDomReader { + + public Audit from(Element rootElement) { + + Audit audit = new Audit(); + + String idS = rootElement.getAttribute(Tags.Audit.ID); + DBC.INTERIM.assertNotEmpty("Id must be set!", idS); + audit.setId(Long.valueOf(idS)); + + NodeList childNodes = rootElement.getChildNodes(); + for (int i = 0; i < childNodes.getLength(); i++) { + Node item = childNodes.item(i); + if (!(item instanceof Element)) + continue; + + Element element = (Element) item; + String nodeName = element.getNodeName(); + String txtContent = element.getTextContent(); + + switch (nodeName) { + case Tags.Audit.USERNAME: + audit.setUsername(txtContent); + break; + case Tags.Audit.FIRSTNAME: + audit.setFirstname(txtContent); + break; + case Tags.Audit.LASTNAME: + audit.setLastname(txtContent); + break; + case Tags.Audit.DATE: + audit.setDate(ISO8601FormatFactory.getInstance().getXmlDateFormat().parse(txtContent)); + break; + case Tags.Audit.ELEMENT_TYPE: + audit.setElementType(txtContent); + break; + case Tags.Audit.ELEMENT_ACCESSED: + audit.setElementAccessed(txtContent); + break; + case Tags.Audit.NEW_VERSION: + audit.setNewVersion(ISO8601FormatFactory.getInstance().getXmlDateFormat().parse(txtContent)); + break; + case Tags.Audit.ACTION: + audit.setAction(txtContent); + break; + case Tags.Audit.ACCESS_TYPE: + audit.setAccessType(AccessType.valueOf(txtContent)); + break; + + default: + throw new IllegalArgumentException(MessageFormat.format("Unhandled/Invalid tag {0} for Audit {1}", + nodeName, idS)); + } + } + + String msg = " missing for element with id " + audit.getId(); + DBC.INTERIM.assertNotEmpty("Username" + msg, audit.getUsername()); + DBC.INTERIM.assertNotEmpty("Firstname" + msg, audit.getFirstname()); + DBC.INTERIM.assertNotEmpty("Lastname" + msg, audit.getLastname()); + DBC.INTERIM.assertNotNull("Date" + msg, audit.getDate()); + DBC.INTERIM.assertNotEmpty("ElementType" + msg, audit.getElementType()); + DBC.INTERIM.assertNotEmpty("ElementAccessed" + msg, audit.getElementAccessed()); + //DBC.INTERIM.assertNotNull("NewVersion" + msg, audit.getNewVersion()); + DBC.INTERIM.assertNotEmpty("Action" + msg, audit.getAction()); + DBC.INTERIM.assertNotNull("AccessType" + msg, audit.getAccessType()); + + return audit; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditQuery.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditQuery.java new file mode 100644 index 000000000..54dcf4914 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditQuery.java @@ -0,0 +1,91 @@ +/* + * 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.audit; + +import java.util.ArrayList; +import java.util.List; + +import li.strolch.model.query.StrolchQuery; +import ch.eitchnet.utils.collections.DateRange; +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +public class AuditQuery implements StrolchQuery { + + private String elementTypeSelection; + private List selections; + private DateRange dateRange; + + public AuditQuery(String elementTypeSelection, DateRange dateRange) { + DBC.PRE.assertFalse("dateRange may not be unbounded!", dateRange.isUnbounded()); + this.elementTypeSelection = elementTypeSelection; + this.dateRange = dateRange; + this.selections = new ArrayList<>(); + } + + public String getElementTypeSelection() { + return this.elementTypeSelection; + } + + public DateRange getDateRange() { + return this.dateRange; + } + + public ActionSelection action() { + ActionSelection selection = new ActionSelection(this); + this.selections.add(selection); + return selection; + } + + public ElementSelection element() { + ElementSelection selection = new ElementSelection(this); + this.selections.add(selection); + return selection; + } + + public IdentitySelection identity() { + IdentitySelection selection = new IdentitySelection(this); + this.selections.add(selection); + return selection; + } + + public void accept(AuditQueryVisitor visitor) { + DBC.PRE.assertNotNull("No elementTypeSelection (navigation) set!", this.elementTypeSelection); //$NON-NLS-1$ + DBC.PRE.assertNotNull("No dateRange set!", this.dateRange); //$NON-NLS-1$ + visitor.visit(this); + for (AuditSelection selection : this.selections) { + selection.accept(visitor); + } + } + + /** + * @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeName() + */ + @Override + public String getPrivilegeName() { + return StrolchQuery.class.getName(); + } + + /** + * @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeValue() + */ + @Override + public Object getPrivilegeValue() { + return getClass().getName(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditQueryVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditQueryVisitor.java new file mode 100644 index 000000000..03fc601de --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditQueryVisitor.java @@ -0,0 +1,30 @@ +/* + * 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.audit; + +/** + * @author Robert von Burg + */ +public interface AuditQueryVisitor { + + public void visit(ElementSelection selection); + + public void visit(IdentitySelection selection); + + public void visit(ActionSelection selection); + + public void visit(AuditQuery auditQuery); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditSaxReader.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditSaxReader.java new file mode 100644 index 000000000..5b585ed8d --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditSaxReader.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.audit; + +import org.xml.sax.helpers.DefaultHandler; + +/** + * @author Robert von Burg + */ +public class AuditSaxReader extends DefaultHandler { + +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditSelection.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditSelection.java new file mode 100644 index 000000000..f2e1cae63 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditSelection.java @@ -0,0 +1,35 @@ +/* + * 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.audit; + +/** + * @author Robert von Burg + */ +public abstract class AuditSelection { + + private AuditQuery query; + + public AuditSelection(AuditQuery query) { + super(); + this.query = query; + } + + public AuditQuery query() { + return this.query; + } + + public abstract void accept(AuditQueryVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditToDomVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditToDomVisitor.java new file mode 100644 index 000000000..f187cff84 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditToDomVisitor.java @@ -0,0 +1,66 @@ +/* + * 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.audit; + +import javax.xml.parsers.DocumentBuilder; + +import li.strolch.model.Tags; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.DomUtil; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +public class AuditToDomVisitor implements AuditVisitor { + + @Override + public Document visitAudit(Audit audit) { + DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder(); + Document doc = documentBuilder.getDOMImplementation().createDocument(null, null, null); + + Element auditE = doc.createElement(Tags.AUDIT); + auditE.setAttribute(Tags.Audit.ID, audit.getId().toString()); + + auditE.appendChild(elem(doc, Tags.Audit.USERNAME, audit.getUsername())); + + auditE.appendChild(elem(doc, Tags.Audit.FIRSTNAME, audit.getUsername())); + auditE.appendChild(elem(doc, Tags.Audit.LASTNAME, audit.getUsername())); + auditE.appendChild(elem(doc, Tags.Audit.DATE, ISO8601FormatFactory.getInstance().formatDate(audit.getDate()))); + + auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_TYPE, audit.getElementType())); + auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_ACCESSED, audit.getElementAccessed())); + + if (audit.getNewVersion() != null) + auditE.appendChild(elem(doc, Tags.Audit.NEW_VERSION, + ISO8601FormatFactory.getInstance().formatDate(audit.getNewVersion()))); + + auditE.appendChild(elem(doc, Tags.Audit.ACTION, audit.getAction())); + auditE.appendChild(elem(doc, Tags.Audit.ACCESS_TYPE, audit.getAccessType().name())); + + doc.appendChild(auditE); + return doc; + } + + private Element elem(Document doc, String tag, String txtValue) { + Element element = doc.createElement(tag); + element.setTextContent(txtValue); + return element; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditVisitor.java new file mode 100644 index 000000000..002e4d922 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditVisitor.java @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.audit; + +/** + * @author Robert von Burg + */ +public interface AuditVisitor { + + public U visitAudit(Audit audit); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/ElementSelection.java b/li.strolch.model/src/main/java/li/strolch/model/audit/ElementSelection.java new file mode 100644 index 000000000..74b78975b --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/ElementSelection.java @@ -0,0 +1,49 @@ +/* + * 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.audit; + +import li.strolch.model.query.StringSelection; +import ch.eitchnet.utils.StringMatchMode; + +/** + * @author Robert von Burg + */ +public class ElementSelection extends AuditSelection { + + private StringSelection elementAccessedSelection; + + public ElementSelection(AuditQuery query) { + super(query); + } + + public ElementSelection elementsAccessed(StringMatchMode matchMode, String... elementsAccessed) { + this.elementAccessedSelection = new StringSelection(matchMode, elementsAccessed); + return this; + } + + public StringSelection getElementAccessedSelection() { + return this.elementAccessedSelection; + } + + public boolean isElementsAccessedWildcard() { + return this.elementAccessedSelection == null || this.elementAccessedSelection.isWildCard(); + } + + @Override + public void accept(AuditQueryVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/IdentitySelection.java b/li.strolch.model/src/main/java/li/strolch/model/audit/IdentitySelection.java new file mode 100644 index 000000000..899442ff6 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/IdentitySelection.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.audit; + +import li.strolch.model.query.StringSelection; +import ch.eitchnet.utils.StringMatchMode; + +/** + * @author Robert von Burg + */ +public class IdentitySelection extends AuditSelection { + + private StringSelection usernameSelection; + private StringSelection firstnameSelection; + private StringSelection lastnameSelection; + + public IdentitySelection(AuditQuery query) { + super(query); + } + + public IdentitySelection usernames(StringMatchMode matchMode, String... usernames) { + this.usernameSelection = new StringSelection(matchMode, usernames); + return this; + } + + public IdentitySelection firstnames(StringMatchMode matchMode, String... firstnames) { + this.firstnameSelection = new StringSelection(matchMode, firstnames); + return this; + } + + public IdentitySelection lastnames(StringMatchMode matchMode, String... lastnames) { + this.lastnameSelection = new StringSelection(matchMode, lastnames); + return this; + } + + /** + * @return the firstnameSelection + */ + public StringSelection getFirstnameSelection() { + return this.firstnameSelection; + } + + /** + * @return the lastnameSelection + */ + public StringSelection getLastnameSelection() { + return this.lastnameSelection; + } + + /** + * @return the usernameSelection + */ + public StringSelection getUsernameSelection() { + return this.usernameSelection; + } + + public boolean isFirstnameWildcard() { + return this.firstnameSelection == null || this.firstnameSelection.isWildCard(); + } + + public boolean isLastnameWildcard() { + return this.lastnameSelection == null || this.lastnameSelection.isWildCard(); + } + + public boolean isUsernameWildcard() { + return this.usernameSelection == null || this.usernameSelection.isWildCard(); + } + + public boolean isWildcard() { + return isFirstnameWildcard() && isLastnameWildcard() && isUsernameWildcard(); + } + + @Override + public void accept(AuditQueryVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/NoStrategyAuditVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/audit/NoStrategyAuditVisitor.java new file mode 100644 index 000000000..5cede2cdb --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/NoStrategyAuditVisitor.java @@ -0,0 +1,27 @@ +/* + * 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.audit; + +/** + * @author Robert von Burg + */ +public class NoStrategyAuditVisitor implements AuditVisitor { + + @Override + public Audit visitAudit(Audit audit) { + return audit; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/AbstractParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/AbstractParameter.java new file mode 100644 index 000000000..18296b782 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/AbstractParameter.java @@ -0,0 +1,267 @@ +/* + * 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.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; +import li.strolch.model.AbstractStrolchElement; +import li.strolch.model.Locator; +import li.strolch.model.Locator.LocatorBuilder; +import li.strolch.model.ParameterizedElement; +import li.strolch.model.StrolchRootElement; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + * @param + */ +public abstract class AbstractParameter extends AbstractStrolchElement implements Parameter { + + private static final long serialVersionUID = 0L; + + protected boolean hidden = false; + protected int index; + protected String interpretation = INTERPRETATION_NONE; + protected String uom = UOM_NONE; + + protected ParameterizedElement parent; + + /** + * Empty constructor + */ + protected AbstractParameter() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + */ + public AbstractParameter(String id, String name) { + super(id, name); + } + + @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 ParameterizedElement getParent() { + return this.parent; + } + + @Override + public void setParent(ParameterizedElement parent) { + this.parent = parent; + } + + @Override + public StrolchRootElement getRootElement() { + return this.parent.getRootElement(); + } + + @Override + public Element toDom(Document doc) { + Element element = doc.createElement(Tags.PARAMETER); + fillElement(element); + + element.setAttribute(Tags.VALUE, getValueAsString()); + + 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(this.id); + } + + @Override + public Locator getLocator() { + LocatorBuilder lb = new LocatorBuilder(); + this.parent.fillLocator(lb); + fillLocator(lb); + return lb.build(); + } + + /** + * 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 + * + * @throws StrolchException + * if the value is null + */ + protected void validateValue(T value) throws StrolchException { + if (value == null) { + String msg = "{0} Parameter {1} may not have a null value!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, getType(), getId()); + throw new StrolchException(msg); + } + } + + /** + * Fills the {@link Parameter} clone with the id, name, hidden, interpretation and uom + * + * @param clone + */ + protected void fillClone(Parameter clone) { + super.fillClone(clone); + + clone.setHidden(this.hidden); + clone.setInterpretation(this.interpretation); + clone.setUom(this.uom); + clone.setIndex(this.index); + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitParam(this); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + + StringBuilder builder = new StringBuilder(); + + builder.append(getClass().getSimpleName()); + builder.append(" [id="); + builder.append(this.id); + builder.append(", name="); + builder.append(this.name); + builder.append(", value="); + builder.append(getValueAsString()); + builder.append("]"); + + return builder.toString(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/BooleanParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/BooleanParameter.java new file mode 100644 index 000000000..56c1aba28 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/BooleanParameter.java @@ -0,0 +1,114 @@ +/* + * 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.parameter; + +import java.text.MessageFormat; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + */ +public class BooleanParameter extends AbstractParameter { + + public static final String TYPE = "Boolean"; //$NON-NLS-1$ + private static final long serialVersionUID = 0L; + + private Boolean value = Boolean.FALSE; + + /** + * Empty constructor + */ + public BooleanParameter() { + // + } + + /** + * Default constructors + * + * @param id + * @param name + * @param value + */ + public BooleanParameter(String id, String name, Boolean value) { + super(id, name); + setValue(value); + } + + /** + * DOM Constructor + * + * @param element + */ + public BooleanParameter(Element element) { + super.fromDom(element); + + String valueS = element.getAttribute(Tags.VALUE); + if (StringHelper.isEmpty(valueS)) { + String msg = MessageFormat.format("No value defined for {0}", this.id); //$NON-NLS-1$ + throw new StrolchException(msg); + } + + setValue(parseFromString(valueS)); + } + + @Override + public String getValueAsString() { + return this.value.toString(); + } + + @Override + public Boolean getValue() { + return this.value; + } + + @Override + public void setValue(Boolean value) { + validateValue(value); + this.value = value; + } + + @Override + public String getType() { + return BooleanParameter.TYPE; + } + + @Override + public BooleanParameter getClone() { + BooleanParameter clone = new BooleanParameter(); + + super.fillClone(clone); + + clone.setValue(this.value); + + return clone; + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitBooleanParam(this); + } + + public static Boolean parseFromString(String valueS) { + return StringHelper.parseBoolean(valueS); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/DateParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/DateParameter.java new file mode 100644 index 000000000..ffffb8462 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/DateParameter.java @@ -0,0 +1,116 @@ +/* + * 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.parameter; + +import java.text.MessageFormat; +import java.util.Date; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +public class DateParameter extends AbstractParameter { + + public static final String TYPE = "Date"; //$NON-NLS-1$ + private static final long serialVersionUID = 0L; + + private Date value; + + /** + * Empty constructor + */ + public DateParameter() { + // + } + + /** + * Default Constructor + * + * @param id + * @param name + * @param value + */ + public DateParameter(String id, String name, Date value) { + super(id, name); + setValue(value); + } + + /** + * DOM Constructor + * + * @param element + */ + public DateParameter(Element element) { + super.fromDom(element); + + String valueS = element.getAttribute(Tags.VALUE); + if (StringHelper.isEmpty(valueS)) { + String msg = MessageFormat.format("No value defined for {0}", this.id); //$NON-NLS-1$ + throw new StrolchException(msg); + } + + setValue(parseFromString(valueS)); + } + + @Override + public String getValueAsString() { + return ISO8601FormatFactory.getInstance().formatDate(this.value); + } + + @Override + public Date getValue() { + return this.value; + } + + @Override + public void setValue(Date value) { + validateValue(value); + this.value = value; + } + + @Override + public String getType() { + return DateParameter.TYPE; + } + + @Override + public DateParameter getClone() { + DateParameter clone = new DateParameter(); + + super.fillClone(clone); + + clone.setValue(this.value); + + return clone; + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitDateParam(this); + } + + public static Date parseFromString(String valueS) { + return ISO8601FormatFactory.getInstance().getDateFormat().parse(valueS); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/FloatParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/FloatParameter.java new file mode 100644 index 000000000..565ce2738 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/FloatParameter.java @@ -0,0 +1,116 @@ +/* + * 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.parameter; + +import java.text.MessageFormat; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +public class FloatParameter extends AbstractParameter { + + public static final String TYPE = "Float"; //$NON-NLS-1$ + private static final long serialVersionUID = 0L; + + private Double value = Double.MAX_VALUE; + + /** + * Empty constructor + */ + public FloatParameter() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + * @param value + */ + public FloatParameter(String id, String name, Double value) { + super(id, name); + + setValue(value); + } + + /** + * DOM Constructor + * + * @param element + */ + public FloatParameter(Element element) { + super.fromDom(element); + + String valueS = element.getAttribute(Tags.VALUE); + if (StringHelper.isEmpty(valueS)) { + String msg = MessageFormat.format("No value defined for {0}", this.id); //$NON-NLS-1$ + throw new StrolchException(msg); + } + + setValue(parseFromString(valueS)); + } + + @Override + public String getValueAsString() { + return Double.toString(this.value); + } + + @Override + public Double getValue() { + return this.value; + } + + @Override + public void setValue(Double value) { + validateValue(value); + this.value = value; + } + + @Override + public String getType() { + return FloatParameter.TYPE; + } + + @Override + public FloatParameter getClone() { + FloatParameter clone = new FloatParameter(); + + super.fillClone(clone); + + clone.setValue(this.value); + + return clone; + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitFloatParam(this); + } + + public static Double parseFromString(String valueS) { + return Double.valueOf(valueS); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/IntegerParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/IntegerParameter.java new file mode 100644 index 000000000..cf29997d4 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/IntegerParameter.java @@ -0,0 +1,115 @@ +/* + * 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.parameter; + +import java.text.MessageFormat; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +public class IntegerParameter extends AbstractParameter { + + public static final String TYPE = "Integer"; //$NON-NLS-1$ + private static final long serialVersionUID = 0L; + + private Integer value = Integer.MAX_VALUE; + + /** + * Empty constructor + */ + public IntegerParameter() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + * @param value + */ + public IntegerParameter(String id, String name, Integer value) { + super(id, name); + setValue(value); + } + + /** + * DOM Constructor + * + * @param element + */ + public IntegerParameter(Element element) { + super.fromDom(element); + + String valueS = element.getAttribute(Tags.VALUE); + if (StringHelper.isEmpty(valueS)) { + String msg = MessageFormat.format("No value defined for {0}", this.id); //$NON-NLS-1$ + throw new StrolchException(msg); + } + + setValue(parseFromString(valueS)); + } + + @Override + public String getType() { + return IntegerParameter.TYPE; + } + + @Override + public String getValueAsString() { + return Integer.toString(this.value); + } + + @Override + public Integer getValue() { + return this.value; + } + + @Override + public void setValue(Integer value) { + validateValue(value); + this.value = value; + } + + @Override + public IntegerParameter getClone() { + IntegerParameter clone = new IntegerParameter(); + + super.fillClone(clone); + + clone.setValue(this.value); + + return clone; + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitIntegerParam(this); + } + + public static Integer parseFromString(String valueS) { + return Integer.valueOf(valueS); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/ListParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/ListParameter.java new file mode 100644 index 000000000..d599bb29b --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/ListParameter.java @@ -0,0 +1,45 @@ +/* + * 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.parameter; + +import java.util.List; + +/** + * @author Robert von Burg + * + */ +public interface ListParameter extends Parameter> { + + public static final String VALUE_SEPARATOR = ";"; //$NON-NLS-1$ + + /** + * Adds a single value to the {@link List} of values + * + * @param value + * the value to add + */ + public void addValue(E value); + + /** + * Removes a single value from the {@link List} of values + * + * @param value + * the value to remove + * + * @return true if the value was removed, false if it did not exist + */ + public boolean removeValue(E value); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/LongParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/LongParameter.java new file mode 100644 index 000000000..0e47f51a9 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/LongParameter.java @@ -0,0 +1,115 @@ +/* + * 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.parameter; + +import java.text.MessageFormat; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +public class LongParameter extends AbstractParameter { + + public static final String TYPE = "Long"; //$NON-NLS-1$ + private static final long serialVersionUID = 0L; + + protected Long value; + + /** + * Empty constructor + */ + public LongParameter() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + * @param value + */ + public LongParameter(String id, String name, Long value) { + super(id, name); + setValue(value); + } + + /** + * DOM Constructor + * + * @param element + */ + public LongParameter(Element element) { + super.fromDom(element); + + String valueS = element.getAttribute(Tags.VALUE); + if (StringHelper.isEmpty(valueS)) { + String msg = MessageFormat.format("No value defined for {0}", this.id); //$NON-NLS-1$ + throw new StrolchException(msg); + } + + setValue(parseFromString(valueS)); + } + + @Override + public String getValueAsString() { + return this.value.toString(); + } + + @Override + public Long getValue() { + return this.value; + } + + @Override + public void setValue(Long value) { + validateValue(value); + this.value = value; + } + + @Override + public String getType() { + return LongParameter.TYPE; + } + + @Override + public LongParameter getClone() { + LongParameter clone = new LongParameter(); + + super.fillClone(clone); + + clone.setValue(this.value); + + return clone; + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitLongParam(this); + } + + public static Long parseFromString(String valueS) { + return Long.valueOf(valueS); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/Parameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/Parameter.java new file mode 100644 index 000000000..f55b99594 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/Parameter.java @@ -0,0 +1,141 @@ +/* + * 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.parameter; + +import li.strolch.model.ParameterizedElement; +import li.strolch.model.StrolchElement; +import li.strolch.model.StrolchModelConstants; +import li.strolch.model.visitor.ParameterVisitor; + +/** + * @author Robert von Burg + */ +public interface Parameter extends StrolchElement { + + /** + * the value of the parameter as string + * + * @return String + */ + public String getValueAsString(); + + /** + * the value of the parameter + * + * @return + */ + public T getValue(); + + /** + * the value of the parameter + * + * @param value + */ + public void setValue(T value); + + /** + * 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); + + /** + * 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(); + + @Override + public boolean equals(Object obj); + + @Override + public Parameter getClone(); + + public U accept(ParameterVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/StringListParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/StringListParameter.java new file mode 100644 index 000000000..3068011f9 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/StringListParameter.java @@ -0,0 +1,154 @@ +/* + * 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.parameter; + +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + */ +public class StringListParameter extends AbstractParameter> implements ListParameter { + + public static final String TYPE = "StringList"; //$NON-NLS-1$ + private static final long serialVersionUID = 1L; + + protected List value; + + /** + * Empty constructor + */ + public StringListParameter() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + * @param value + */ + public StringListParameter(String id, String name, List value) { + super(id, name); + + setValue(value); + } + + /** + * DOM Constructor + * + * @param element + */ + public StringListParameter(Element element) { + super.fromDom(element); + + String valueS = element.getAttribute(Tags.VALUE); + if (StringHelper.isEmpty(valueS)) { + String msg = MessageFormat.format("No value defined for {0}", this.id); //$NON-NLS-1$ + throw new StrolchException(msg); + } + + setValue(parseFromString(valueS)); + } + + @Override + public String getValueAsString() { + if (this.value.isEmpty()) { + return StringHelper.EMPTY; + } + + StringBuilder sb = new StringBuilder(); + Iterator iter = this.value.iterator(); + while (iter.hasNext()) { + + sb.append(iter.next()); + + if (iter.hasNext()) { + sb.append(VALUE_SEPARATOR); + } + } + + return sb.toString(); + } + + @Override + public List getValue() { + return new ArrayList(this.value); + } + + @Override + public void setValue(List value) { + validateValue(value); + if (this.value == null) { + this.value = new ArrayList(value.size()); + } + this.value.clear(); + this.value.addAll(value); + } + + @Override + public void addValue(String value) { + this.value.add(value); + } + + @Override + public boolean removeValue(String value) { + return this.value.remove(value); + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public StringListParameter getClone() { + StringListParameter clone = new StringListParameter(); + + super.fillClone(clone); + + clone.setValue(this.value); + + return clone; + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitStringListParam(this); + } + + public static List parseFromString(String value) { + if (value.isEmpty()) { + return Collections.emptyList(); + } + + String[] valueArr = value.split(VALUE_SEPARATOR); + return Arrays.asList(valueArr); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/parameter/StringParameter.java b/li.strolch.model/src/main/java/li/strolch/model/parameter/StringParameter.java new file mode 100644 index 000000000..b7c65b897 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/parameter/StringParameter.java @@ -0,0 +1,113 @@ +/* + * 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.parameter; + +import java.text.MessageFormat; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; +import li.strolch.model.visitor.ParameterVisitor; + +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +public class StringParameter extends AbstractParameter { + + public static final String UNDEFINED_VALUE = "-"; //$NON-NLS-1$ + public static final String TYPE = "String"; //$NON-NLS-1$ + private static final long serialVersionUID = 0L; + + private String value = UNDEFINED_VALUE; + + /** + * Empty constructor + * + */ + public StringParameter() { + // + } + + /** + * Default constructor + * + * @param id + * @param name + * @param value + */ + public StringParameter(String id, String name, String value) { + super(id, name); + setValue(value); + } + + /** + * DOM Constructor + * + * @param element + */ + public StringParameter(Element element) { + super.fromDom(element); + + String valueS = element.getAttribute(Tags.VALUE); + if (StringHelper.isEmpty(valueS)) { + String msg = MessageFormat.format("No value defined for {0}", this.id); //$NON-NLS-1$ + throw new StrolchException(msg); + } + + setValue(valueS); + } + + @Override + public String getType() { + return StringParameter.TYPE; + } + + @Override + public String getValue() { + return this.value; + } + + @Override + public String getValueAsString() { + return this.value; + } + + @Override + public void setValue(String value) { + validateValue(value); + this.value = value; + } + + @Override + public StringParameter getClone() { + StringParameter clone = new StringParameter(); + + super.fillClone(clone); + + clone.setValue(this.value); + + return clone; + } + + @Override + public U accept(ParameterVisitor visitor) { + return visitor.visitStringParam(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/AndSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/AndSelection.java new file mode 100644 index 000000000..877ba4f50 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/AndSelection.java @@ -0,0 +1,63 @@ +/* + * 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.query; + +import java.util.List; + +/** + * @author Robert von Burg + */ +public class AndSelection extends BooleanSelection { + + public AndSelection() { + super(); + } + + @SafeVarargs + public AndSelection(Selection... selections) { + super(selections); + } + + /** + * @param selections + */ + public AndSelection(List selections) { + super(selections); + } + + @Override + public AndSelection with(Selection selection) { + super.with(selection); + return this; + } + + @Override + public AndSelection with(List selections) { + super.with(selections); + return this; + } + + @Override + public AndSelection with(Selection... selections) { + super.with(selections); + return this; + } + + @Override + public void accept(QueryVisitor visitor) { + visitor.visitAnd(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/AnySelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/AnySelection.java new file mode 100644 index 000000000..79762b54c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/AnySelection.java @@ -0,0 +1,32 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public class AnySelection implements Selection { + + @Override + public void accept(QueryVisitor visitor) { + visitor.visitAny(); + } + + @Override + public boolean hasSelection() { + return true; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/BooleanSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/BooleanSelection.java new file mode 100644 index 000000000..afc7284b7 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/BooleanSelection.java @@ -0,0 +1,85 @@ +/* + * 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.query; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author Robert von Burg + */ +public abstract class BooleanSelection implements Selection { + + protected List selections; + + public BooleanSelection() { + this.selections = new ArrayList<>(1); + } + + public BooleanSelection(List selections) { + this.selections = selections; + } + + public BooleanSelection(Selection leftHandSide, Selection rightHandSide) { + this.selections = new ArrayList<>(2); + this.selections.add(leftHandSide); + this.selections.add(rightHandSide); + } + + public BooleanSelection(Selection... selections) { + this.selections = Arrays.asList(selections); + } + + @Override + public boolean hasSelection() { + if (this.selections == null || this.selections.isEmpty()) + return false; + + for (Selection selection : this.selections) { + if (selection.hasSelection()) { + return true; + } + } + + return false; + } + + public List getSelections() { + return Collections.unmodifiableList(this.selections); + } + + public BooleanSelection with(Selection selection) { + this.selections.add(selection); + return this; + } + + public BooleanSelection with(Selection... selections) { + for (Selection selection : selections) { + this.selections.add(selection); + } + return this; + } + + public BooleanSelection with(List selections) { + this.selections.addAll(selections); + return this; + } + + @Override + public abstract void accept(QueryVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/DateSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/DateSelection.java new file mode 100644 index 000000000..ea3ef2645 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/DateSelection.java @@ -0,0 +1,79 @@ +/* + * 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.query; + +import java.util.Date; + +import ch.eitchnet.utils.collections.DateRange; + +/** + * @author Robert von Burg + */ +public class DateSelection extends OrderSelection { + + private DateRange dateRange; + + public DateSelection() { + this.dateRange = new DateRange(); + } + + public DateSelection from(Date from, boolean inclusive) { + this.dateRange.from(from, inclusive); + return this; + } + + public DateSelection to(Date to, boolean inclusive) { + this.dateRange.to(to, inclusive); + return this; + } + + public Date getFromDate() { + return this.dateRange.getFromDate(); + } + + public Date getToDate() { + return this.dateRange.getToDate(); + } + + public boolean isFromBounded() { + return this.dateRange.isFromBounded(); + } + + public boolean isToBounded() { + return this.dateRange.isToBounded(); + } + + public boolean isUnbounded() { + return this.dateRange.isUnbounded(); + } + + public boolean isBounded() { + return this.dateRange.isBounded(); + } + + public boolean contains(Date date) { + return this.dateRange.contains(date); + } + + public DateRange getDateRange() { + return this.dateRange; + } + + @Override + public void accept(OrderSelectionVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/IdSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/IdSelection.java new file mode 100644 index 000000000..1aea0f913 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/IdSelection.java @@ -0,0 +1,75 @@ +/* + * 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.query; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Robert von Burg + */ +public class IdSelection extends StrolchElementSelection { + + private List ids; + + public IdSelection() { + this.ids = new ArrayList<>(1); + } + + /** + * @param id + */ + public IdSelection(String id) { + this.ids = new ArrayList<>(1); + this.ids.add(id); + } + + /** + * @param ids + */ + public IdSelection(String... ids) { + this.ids = Arrays.asList(ids); + } + + /** + * @param ids + */ + public IdSelection(List ids) { + this.ids = ids; + } + + /** + * @return the ids + */ + public List getIds() { + return this.ids; + } + + /** + * @param id + * @return + */ + public IdSelection with(String id) { + this.ids.add(id); + return this; + } + + @Override + public void accept(StrolchElementSelectionVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/NameSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/NameSelection.java new file mode 100644 index 000000000..9b618563d --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/NameSelection.java @@ -0,0 +1,55 @@ +/* + * 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.query; + +import ch.eitchnet.utils.StringMatchMode; + +/** + * @author Robert von Burg + */ +public class NameSelection extends StrolchElementSelection { + + private StringMatchMode matchMode; + private String name; + + /** + * @param name + * @param matchMode + */ + public NameSelection(String name, StringMatchMode matchMode) { + this.name = name; + this.matchMode = matchMode; + } + + /** + * @return the name + */ + public String getName() { + return this.name; + } + + /** + * @return the matchMode + */ + public StringMatchMode getMatchMode() { + return this.matchMode; + } + + @Override + public void accept(StrolchElementSelectionVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/Navigation.java b/li.strolch.model/src/main/java/li/strolch/model/query/Navigation.java new file mode 100644 index 000000000..b184bdd02 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/Navigation.java @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.query; + +/** + * @author Robert von Burg + */ +public interface Navigation { + + public void accept(QueryVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/NotSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/NotSelection.java new file mode 100644 index 000000000..a6ea2e0cf --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/NotSelection.java @@ -0,0 +1,47 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public class NotSelection extends BooleanSelection { + + /** + * @param selection + */ + public NotSelection(Selection selection) { + super(selection); + } + + /** + * @throws UnsupportedOperationException + * because a {@link NotSelection} can only work on a single {@link Selection} + */ + @Override + public NotSelection with(Selection selection) { + throw new UnsupportedOperationException("NotSelection can only have a single selection"); //$NON-NLS-1$ + } + + public Selection getSelection() { + return this.selections.get(0); + } + + @Override + public void accept(QueryVisitor visitor) { + visitor.visitNot(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/OrSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/OrSelection.java new file mode 100644 index 000000000..e2b0d582c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/OrSelection.java @@ -0,0 +1,60 @@ +/* + * 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.query; + +import java.util.List; + +/** + * @author Robert von Burg + */ +public class OrSelection extends BooleanSelection { + + public OrSelection() { + super(); + } + + public OrSelection(List selections) { + super(selections); + } + + @SafeVarargs + public OrSelection(Selection... selections) { + super(selections); + } + + @Override + public OrSelection with(Selection selection) { + super.with(selection); + return this; + } + + @Override + public OrSelection with(List selections) { + super.with(selections); + return this; + } + + @Override + public OrSelection with(Selection... selections) { + super.with(selections); + return this; + } + + @Override + public void accept(QueryVisitor visitor) { + visitor.visitOr(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/OrderQuery.java b/li.strolch.model/src/main/java/li/strolch/model/query/OrderQuery.java new file mode 100644 index 000000000..b7d3347c9 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/OrderQuery.java @@ -0,0 +1,62 @@ +/* + * 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.query; + +import li.strolch.model.Order; +import li.strolch.model.OrderVisitor; +import li.strolch.model.parameter.Parameter; + +/** + * {@link OrderQuery} is the user API to query {@link Order Orders} in Strolch. The {@link Navigation} is used to + * navigate to a type of order on which any further {@link Selection Selections} will be performed. The + * {@link OrderVisitor} is used to transform the returned object into a domain specific object (if required). This + * mechanism allows you to query only the values of a {@link Parameter} instead of having to return all the elements and + * then performing this transformation. + * + * @author Robert von Burg + */ +public class OrderQuery extends StrolchElementQuery { + + public OrderQuery(Navigation navigation) { + super(navigation); + } + + @Override + public OrderQuery with(Selection selection) { + super.with(selection); + return this; + } + + @Override + public OrderQuery not(Selection selection) { + super.not(selection); + return this; + } + + @Override + public OrderQuery withAny() { + super.withAny(); + return this; + } + + public static OrderQuery query(Navigation navigation) { + return new OrderQuery(navigation); + } + + public static OrderQuery query(String type) { + return new OrderQuery(new StrolchTypeNavigation(type)); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/OrderQueryVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/query/OrderQueryVisitor.java new file mode 100644 index 000000000..91196a0f3 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/OrderQueryVisitor.java @@ -0,0 +1,25 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.query; + +/** + * @author Robert von Burg + * + */ +public interface OrderQueryVisitor extends OrderSelectionVisitor, ParameterSelectionVisitor { + + // marker interface +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/OrderSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/OrderSelection.java new file mode 100644 index 000000000..4a904d612 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/OrderSelection.java @@ -0,0 +1,35 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + * + */ +public abstract class OrderSelection implements Selection { + + @Override + public void accept(QueryVisitor visitor) { + accept((OrderSelectionVisitor) visitor); + } + + @Override + public boolean hasSelection() { + return true; + } + + public abstract void accept(OrderSelectionVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/OrderSelectionVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/query/OrderSelectionVisitor.java new file mode 100644 index 000000000..6f3c36349 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/OrderSelectionVisitor.java @@ -0,0 +1,27 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + * + */ +public interface OrderSelectionVisitor extends StrolchRootElementSelectionVisitor { + + public void visit(DateSelection selection); + + public void visit(StateSelection selection); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/ParameterBagSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/ParameterBagSelection.java new file mode 100644 index 000000000..c1910d2ea --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/ParameterBagSelection.java @@ -0,0 +1,71 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public class ParameterBagSelection implements Selection { + + private String bagKey; + + public ParameterBagSelection(String bagKey) { + this.bagKey = bagKey; + } + + /** + * @return the bagKey + */ + public String getBagKey() { + return this.bagKey; + } + + @Override + public boolean hasSelection() { + return true; + } + + @Override + public void accept(QueryVisitor visitor) { + accept((StrolchRootElementSelectionVisitor) visitor); + } + + public void accept(StrolchRootElementSelectionVisitor visitor) { + visitor.visit(this); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName() + " [bagKey="); + builder.append(this.bagKey); + builder.append("]"); + return builder.toString(); + } + + public static class NullParameterBagSelection extends ParameterBagSelection { + + public NullParameterBagSelection(String bagKey) { + super(bagKey); + } + + @Override + public void accept(StrolchRootElementSelectionVisitor visitor) { + visitor.visit(this); + } + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/ParameterSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/ParameterSelection.java new file mode 100644 index 000000000..d6742d54c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/ParameterSelection.java @@ -0,0 +1,288 @@ +/* + * 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.query; + +import java.util.Date; +import java.util.List; + +import ch.eitchnet.utils.StringMatchMode; +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +public abstract class ParameterSelection implements Selection { + + private String bagKey; + private String paramKey; + + public ParameterSelection(String bagKey, String paramKey) { + this.bagKey = bagKey; + this.paramKey = paramKey; + } + + /** + * @return the bagKey + */ + public String getBagKey() { + return this.bagKey; + } + + /** + * @return the paramKey + */ + public String getParamKey() { + return this.paramKey; + } + + @Override + public boolean hasSelection() { + return true; + } + + @Override + public void accept(QueryVisitor visitor) { + accept((ParameterSelectionVisitor) visitor); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append(getClass().getSimpleName() + " [bagKey="); + builder.append(this.bagKey); + builder.append(", paramKey="); + builder.append(this.paramKey); + builder.append("]"); + return builder.toString(); + } + + public abstract void accept(ParameterSelectionVisitor visitor); + + public static StringParameterSelection stringSelection(String bagKey, String paramKey, String value, + StringMatchMode matchMode) { + return new StringParameterSelection(bagKey, paramKey, value, matchMode); + } + + public static IntegerParameterSelection integerSelection(String bagKey, String paramKey, int value) { + return new IntegerParameterSelection(bagKey, paramKey, value); + } + + public static BooleanParameterSelection booleanSelection(String bagKey, String paramKey, boolean value) { + return new BooleanParameterSelection(bagKey, paramKey, value); + } + + public static FloatParameterSelection floatSelection(String bagKey, String paramKey, double value) { + return new FloatParameterSelection(bagKey, paramKey, value); + } + + public static LongParameterSelection longSelection(String bagKey, String paramKey, long value) { + return new LongParameterSelection(bagKey, paramKey, value); + } + + public static DateParameterSelection dateSelection(String bagKey, String paramKey, Date value) { + return new DateParameterSelection(bagKey, paramKey, value); + } + + public static DateRangeParameterSelection dateRangeSelection(String bagKey, String paramKey, Date from, Date to) { + return new DateRangeParameterSelection(bagKey, paramKey, from, to); + } + + public static StringListParameterSelection stringListSelection(String bagKey, String paramKey, List value) { + return new StringListParameterSelection(bagKey, paramKey, value); + } + + public static NullParameterSelection nullSelection(String bagKey, String paramKey) { + return new NullParameterSelection(bagKey, paramKey); + } + + public static class NullParameterSelection extends ParameterSelection { + + public NullParameterSelection(String bagKey, String paramKey) { + super(bagKey, paramKey); + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class StringParameterSelection extends ParameterSelection { + + private StringMatchMode matchMode; + private String value; + + public StringParameterSelection(String bagKey, String paramKey, String value, StringMatchMode matchMode) { + super(bagKey, paramKey); + this.value = value; + this.matchMode = matchMode; + } + + public String getValue() { + return this.value; + } + + public StringMatchMode getMatchMode() { + return this.matchMode; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class IntegerParameterSelection extends ParameterSelection { + + private Integer value; + + public IntegerParameterSelection(String bagKey, String paramKey, Integer value) { + super(bagKey, paramKey); + this.value = value; + } + + public Integer getValue() { + return this.value; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class BooleanParameterSelection extends ParameterSelection { + + private Boolean value; + + public BooleanParameterSelection(String bagKey, String paramKey, Boolean value) { + super(bagKey, paramKey); + this.value = value; + } + + public Boolean getValue() { + return this.value; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class LongParameterSelection extends ParameterSelection { + + private Long value; + + public LongParameterSelection(String bagKey, String paramKey, Long value) { + super(bagKey, paramKey); + this.value = value; + } + + public Long getValue() { + return this.value; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class FloatParameterSelection extends ParameterSelection { + + private Double value; + + public FloatParameterSelection(String bagKey, String paramKey, Double value) { + super(bagKey, paramKey); + this.value = value; + } + + public Double getValue() { + return this.value; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class DateParameterSelection extends ParameterSelection { + + private Date value; + + public DateParameterSelection(String bagKey, String paramKey, Date value) { + super(bagKey, paramKey); + this.value = value; + } + + public Date getValue() { + return this.value; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class DateRangeParameterSelection extends ParameterSelection { + + private Date from; + private Date to; + + public DateRangeParameterSelection(String bagKey, String paramKey, Date from, Date to) { + super(bagKey, paramKey); + DBC.PRE.assertFalse("Either 'to' or 'from' must be set! Both can not be null!", from == null && to == null); //$NON-NLS-1$ + this.from = from; + this.to = to; + } + + public Date getFrom() { + return this.from; + } + + public Date getTo() { + return this.to; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } + + public static class StringListParameterSelection extends ParameterSelection { + + private List value; + + public StringListParameterSelection(String bagKey, String paramKey, List value) { + super(bagKey, paramKey); + this.value = value; + } + + public List getValue() { + return this.value; + } + + @Override + public void accept(ParameterSelectionVisitor visitor) { + visitor.visit(this); + } + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/ParameterSelectionVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/query/ParameterSelectionVisitor.java new file mode 100644 index 000000000..3b53f54f6 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/ParameterSelectionVisitor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.query; + +import li.strolch.model.query.ParameterSelection.BooleanParameterSelection; +import li.strolch.model.query.ParameterSelection.DateParameterSelection; +import li.strolch.model.query.ParameterSelection.DateRangeParameterSelection; +import li.strolch.model.query.ParameterSelection.FloatParameterSelection; +import li.strolch.model.query.ParameterSelection.IntegerParameterSelection; +import li.strolch.model.query.ParameterSelection.LongParameterSelection; +import li.strolch.model.query.ParameterSelection.NullParameterSelection; +import li.strolch.model.query.ParameterSelection.StringListParameterSelection; +import li.strolch.model.query.ParameterSelection.StringParameterSelection; + +/** + * @author Robert von Burg + */ +public interface ParameterSelectionVisitor extends QueryVisitor { + + public void visit(StringParameterSelection selection); + + public void visit(IntegerParameterSelection selection); + + public void visit(BooleanParameterSelection selection); + + public void visit(LongParameterSelection selection); + + public void visit(FloatParameterSelection selection); + + public void visit(DateParameterSelection selection); + + public void visit(DateRangeParameterSelection selection); + + public void visit(StringListParameterSelection selection); + + public void visit(NullParameterSelection nullParameterSelection); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/QueryVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/query/QueryVisitor.java new file mode 100644 index 000000000..0209ae2bc --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/QueryVisitor.java @@ -0,0 +1,30 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public interface QueryVisitor { + + public void visitAny(); + + public void visitAnd(AndSelection andSelection); + + public void visitOr(OrSelection orSelection); + + public void visitNot(NotSelection notSelection); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/ResourceQuery.java b/li.strolch.model/src/main/java/li/strolch/model/query/ResourceQuery.java new file mode 100644 index 000000000..900d2659a --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/ResourceQuery.java @@ -0,0 +1,66 @@ +/* + * 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.query; + +import li.strolch.model.Resource; +import li.strolch.model.ResourceVisitor; +import li.strolch.model.parameter.Parameter; + +/** + * {@link ResourceQuery} is the user API to query {@link Resource Resources} in Strolch. The {@link Navigation} is used + * to navigate to a type of resource on which any further {@link Selection Selections} will be performed. The + * {@link ResourceVisitor} is used to transform the returned object into a domain specific object (if required). This + * mechanism allows you to query only the values of a {@link Parameter} instead of having to return all the elements and + * then performing this transformation. + * + * @author Robert von Burg + */ +public class ResourceQuery extends StrolchElementQuery { + + /** + * @param navigation + * @param elementVisitor + */ + public ResourceQuery(Navigation navigation) { + super(navigation); + } + + @Override + public ResourceQuery with(Selection selection) { + super.with(selection); + return this; + } + + @Override + public ResourceQuery not(Selection selection) { + super.not(selection); + return this; + } + + @Override + public ResourceQuery withAny() { + super.withAny(); + return this; + } + + public static ResourceQuery query(Navigation navigation) { + return new ResourceQuery(navigation); + } + + public static ResourceQuery query(String type) { + return new ResourceQuery(new StrolchTypeNavigation(type)); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/ResourceQueryVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/query/ResourceQueryVisitor.java new file mode 100644 index 000000000..867e0b344 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/ResourceQueryVisitor.java @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.query; + +/** + * @author Robert von Burg + */ +public interface ResourceQueryVisitor extends StrolchRootElementSelectionVisitor, ParameterSelectionVisitor { + + // marker interface +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/Selection.java b/li.strolch.model/src/main/java/li/strolch/model/query/Selection.java new file mode 100644 index 000000000..7d720035e --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/Selection.java @@ -0,0 +1,26 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public interface Selection { + + public void accept(QueryVisitor visitor); + + public boolean hasSelection(); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StateSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/StateSelection.java new file mode 100644 index 000000000..8c4aae742 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StateSelection.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.query; + +import li.strolch.model.State; + +/** + * @author Robert von Burg + */ +public class StateSelection extends OrderSelection { + + private State state; + + public StateSelection(State state) { + this.state = state; + } + + public State getState() { + return this.state; + } + + @Override + public void accept(OrderSelectionVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StringSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/StringSelection.java new file mode 100644 index 000000000..f5fa5d39a --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StringSelection.java @@ -0,0 +1,85 @@ +/* + * 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.query; + +import ch.eitchnet.utils.StringMatchMode; + +/** + * @author Robert von Burg + */ +public class StringSelection { + + private StringMatchMode matchMode; + private String[] values; + + public StringSelection() { + // + } + + /** + * @param matchMode + * @param values + */ + public StringSelection(StringMatchMode matchMode, String[] values) { + this.matchMode = matchMode; + this.values = values; + } + + /** + * @return the matchMode + */ + public StringMatchMode getMatchMode() { + return this.matchMode; + } + + /** + * @param matchMode + * the matchMode to set + */ + public void setMatchMode(StringMatchMode matchMode) { + this.matchMode = matchMode; + } + + /** + * @return the values + */ + public String[] getValues() { + return this.values; + } + + /** + * @param values + * the values to set + */ + public void setValues(String... values) { + this.values = values; + } + + /** + * @return + */ + public boolean isWildCard() { + return this.values == null || this.values.length == 0; + } + + public boolean matches(String value) { + for (String sel : this.values) { + if (this.matchMode.matches(value, sel)) + return true; + } + return false; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementQuery.java b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementQuery.java new file mode 100644 index 000000000..78c429815 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementQuery.java @@ -0,0 +1,103 @@ +/* + * 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.query; + +import ch.eitchnet.utils.dbc.DBC; + +/** + * @author Robert von Burg + */ +public abstract class StrolchElementQuery implements StrolchQuery { + + private Navigation navigation; + private Selection selection; + + public StrolchElementQuery(Navigation navigation) { + this.navigation = navigation; + } + + public boolean hasNavigation() { + return this.navigation != null; + } + + public boolean hasSelection() { + return this.selection != null && this.selection.hasSelection(); + } + + public Selection getSelection() { + return this.selection; + } + + public StrolchElementQuery with(Selection selection) { + assertNoSelectionYetSet(); + this.selection = selection; + return this; + } + + private void assertNoSelectionYetSet() { + String msg = "A selection is already set! Use a cascaded boolean operators to perform multiple selections"; //$NON-NLS-1$ + DBC.PRE.assertNull(msg, this.selection); + } + + public StrolchElementQuery withAny() { + assertNoSelectionYetSet(); + this.selection = new AnySelection(); + return this; + } + + public AndSelection and() { + assertNoSelectionYetSet(); + AndSelection and = new AndSelection(); + this.selection = and; + return and; + } + + public OrSelection or() { + assertNoSelectionYetSet(); + OrSelection or = new OrSelection(); + this.selection = or; + return or; + } + + public StrolchElementQuery not(Selection selection) { + assertNoSelectionYetSet(); + this.selection = new NotSelection(selection); + return this; + } + + public void accept(T visitor) { + DBC.PRE.assertNotNull("No navigation set!", this.navigation); //$NON-NLS-1$ + DBC.PRE.assertNotNull("No selection defined!", this.selection); //$NON-NLS-1$ + this.navigation.accept(visitor); + this.selection.accept(visitor); + } + + /** + * @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeName() + */ + @Override + public String getPrivilegeName() { + return StrolchQuery.class.getName(); + } + + /** + * @see ch.eitchnet.privilege.model.Restrictable#getPrivilegeValue() + */ + @Override + public Object getPrivilegeValue() { + return getClass().getName(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementSelection.java b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementSelection.java new file mode 100644 index 000000000..0d33dc4bc --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementSelection.java @@ -0,0 +1,34 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public abstract class StrolchElementSelection implements Selection { + + @Override + public void accept(QueryVisitor visitor) { + accept((StrolchElementSelectionVisitor) visitor); + } + + @Override + public boolean hasSelection() { + return true; + } + + public abstract void accept(StrolchElementSelectionVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementSelectionVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementSelectionVisitor.java new file mode 100644 index 000000000..b7bf67fdb --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchElementSelectionVisitor.java @@ -0,0 +1,28 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public interface StrolchElementSelectionVisitor extends QueryVisitor { + + public void visit(StrolchTypeNavigation navigation); + + public void visit(IdSelection selection); + + public void visit(NameSelection selection); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StrolchQuery.java b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchQuery.java new file mode 100644 index 000000000..018e3b9e4 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchQuery.java @@ -0,0 +1,26 @@ +/* + * 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.query; + +import ch.eitchnet.privilege.model.Restrictable; + +/** + * @author Robert von Burg + */ +public interface StrolchQuery extends Restrictable { + + // marker interface +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StrolchRootElementSelectionVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchRootElementSelectionVisitor.java new file mode 100644 index 000000000..3a2c3cace --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchRootElementSelectionVisitor.java @@ -0,0 +1,28 @@ +/* + * 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.query; + +import li.strolch.model.query.ParameterBagSelection.NullParameterBagSelection; + +/** + * @author Robert von Burg + */ +public interface StrolchRootElementSelectionVisitor extends StrolchElementSelectionVisitor { + + public void visit(ParameterBagSelection selection); + + public void visit(NullParameterBagSelection selection); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/query/StrolchTypeNavigation.java b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchTypeNavigation.java new file mode 100644 index 000000000..a4f7c9fa2 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/query/StrolchTypeNavigation.java @@ -0,0 +1,44 @@ +/* + * 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.query; + +/** + * @author Robert von Burg + */ +public class StrolchTypeNavigation implements Navigation { + + private String type; + + public StrolchTypeNavigation(String type) { + this.type = type; + } + + /** + * @return the type + */ + public String getType() { + return this.type; + } + + @Override + public void accept(QueryVisitor visitor) { + accept((StrolchElementSelectionVisitor) visitor); + } + + public void accept(StrolchElementSelectionVisitor visitor) { + visitor.visit(this); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/AbstractStrolchTimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/AbstractStrolchTimedState.java new file mode 100644 index 000000000..f79cff7b4 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/AbstractStrolchTimedState.java @@ -0,0 +1,263 @@ +/* + * 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.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; +import li.strolch.model.Resource; +import li.strolch.model.StrolchElement; +import li.strolch.model.StrolchRootElement; +import li.strolch.model.Tags; +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 + */ +@SuppressWarnings("rawtypes") +public abstract class AbstractStrolchTimedState extends AbstractStrolchElement implements + StrolchTimedState { + + 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; + + public AbstractStrolchTimedState() { + this.state = new TimedState<>(); + } + + public AbstractStrolchTimedState(String id, String name) { + super(id, name); + 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); + } + + @Override + public ITimeValue getPreviousMatch(Long time, T value) { + return this.state.getPreviousMatch(time, value); + } + + @Override + public > void applyChange(U change) { + this.state.applyChange(change); + } + + @Override + public ITimeValue getStateAt(Long time) { + return this.state.getStateAt(time); + } + + @Override + public ITimeVariable getTimeEvolution() { + return this.state.getTimeEvolution(); + } + + @Override + public StrolchElement getParent() { + return this.parent; + } + + @Override + public void setParent(Resource parent) { + this.parent = parent; + } + + @Override + public StrolchRootElement getRootElement() { + return this.parent; + } + + @Override + 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 + public Locator getLocator() { + LocatorBuilder lb = new LocatorBuilder(); + this.parent.fillLocator(lb); + fillLocator(lb); + return lb.build(); + } + + protected void fillClone(AbstractStrolchTimedState clone) { + super.fillClone(clone); + clone.state = this.state.getCopy(); + } + + @Override + public U accept(TimedStateVisitor visitor) { + return visitor.visitTimedState(this); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + + StringBuilder builder = new StringBuilder(); + + builder.append(getClass().getSimpleName()); + builder.append(" [id="); + builder.append(this.id); + builder.append(", name="); + builder.append(this.name); + builder.append(", valueNow="); + builder.append(this.state.getStateAt(System.currentTimeMillis())); + builder.append("]"); + + return builder.toString(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/BooleanTimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/BooleanTimedState.java new file mode 100644 index 000000000..13f3474a7 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/BooleanTimedState.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.timedstate; + +import java.util.SortedSet; + +import li.strolch.model.StrolchElement; +import li.strolch.model.Tags; +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.impl.BooleanValue; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * @author Robert von Burg + */ +public class BooleanTimedState extends AbstractStrolchTimedState { + + private static final long serialVersionUID = 1L; + + public static final String TYPE = "BooleanState"; + + public BooleanTimedState() { + super(); + } + + public BooleanTimedState(String id, String name) { + super(id, name); + } + + public BooleanTimedState(Element element) { + super.fromDom(element); + + this.state = new TimedState<>(); + + NodeList timeValueElems = element.getElementsByTagName(Tags.VALUE); + for (int i = 0; i < timeValueElems.getLength(); i++) { + Element timeValueElem = (Element) timeValueElems.item(i); + Long time = Long.valueOf(timeValueElem.getAttribute(Tags.TIME)); + Boolean value = Boolean.valueOf(timeValueElem.getAttribute(Tags.VALUE)); + BooleanValue booleanValue = new BooleanValue(value); + this.state.getTimeEvolution().setValueAt(time, booleanValue); + } + } + + @Override + public Element toDom(Document doc) { + + Element stateElement = doc.createElement(Tags.TIMED_STATE); + super.fillElement(stateElement); + SortedSet> values = this.state.getTimeEvolution().getValues(); + for (ITimeValue timeValue : values) { + Long time = timeValue.getTime(); + BooleanValue value = timeValue.getValue(); + Element valueElem = doc.createElement(Tags.VALUE); + valueElem.setAttribute(Tags.TIME, time.toString()); + valueElem.setAttribute(Tags.VALUE, value.getValue().toString()); + stateElement.appendChild(valueElem); + } + + return stateElement; + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public StrolchElement getClone() { + BooleanTimedState clone = new BooleanTimedState(); + fillClone(clone); + return clone; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/FloatTimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/FloatTimedState.java new file mode 100644 index 000000000..a82960ba3 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/FloatTimedState.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.timedstate; + +import java.util.SortedSet; + +import li.strolch.model.StrolchElement; +import li.strolch.model.Tags; +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.impl.FloatValue; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * @author Robert von Burg + */ +public class FloatTimedState extends AbstractStrolchTimedState { + + private static final long serialVersionUID = 1L; + + public static final String TYPE = "FloatState"; + + public FloatTimedState() { + super(); + } + + public FloatTimedState(String id, String name) { + super(id, name); + } + + public FloatTimedState(Element element) { + super.fromDom(element); + + this.state = new TimedState<>(); + + NodeList timeValueElems = element.getElementsByTagName(Tags.VALUE); + for (int i = 0; i < timeValueElems.getLength(); i++) { + Element timeValueElem = (Element) timeValueElems.item(i); + Long time = Long.valueOf(timeValueElem.getAttribute(Tags.TIME)); + Double value = Double.valueOf(timeValueElem.getAttribute(Tags.VALUE)); + FloatValue floatValue = new FloatValue(value); + this.state.getTimeEvolution().setValueAt(time, floatValue); + } + } + + @Override + public Element toDom(Document doc) { + + Element stateElement = doc.createElement(Tags.TIMED_STATE); + super.fillElement(stateElement); + SortedSet> values = this.state.getTimeEvolution().getValues(); + for (ITimeValue timeValue : values) { + Long time = timeValue.getTime(); + FloatValue value = timeValue.getValue(); + Element valueElem = doc.createElement(Tags.VALUE); + valueElem.setAttribute(Tags.TIME, time.toString()); + valueElem.setAttribute(Tags.VALUE, value.getValue().toString()); + stateElement.appendChild(valueElem); + } + + return stateElement; + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public StrolchElement getClone() { + FloatTimedState clone = new FloatTimedState(); + fillClone(clone); + return clone; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/ITimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/ITimedState.java new file mode 100644 index 000000000..e1e60a2be --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/ITimedState.java @@ -0,0 +1,64 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timedstate; + +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.ITimeVariable; +import li.strolch.model.timevalue.IValue; +import li.strolch.model.timevalue.IValueChange; + +/** + * A time based state characterized by a {@link IValue} object implementation. + * + * @author Martin Smock + * + * @param + * IValue implementation representing the state at a given time + */ +@SuppressWarnings("rawtypes") +public interface ITimedState { + + /** + * @return the new {@link ITimeValue} matching the value in the future + */ + ITimeValue getNextMatch(final Long time, T value); + + /** + * @return the new {@link ITimeValue} matching the value in the future + */ + ITimeValue getPreviousMatch(final Long time, T value); + + /** + * @param change + * the state change to be applied + */ + > void applyChange(final U change); + + /** + * @return the state at the given time + */ + ITimeValue getStateAt(final Long time); + + /** + * @return get the states evolution in time + */ + ITimeVariable getTimeEvolution(); + + /** + * @return a copy of this timed state + */ + ITimedState getCopy(); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/IntegerTimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/IntegerTimedState.java new file mode 100644 index 000000000..8cd771412 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/IntegerTimedState.java @@ -0,0 +1,90 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.timedstate; + +import java.util.SortedSet; + +import li.strolch.model.StrolchElement; +import li.strolch.model.Tags; +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.impl.IntegerValue; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * @author Robert von Burg + */ +public class IntegerTimedState extends AbstractStrolchTimedState { + + private static final long serialVersionUID = 1L; + + public static final String TYPE = "IntegerState"; + + public IntegerTimedState() { + super(); + } + + public IntegerTimedState(String id, String name) { + super(id, name); + } + + public IntegerTimedState(Element element) { + super.fromDom(element); + + this.state = new TimedState<>(); + + NodeList timeValueElems = element.getElementsByTagName(Tags.VALUE); + for (int i = 0; i < timeValueElems.getLength(); i++) { + Element timeValueElem = (Element) timeValueElems.item(i); + Long time = Long.valueOf(timeValueElem.getAttribute(Tags.TIME)); + Integer value = Integer.valueOf(timeValueElem.getAttribute(Tags.VALUE)); + IntegerValue integerValue = new IntegerValue(value); + this.state.getTimeEvolution().setValueAt(time, integerValue); + } + } + + @Override + public Element toDom(Document doc) { + + Element stateElement = doc.createElement(Tags.TIMED_STATE); + super.fillElement(stateElement); + SortedSet> values = this.state.getTimeEvolution().getValues(); + for (ITimeValue timeValue : values) { + Long time = timeValue.getTime(); + IntegerValue value = timeValue.getValue(); + Element valueElem = doc.createElement(Tags.VALUE); + valueElem.setAttribute(Tags.TIME, time.toString()); + valueElem.setAttribute(Tags.VALUE, value.getValue().toString()); + stateElement.appendChild(valueElem); + } + + return stateElement; + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public StrolchElement getClone() { + IntegerTimedState clone = new IntegerTimedState(); + fillClone(clone); + return clone; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/StringSetTimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/StringSetTimedState.java new file mode 100644 index 000000000..76c202e56 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/StringSetTimedState.java @@ -0,0 +1,113 @@ +/* + * 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.timedstate; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.SortedSet; + +import li.strolch.model.StrolchElement; +import li.strolch.model.Tags; +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.impl.AString; +import li.strolch.model.timevalue.impl.StringSetValue; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +/** + * @author Robert von Burg + */ +public class StringSetTimedState extends AbstractStrolchTimedState { + + private static final long serialVersionUID = 1L; + + public static final String TYPE = "StringSetState"; + + public StringSetTimedState() { + super(); + } + + public StringSetTimedState(String id, String name) { + super(id, name); + } + + public StringSetTimedState(Element element) { + super.fromDom(element); + + this.state = new TimedState<>(); + + NodeList timeValueElems = element.getElementsByTagName(Tags.VALUE); + for (int i = 0; i < timeValueElems.getLength(); i++) { + Element timeValueElem = (Element) timeValueElems.item(i); + Long time = Long.valueOf(timeValueElem.getAttribute(Tags.TIME)); + + String valueAsString = timeValueElem.getAttribute(Tags.VALUE); + Set value = new HashSet<>(); + String[] values = valueAsString.split(","); + for (String s : values) { + value.add(new AString(s.trim())); + } + + StringSetValue integerValue = new StringSetValue(value); + this.state.getTimeEvolution().setValueAt(time, integerValue); + } + } + + @Override + public Element toDom(Document doc) { + + Element stateElement = doc.createElement(Tags.TIMED_STATE); + super.fillElement(stateElement); + SortedSet> values = this.state.getTimeEvolution().getValues(); + for (ITimeValue timeValue : values) { + Long time = timeValue.getTime(); + StringSetValue stringSetValue = timeValue.getValue(); + + Set value = stringSetValue.getValue(); + StringBuilder sb = new StringBuilder(); + Iterator iter = value.iterator(); + while (iter.hasNext()) { + sb.append(iter.next().getString()); + if (iter.hasNext()) { + sb.append(", "); + } + } + String valueAsString = sb.toString(); + + Element valueElem = doc.createElement(Tags.VALUE); + valueElem.setAttribute(Tags.TIME, time.toString()); + valueElem.setAttribute(Tags.VALUE, valueAsString); + stateElement.appendChild(valueElem); + } + + return stateElement; + } + + @Override + public String getType() { + return TYPE; + } + + @Override + public StrolchElement getClone() { + StringSetTimedState clone = new StringSetTimedState(); + fillClone(clone); + return clone; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/StrolchTimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/StrolchTimedState.java new file mode 100644 index 000000000..1b7942ddb --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/StrolchTimedState.java @@ -0,0 +1,116 @@ +/* + * 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.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 + */ +@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); + + public > void applyChange(U change); + + public ITimeValue getStateAt(Long time); + + public ITimeVariable getTimeEvolution(); + + public void setParent(Resource aThis); + + public U accept(TimedStateVisitor visitor); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timedstate/TimedState.java b/li.strolch.model/src/main/java/li/strolch/model/timedstate/TimedState.java new file mode 100644 index 000000000..23f9fbdf8 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timedstate/TimedState.java @@ -0,0 +1,87 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timedstate; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +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.timevalue.impl.TimeVariable; + +/** + * @author Martin Smock + */ +@SuppressWarnings("rawtypes") +public class TimedState implements ITimedState, Serializable { + + private static final long serialVersionUID = 1L; + + private ITimeVariable timeVariable = new TimeVariable(); + + @Override + @SuppressWarnings("unchecked") + public ITimeValue getNextMatch(final Long time, final T value) { + Collection> futureValues = this.timeVariable.getFutureValues(time); + for (ITimeValue iTimeValue : futureValues) { + if (iTimeValue.getValue().matches(value)) { + return iTimeValue; + } + } + return null; + } + + @Override + @SuppressWarnings("unchecked") + public ITimeValue getPreviousMatch(final Long time, final T value) { + Collection> pastValues = this.timeVariable.getPastValues(time); + List> asList = new ArrayList>(pastValues); + Collections.reverse(asList); + for (ITimeValue iTimeValue : asList) { + if (iTimeValue.getValue().matches(value)) { + return iTimeValue; + } + } + return null; + } + + @Override + public > void applyChange(U change) { + this.timeVariable.applyChange(change); + } + + @Override + public ITimeValue getStateAt(final Long time) { + return this.timeVariable.getValueAt(time); + } + + @Override + public ITimeVariable getTimeEvolution() { + return this.timeVariable; + } + + @Override + public ITimedState getCopy() { + TimedState copy = new TimedState<>(); + copy.timeVariable = this.timeVariable.getCopy(); + return copy; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/ITimeValue.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/ITimeValue.java new file mode 100644 index 000000000..32f0478e7 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/ITimeValue.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +import li.strolch.model.timevalue.impl.TimeVariable; + +/** + * Interface for timed value objects to be used with the {@link TimeVariable} + * + * @author Martin Smock + * + * @param + * the backing value of the timed value object + */ +@SuppressWarnings("rawtypes") +public interface ITimeValue extends Comparable> { + + ITimeValue setValue(final T value); + + T getValue(); + + Long getTime(); + + ITimeValue add(final T change); + + ITimeValue getCopy(); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/ITimeVariable.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/ITimeVariable.java new file mode 100644 index 000000000..d3e68b804 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/ITimeVariable.java @@ -0,0 +1,91 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +import java.util.Collection; +import java.util.SortedSet; + +/** + * A timed variable storing a ordered sequence of {@link ITimeValue} objects modeling a time evolution of a quantity. + * + * @author Martin Smock + * + * @param + * the backing value of the timed value object + */ +@SuppressWarnings("rawtypes") +public interface ITimeVariable { + + /** + * set the value at a point in time to a given time value object + * + * @param time + * the time to set the {@link IValue} + * @param value + * the {@link IValue} to set + */ + void setValueAt(final Long time, final T value); + + /** + * get the latest {@link ITimeValue} whose time field is less or equal to the time given + */ + ITimeValue getValueAt(final Long time); + + /** + * Applies a {@link IValueChange} propagating the change to all future values starting from the time of the change. + * + * @param change + * the {@link IValueChange} to be applied + */ + void applyChange(final IValueChange change); + + /** + * Get all {@link ITimeValue} objects whose time field is greater or equal to the given time + * + * @param time + * the time the sequence starts with + * @return the sequence of {@link ITimeValue} objects in the future + */ + Collection> getFutureValues(final Long time); + + /** + * Get all {@link ITimeValue} objects whose time field is strictly smaller than the given time + * + * @param time + * the time the sequence starts with + * @return the sequence of {@link ITimeValue} objects in the future + */ + Collection> getPastValues(final Long time); + + /** + * Get all {@link ITimeValue} objects + * + * @return a defensive copy of the {@link ITimeValue}s + */ + SortedSet> getValues(); + + /** + * removes {@link ITimeValue} objects from the sequence, where the successor matches value. I.e considering a pair + * of adjacent {@link ITimeValue} objects in the sequence which have the same {@link IValue}, the later one is + * removed, since it contains no additional information. + */ + void compact(); + + /** + * @return a copy of this time variable + */ + ITimeVariable getCopy(); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/IValue.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/IValue.java new file mode 100644 index 000000000..2c33a262d --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/IValue.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +/** + * A value object defining some basic algebraic operations. Mathematically speaking {@link IValue} objects define a + * group with a addition operation. + * + * @author Martin Smock + * + * @param + * any object for which a (generalized) add operation can be defined. + */ +public interface IValue { + + /** + * @return the backing value + */ + T getValue(); + + /** + * @return a value with the backing value added to the argument value + */ + IValue add(T o); + + /** + * @return true, if the backing values match. + */ + boolean matches(IValue other); + + /** + * @return the inverse value, such that add(value.getInverse()) returns the neutral element of the group + */ + IValue getInverse(); + + /** + * @return a copy of this + */ + IValue getCopy(); + + /** + * @return this value in string representation + */ + String getValueAsString(); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/IValueChange.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/IValueChange.java new file mode 100644 index 000000000..3821f7913 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/IValueChange.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +/** + * Interface for operators to be used to change the values of {@link ITimeValue} in a {@link ITimeVariable}. + * + * @author Martin Smock + */ +@SuppressWarnings("rawtypes") +public interface IValueChange { + + /** + * @return the time this change has to be applied + */ + Long getTime(); + + /** + * @return the value of the change + */ + T getValue(); + + /** + * @return the inverse neutralizing a change. Very useful to undo changes applied. + */ + IValueChange getInverse(); + +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/AString.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/AString.java new file mode 100644 index 000000000..fc2835b74 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/AString.java @@ -0,0 +1,106 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.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. + * + * @author Martin Smock + */ +public class AString implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String string; + 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; + } + + public String getString() { + return this.string; + } + + public boolean isInverse() { + return this.inverse; + } + + public AString getInverse() { + return new AString(this.string, !this.inverse); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (this.inverse ? 1231 : 1237); + result = prime * result + ((this.string == null) ? 0 : this.string.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + AString other = (AString) obj; + if (this.inverse != other.inverse) { + return false; + } + if (this.string == null) { + if (other.string != null) { + return false; + } + } else if (!this.string.equals(other.string)) { + return false; + } + return true; + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("AString [string="); + sb.append(this.string); + sb.append(", inverse="); + sb.append(this.inverse); + sb.append("]"); + return sb.toString(); + } + +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/BooleanValue.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/BooleanValue.java new file mode 100644 index 000000000..4e00f603c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/BooleanValue.java @@ -0,0 +1,118 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue.impl; + +import java.io.Serializable; + +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.IValue; + +/** + * {@link IValue} implementation to work with Boolean valued {@link ITimeValue} objects + * + * @author Martin Smock + */ +public class BooleanValue implements IValue, Serializable { + + private static final long serialVersionUID = 1L; + + public static final BooleanValue NEUTRAL = new BooleanValue(false); + + private Boolean value; + + public BooleanValue(Boolean value) { + this.value = value; + } + + public BooleanValue(boolean value) { + this.value = Boolean.valueOf(value); + } + + public BooleanValue(String valueAsString) throws NumberFormatException { + this.value = Boolean.parseBoolean(valueAsString); + } + + @Override + public BooleanValue add(Boolean o) { + this.value = o; + return this; + } + + @Override + public boolean matches(IValue other) { + return this.value.equals(other.getValue()); + } + + @Override + public Boolean getValue() { + return this.value; + } + + @Override + public BooleanValue getInverse() { + return new BooleanValue(!getValue()); + } + + @Override + public String getValueAsString() { + return this.value.toString(); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("BooleanValue [value="); + sb.append(this.value); + sb.append("]"); + return sb.toString(); + } + + @Override + public BooleanValue getCopy() { + return new BooleanValue(this.value); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.value == null) ? 0 : this.value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + BooleanValue other = (BooleanValue) obj; + if (this.value == null) { + if (other.value != null) { + return false; + } + } else if (!this.value.equals(other.value)) { + return false; + } + return true; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/FloatValue.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/FloatValue.java new file mode 100644 index 000000000..deaddc02d --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/FloatValue.java @@ -0,0 +1,127 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue.impl; + +import java.io.Serializable; + +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.IValue; + +/** + * {@link IValue} implementation to work with Double valued {@link ITimeValue} objects + * + * @author Martin Smock + */ +public class FloatValue implements IValue, Serializable { + + private static final long serialVersionUID = 1L; + + public static final FloatValue NEUTRAL = new FloatValue(0.0d); + + private Double value; + + public FloatValue(Double value) { + this.value = value; + } + + public FloatValue(double value) { + this.value = Double.valueOf(value); + } + + public FloatValue(Integer value) { + this.value = this.value.doubleValue(); + } + + public FloatValue(int value) { + this.value = Integer.valueOf(value).doubleValue(); + } + + public FloatValue(String valueAsString) throws NumberFormatException { + this.value = Double.parseDouble(valueAsString); + } + + @Override + public FloatValue add(Double o) { + this.value += o; + return this; + } + + @Override + public Double getValue() { + return this.value; + } + + @Override + public String getValueAsString() { + return this.value.toString(); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("DoubleValue [value="); + sb.append(this.value); + sb.append("]"); + return sb.toString(); + } + + @Override + public boolean matches(IValue other) { + return this.value.equals(other.getValue()); + } + + @Override + public FloatValue getInverse() { + return new FloatValue(-getValue()); + } + + @Override + public FloatValue getCopy() { + return new FloatValue(this.value); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.value == null) ? 0 : this.value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + FloatValue other = (FloatValue) obj; + if (this.value == null) { + if (other.value != null) { + return false; + } + } else if (!this.value.equals(other.value)) { + return false; + } + return true; + } + +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/IntegerValue.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/IntegerValue.java new file mode 100644 index 000000000..c1476273f --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/IntegerValue.java @@ -0,0 +1,119 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue.impl; + +import java.io.Serializable; + +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.IValue; + +/** + * {@link IValue} implementation to work with Integer valued {@link ITimeValue} objects + * + * @author Martin Smock + */ +public class IntegerValue implements IValue, Serializable { + + private static final long serialVersionUID = 1L; + + public static final IntegerValue NEUTRAL = new IntegerValue(0); + + private Integer value; + + public IntegerValue(Integer value) { + this.value = value; + } + + public IntegerValue(int value) { + this.value = Integer.valueOf(value); + } + + public IntegerValue(String valueAsString) throws NumberFormatException { + this.value = Integer.parseInt(valueAsString); + } + + @Override + public IntegerValue add(Integer o) { + this.value += o; + return this; + } + + @Override + public boolean matches(IValue other) { + return this.value.equals(other.getValue()); + } + + @Override + public Integer getValue() { + return this.value; + } + + @Override + public IntegerValue getInverse() { + return new IntegerValue(-getValue()); + } + + @Override + public String getValueAsString() { + return this.value.toString(); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("IntegerValue [value="); + sb.append(this.value); + sb.append("]"); + return sb.toString(); + } + + @Override + public IntegerValue getCopy() { + return new IntegerValue(this.value); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.value == null) ? 0 : this.value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + IntegerValue other = (IntegerValue) obj; + if (this.value == null) { + if (other.value != null) { + return false; + } + } else if (!this.value.equals(other.value)) { + return false; + } + return true; + } + +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/StringSetValue.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/StringSetValue.java new file mode 100644 index 000000000..e17c590c7 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/StringSetValue.java @@ -0,0 +1,131 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue.impl; + +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 + * does not define a inverse, a algebraic {@link AString} wrapper is used. + * + * @author Martin Smock + */ +public class StringSetValue implements IValue>, Serializable { + + private static final long serialVersionUID = 1L; + + private static Set neu = Collections.emptySet(); + public static final IValue> NEUTRAL = new StringSetValue(neu); + + private Set aStrings = new HashSet<>(); + + public StringSetValue() { + } + + public StringSetValue(final Set aStrings) { + DBC.PRE.assertNotNull("Value may not be null!", aStrings); + this.aStrings = aStrings; + } + + @Override + public Set getValue() { + return this.aStrings; + } + + @Override + public IValue> add(Set o) { + + Set toBeAdded = new HashSet<>(o); + + for (Iterator iter1 = toBeAdded.iterator(); iter1.hasNext();) { + AString toAdd = iter1.next(); + if (StringHelper.isEmpty(toAdd.getString())) { + throw new StrolchException("StringSetValue may not contain null values in set!"); + } + + for (Iterator iter = this.aStrings.iterator(); iter.hasNext();) { + AString aString = iter.next(); + boolean valueMatch = aString.getString().equals(toAdd.getString()); + boolean compensate = (toAdd.isInverse() && !aString.isInverse()) + || (!toAdd.isInverse() && aString.isInverse()); + if (valueMatch && compensate) { + iter.remove(); + iter1.remove(); + } + } + } + this.aStrings.addAll(toBeAdded); + return this; + } + + @Override + public boolean matches(IValue> other) { + return getValue().equals(other.getValue()); + } + + @Override + public StringSetValue getInverse() { + Set inverseSet = new HashSet<>(); + for (AString as : this.aStrings) { + inverseSet.add(as.getInverse()); + } + StringSetValue inverse = new StringSetValue(); + inverse.aStrings = inverseSet; + return inverse; + } + + @Override + public StringSetValue getCopy() { + 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 = this.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(getValueAsString()); + sb.append("]"); + return sb.toString(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/TimeValue.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/TimeValue.java new file mode 100644 index 000000000..3ffec7a36 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/TimeValue.java @@ -0,0 +1,128 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue.impl; + +import java.io.Serializable; + +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.IValue; + +/** + * @author Martin Smock + */ +@SuppressWarnings("rawtypes") +public class TimeValue implements ITimeValue, Serializable { + + private static final long serialVersionUID = 1L; + + protected final Long time; + protected T value; + + /** + * @param time + * @param value + */ + public TimeValue(final Long time, final T value) { + this.time = time; + this.value = value; + } + + @Override + @SuppressWarnings("unchecked") + public T getValue() { + return (T) this.value.getCopy(); + } + + @Override + public Long getTime() { + return this.time; + } + + @Override + public ITimeValue setValue(final T value) { + this.value = value; + return this; + } + + @SuppressWarnings("unchecked") + @Override + public ITimeValue add(final T change) { + this.value.add(change.getValue()); + return this; + } + + @Override + public int compareTo(final ITimeValue arg0) { + return this.getTime().compareTo(arg0.getTime()); + } + + @SuppressWarnings("unchecked") + @Override + public ITimeValue getCopy() { + return new TimeValue(this.time, (T) this.value.getCopy()); + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("TimeValue [time="); + sb.append(this.time); + sb.append(", value="); + sb.append(this.value); + sb.append("]"); + return sb.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.time == null) ? 0 : this.time.hashCode()); + result = prime * result + ((this.value == null) ? 0 : this.value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + @SuppressWarnings("unchecked") + TimeValue other = (TimeValue) obj; + if (this.time == null) { + if (other.time != null) { + return false; + } + } else if (!this.time.equals(other.time)) { + return false; + } + if (this.value == null) { + if (other.value != null) { + return false; + } + } else if (!this.value.equals(other.value)) { + return false; + } + return true; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/TimeVariable.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/TimeVariable.java new file mode 100644 index 000000000..97c90cc97 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/TimeVariable.java @@ -0,0 +1,130 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue.impl; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; +import java.util.SortedSet; +import java.util.TreeSet; + +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.ITimeVariable; +import li.strolch.model.timevalue.IValue; +import li.strolch.model.timevalue.IValueChange; + +/** + * @author Martin Smock + */ +@SuppressWarnings("rawtypes") +public class TimeVariable implements ITimeVariable, Serializable { + + private static final long serialVersionUID = 1L; + + public SortedSet> container = new TreeSet>(); + + @Override + public ITimeValue getValueAt(final Long time) { + ITimeValue tmp = null; + for (ITimeValue value : this.container) { + if (value.getTime() <= time) { + tmp = value; + } else { + break; + } + } + return tmp; + } + + @Override + public void setValueAt(final Long time, final T targetValue) { + ITimeValue current = getValueAt(time); + if (current != null && current.getTime().equals(time)) { + current.setValue(targetValue); + } else { + this.container.add(new TimeValue(time, targetValue)); + } + } + + @Override + public SortedSet> getFutureValues(final Long time) { + TimeValue picker = new TimeValue(time, null); + return new TreeSet>(this.container.tailSet(picker)); + } + + @Override + public Collection> getPastValues(final Long time) { + TimeValue picker = new TimeValue(time, null); + return new TreeSet>(this.container.headSet(picker)); + } + + @Override + public SortedSet> getValues() { + return new TreeSet>(this.container); + } + + @Override + public void applyChange(final IValueChange change) { + + SortedSet> futureValues = getFutureValues(change.getTime()); + for (ITimeValue value : futureValues) { + value.add(change.getValue()); + } + + ITimeValue initialValue = getValueAt(change.getTime()); + if (initialValue == null) { + ITimeValue newValue = new TimeValue(change.getTime(), change.getValue()); + this.container.add(newValue); + } else if (initialValue.getTime().longValue() < change.getTime().longValue()) { + ITimeValue newValue = new TimeValue(change.getTime(), initialValue.getValue()); + newValue.add(change.getValue()); + this.container.add(newValue); + } + + compact(); + } + + @SuppressWarnings("unchecked") + @Override + public void compact() { + + if (this.container.size() < 2) { + return; + } + + Iterator> iterator = this.container.iterator(); + ITimeValue predecessor = iterator.next(); + + while (iterator.hasNext()) { + ITimeValue successor = iterator.next(); + if (successor.getValue().matches(predecessor.getValue())) { + iterator.remove(); + } else { + predecessor = successor; + } + } + } + + @Override + public ITimeVariable getCopy() { + TimeVariable clone = new TimeVariable<>(); + for (ITimeValue timeValue : this.container) { + clone.container.add(timeValue.getCopy()); + } + + return clone; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/ValueChange.java b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/ValueChange.java new file mode 100644 index 000000000..c3e439df4 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/timevalue/impl/ValueChange.java @@ -0,0 +1,110 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue.impl; + +import java.io.Serializable; + +import li.strolch.model.timevalue.IValue; +import li.strolch.model.timevalue.IValueChange; + +/** + * @author Martin Smock + */ +@SuppressWarnings("rawtypes") +public class ValueChange implements IValueChange, Serializable { + + private static final long serialVersionUID = 1L; + + protected final Long time; + protected final T value; + + /** + * @param time + * @param value + */ + public ValueChange(final Long time, final T value) { + this.time = time; + this.value = value; + } + + @Override + public Long getTime() { + return this.time; + } + + @Override + @SuppressWarnings("unchecked") + public T getValue() { + return (T) this.value.getCopy(); + } + + @Override + @SuppressWarnings("unchecked") + public IValueChange getInverse() { + return new ValueChange(this.time, this.value.getInverse()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ValueChange other = (ValueChange) obj; + if (this.time == null) { + if (other.time != null) { + return false; + } + } else if (!this.time.equals(other.time)) { + return false; + } + if (this.value == null) { + if (other.value != null) { + return false; + } + } else if (!this.value.equals(other.value)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.time == null) ? 0 : this.time.hashCode()); + result = prime * result + ((this.value == null) ? 0 : this.value.hashCode()); + return result; + } + + @SuppressWarnings("nls") + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("ValueChange [time="); + sb.append(this.time); + sb.append(", value="); + sb.append(this.value); + sb.append("]"); + return sb.toString(); + } + +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/ElementTypeVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/ElementTypeVisitor.java new file mode 100644 index 000000000..74a8621e3 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/ElementTypeVisitor.java @@ -0,0 +1,36 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import li.strolch.model.Order; +import li.strolch.model.Resource; +import li.strolch.model.Tags; + +/** + * @author Robert von Burg + */ +public class ElementTypeVisitor implements StrolchRootElementVisitor { + + @Override + public String visitOrder(Order order) { + return Tags.ORDER; + } + + @Override + public String visitResource(Resource resource) { + return Tags.RESOURCE; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyOrderVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyOrderVisitor.java new file mode 100644 index 000000000..df168fb8b --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyOrderVisitor.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import li.strolch.model.Order; +import li.strolch.model.OrderVisitor; + +/** + * @author Robert von Burg + */ +public class NoStrategyOrderVisitor implements OrderVisitor { + + @Override + public Order visit(Order element) { + return element; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyResourceVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyResourceVisitor.java new file mode 100644 index 000000000..d319aa7b9 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyResourceVisitor.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import li.strolch.model.Resource; +import li.strolch.model.ResourceVisitor; + +/** + * @author Robert von Burg + */ +public class NoStrategyResourceVisitor implements ResourceVisitor { + + @Override + public Resource visit(Resource element) { + return element; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyVisitor.java new file mode 100644 index 000000000..050cf634a --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/NoStrategyVisitor.java @@ -0,0 +1,29 @@ +/* + * 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.StrolchElement; + +/** + * @author Robert von Burg + */ +public class NoStrategyVisitor implements StrolchElementVisitor { + + @Override + public T visit(T element) { + return element; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/OrderDeepEqualsVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/OrderDeepEqualsVisitor.java new file mode 100644 index 000000000..f6c727c44 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/OrderDeepEqualsVisitor.java @@ -0,0 +1,40 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import java.util.List; + +import li.strolch.model.Locator; +import li.strolch.model.Order; +import li.strolch.model.OrderVisitor; + +/** + * @author Robert von Burg + */ +public class OrderDeepEqualsVisitor extends StrolchElementDeepEqualsVisitor implements OrderVisitor> { + + private Order srcOrder; + + public OrderDeepEqualsVisitor(Order srcOrder) { + this.srcOrder = srcOrder; + } + + @Override + public List visit(Order dstOrder) { + deepEquals(this.srcOrder, dstOrder); + return getMismatchedLocators(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/ParameterVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/ParameterVisitor.java new file mode 100644 index 000000000..a4a914849 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/ParameterVisitor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import li.strolch.model.parameter.BooleanParameter; +import li.strolch.model.parameter.DateParameter; +import li.strolch.model.parameter.FloatParameter; +import li.strolch.model.parameter.IntegerParameter; +import li.strolch.model.parameter.ListParameter; +import li.strolch.model.parameter.LongParameter; +import li.strolch.model.parameter.Parameter; +import li.strolch.model.parameter.StringListParameter; +import li.strolch.model.parameter.StringParameter; + +/** + * @author Robert von Burg + */ +public interface ParameterVisitor { + + public T visitParam(Parameter param); + + public T visitBooleanParam(BooleanParameter param); + + public T visitDateParam(DateParameter param); + + public T visitFloatParam(FloatParameter param); + + public T visitIntegerParam(IntegerParameter param); + + public T visitLongParam(LongParameter param); + + public T visitStringParam(StringParameter param); + + public T visitListParam(ListParameter param); + + public T visitStringListParam(StringListParameter param); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/ResourceDeepEqualsVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/ResourceDeepEqualsVisitor.java new file mode 100644 index 000000000..de4213494 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/ResourceDeepEqualsVisitor.java @@ -0,0 +1,41 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import java.util.List; + +import li.strolch.model.Locator; +import li.strolch.model.Resource; +import li.strolch.model.ResourceVisitor; + +/** + * @author Robert von Burg + */ +public class ResourceDeepEqualsVisitor extends StrolchElementDeepEqualsVisitor implements + ResourceVisitor> { + + private Resource srcRes; + + public ResourceDeepEqualsVisitor(Resource sourceRes) { + this.srcRes = sourceRes; + } + + @Override + public List visit(Resource dstRes) { + deepEquals(this.srcRes, dstRes); + return getMismatchedLocators(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/SetParameterValueVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/SetParameterValueVisitor.java new file mode 100644 index 000000000..c31bd6718 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/SetParameterValueVisitor.java @@ -0,0 +1,96 @@ +/* + * 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.parameter.BooleanParameter; +import li.strolch.model.parameter.DateParameter; +import li.strolch.model.parameter.FloatParameter; +import li.strolch.model.parameter.IntegerParameter; +import li.strolch.model.parameter.ListParameter; +import li.strolch.model.parameter.LongParameter; +import li.strolch.model.parameter.Parameter; +import li.strolch.model.parameter.StringListParameter; +import li.strolch.model.parameter.StringParameter; + +/** + * @author Robert von Burg + */ +public class SetParameterValueVisitor implements ParameterVisitor { + + private String value; + + public void setValue(Parameter parameter, String value) { + this.value = value; + try { + parameter.accept(this); + } finally { + this.value = null; + } + } + + @Override + public T visitParam(Parameter param) { + throw new UnsupportedOperationException("Not implemented on " + param.getClass()); + } + + @Override + public T visitListParam(ListParameter param) { + throw new UnsupportedOperationException("Not implemented on " + param.getClass()); + } + + @Override + public T visitBooleanParam(BooleanParameter param) { + param.setValue(BooleanParameter.parseFromString(this.value)); + return null; + } + + @Override + public T visitDateParam(DateParameter param) { + param.setValue(DateParameter.parseFromString(this.value)); + return null; + } + + @Override + public T visitFloatParam(FloatParameter param) { + param.setValue(FloatParameter.parseFromString(this.value)); + return null; + } + + @Override + public T visitIntegerParam(IntegerParameter param) { + param.setValue(IntegerParameter.parseFromString(this.value)); + return null; + } + + @Override + public T visitLongParam(LongParameter param) { + param.setValue(LongParameter.parseFromString(this.value)); + return null; + } + + @Override + public T visitStringParam(StringParameter param) { + param.setValue(this.value); + return null; + } + + @Override + public T visitStringListParam(StringListParameter param) { + param.setValue(StringListParameter.parseFromString(this.value)); + return null; + } + +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java new file mode 100644 index 000000000..2e8b1b038 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchElementDeepEqualsVisitor.java @@ -0,0 +1,190 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import li.strolch.model.GroupedParameterizedElement; +import li.strolch.model.Locator; +import li.strolch.model.Order; +import li.strolch.model.ParameterBag; +import li.strolch.model.Resource; +import li.strolch.model.StrolchElement; +import li.strolch.model.parameter.Parameter; +import li.strolch.model.timedstate.StrolchTimedState; +import li.strolch.model.timevalue.ITimeVariable; + +/** + * @author Robert von Burg + * + */ +public class StrolchElementDeepEqualsVisitor { + + private List mismatchedLocators; + + public StrolchElementDeepEqualsVisitor() { + this.mismatchedLocators = new ArrayList<>(); + } + + /** + * @return the mismatchedLocators + */ + public List getMismatchedLocators() { + return this.mismatchedLocators; + } + + public boolean isEqual() { + return this.mismatchedLocators.isEmpty(); + } + + protected void deepEquals(StrolchElement srcElement, StrolchElement dstElement) { + if (!srcElement.getName().equals(dstElement.getName())) { + this.mismatchedLocators.add(dstElement.getLocator()); + } + if (!srcElement.getType().equals(dstElement.getType())) { + this.mismatchedLocators.add(dstElement.getLocator()); + } + } + + protected void deepEquals(Order srcOrder, Order dstOrder) { + deepEquals((StrolchElement) srcOrder, (StrolchElement) dstOrder); + if (!srcOrder.getState().equals(dstOrder.getState())) { + this.mismatchedLocators.add(dstOrder.getLocator()); + } + if (!srcOrder.getDate().equals(dstOrder.getDate())) { + this.mismatchedLocators.add(dstOrder.getLocator()); + } + + deepEquals((GroupedParameterizedElement) srcOrder, (GroupedParameterizedElement) dstOrder); + } + + protected void deepEquals(Resource srcRes, Resource dstRes) { + deepEquals((StrolchElement) srcRes, (StrolchElement) dstRes); + deepEquals((GroupedParameterizedElement) srcRes, (GroupedParameterizedElement) dstRes); + + Set srcTimedStateKeySet = srcRes.getTimedStateKeySet(); + for (String timedStateKey : srcTimedStateKeySet) { + StrolchTimedState srcTimedState = srcRes.getTimedState(timedStateKey); + + if (!dstRes.hasTimedState(timedStateKey)) { + this.mismatchedLocators.add(srcTimedState.getLocator()); + continue; + } + + 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); + this.mismatchedLocators.add(dstTimedState.getLocator()); + } + } + } + + protected void deepEquals(GroupedParameterizedElement srcElement, GroupedParameterizedElement dstElement) { + Set srcBagKeySet = srcElement.getParameterBagKeySet(); + for (String bagKey : srcBagKeySet) { + ParameterBag srcBag = srcElement.getParameterBag(bagKey); + + if (!dstElement.hasParameterBag(bagKey)) { + this.mismatchedLocators.add(srcBag.getLocator()); + continue; + } + + ParameterBag dstBag = dstElement.getParameterBag(bagKey); + deepEquals(srcBag, dstBag); + } + + Set dstBagKeySet = dstElement.getParameterBagKeySet(); + for (String bagKey : dstBagKeySet) { + if (!srcElement.hasParameterBag(bagKey)) { + ParameterBag dstBag = dstElement.getParameterBag(bagKey); + this.mismatchedLocators.add(dstBag.getLocator()); + } + } + } + + protected void deepEquals(ParameterBag srcBag, ParameterBag dstBag) { + deepEquals((StrolchElement) srcBag, (StrolchElement) dstBag); + + Set srcParamKeySet = srcBag.getParameterKeySet(); + for (String paramKey : srcParamKeySet) { + Parameter srcParam = srcBag.getParameter(paramKey); + if (!dstBag.hasParameter(paramKey)) { + this.mismatchedLocators.add(srcParam.getLocator()); + continue; + } + + Parameter dstParam = dstBag.getParameter(paramKey); + deepEquals(srcParam, dstParam); + } + + Set dstParamKeySet = dstBag.getParameterKeySet(); + for (String paramKey : dstParamKeySet) { + if (!srcBag.hasParameter(paramKey)) { + Parameter dstParam = dstBag.getParameter(paramKey); + this.mismatchedLocators.add(dstParam.getLocator()); + } + } + } + + protected void deepEquals(Parameter srcParam, Parameter dstParam) { + deepEquals((StrolchElement) srcParam, (StrolchElement) dstParam); + if (!srcParam.getUom().equals(dstParam.getUom())) { + this.mismatchedLocators.add(dstParam.getLocator()); + } + if (!srcParam.getInterpretation().equals(dstParam.getInterpretation())) { + this.mismatchedLocators.add(dstParam.getLocator()); + } + if (srcParam.isHidden() != dstParam.isHidden()) { + this.mismatchedLocators.add(dstParam.getLocator()); + } + if (srcParam.getIndex() != dstParam.getIndex()) { + this.mismatchedLocators.add(dstParam.getLocator()); + } + + if (!srcParam.getValue().equals(dstParam.getValue())) { + this.mismatchedLocators.add(dstParam.getLocator()); + } + } + + protected void deepEquals(StrolchTimedState srcState, StrolchTimedState dstState) { + deepEquals((StrolchElement) srcState, (StrolchElement) dstState); + final ITimeVariable srcTimeEvolution = srcState.getTimeEvolution(); + final ITimeVariable dstTimeEvolution = dstState.getTimeEvolution(); + + if (!srcTimeEvolution.getValues().equals(dstTimeEvolution.getValues())) { + this.mismatchedLocators.add(dstState.getLocator()); + } + } + + public static boolean isEqual(Order srcOrder, Order dstOrder) { + OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(srcOrder); + visitor.visit(dstOrder); + return visitor.isEqual(); + } + + public static boolean isEqual(Resource srcRes, Resource dstRes) { + ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); + visitor.visit(dstRes); + return visitor.isEqual(); + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchElementVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchElementVisitor.java new file mode 100644 index 000000000..30d23ba9b --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchElementVisitor.java @@ -0,0 +1,26 @@ +/* + * 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.StrolchElement; + +/** + * @author Robert von Burg + */ +public interface StrolchElementVisitor extends StrolchVisitor { + + public U visit(T element); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchRootElementVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchRootElementVisitor.java new file mode 100644 index 000000000..d24cbebd9 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchRootElementVisitor.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.visitor; + +import li.strolch.model.Order; +import li.strolch.model.Resource; + +/** + * @author Robert von Burg + */ +public interface StrolchRootElementVisitor extends StrolchVisitor { + + public T visitOrder(Order order); + + public T visitResource(Resource resource); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchVisitor.java new file mode 100644 index 000000000..f3988cb16 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/visitor/StrolchVisitor.java @@ -0,0 +1,26 @@ +/* + * 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; + +/** + * Marker interface to allow to quickly see the visitor implementations in Strolch + * + * @author Robert von Burg + */ +public interface StrolchVisitor { + + // marker interface +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/visitor/TimedStateVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/visitor/TimedStateVisitor.java new file mode 100644 index 000000000..072afc482 --- /dev/null +++ b/li.strolch.model/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/li.strolch.model/src/main/java/li/strolch/model/xml/AbstractToSaxWriterVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/AbstractToSaxWriterVisitor.java new file mode 100644 index 000000000..9f50deaf4 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/AbstractToSaxWriterVisitor.java @@ -0,0 +1,162 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import 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; + +/** + * @author Robert von Burg + */ +public abstract class AbstractToSaxWriterVisitor { + + protected XMLStreamWriter writer; + + public AbstractToSaxWriterVisitor(XMLStreamWriter writer) { + this.writer = writer; + } + + protected void writeElement(String tag, Order order) throws XMLStreamException { + boolean empty = !order.hasParameterBags(); + writeElement(tag, empty, order); + if (!empty) + this.writer.writeEndElement(); + } + + protected void writeElement(String tag, Resource resource) throws XMLStreamException { + boolean empty = !resource.hasParameterBags() && !resource.hasTimedStates(); + writeElement(tag, empty, 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) { + this.writer.writeEmptyElement(Tags.VALUE); + this.writer.writeAttribute(Tags.TIME, timeValue.getTime().toString()); + this.writer.writeAttribute(Tags.VALUE, timeValue.getValue().getValueAsString()); + } + + if (!values.isEmpty()) + this.writer.writeEndElement(); + } + } + + protected void writeElement(String tag, boolean empty, GroupedParameterizedElement element) + throws XMLStreamException { + writeStartStrolchElement(tag, empty, element); + if (!empty) { + writeParameterBags(element); + } + } + + protected void writeStartStrolchElement(String tag, boolean empty, StrolchElement element) + throws XMLStreamException { + if (empty) { + this.writer.writeEmptyElement(tag); + } else { + this.writer.writeStartElement(tag); + } + + this.writer.writeAttribute(Tags.ID, element.getId()); + if (StringHelper.isNotEmpty(element.getName())) { + this.writer.writeAttribute(Tags.NAME, element.getName()); + } + this.writer.writeAttribute(Tags.TYPE, element.getType()); + } + + protected void writeParameterBags(GroupedParameterizedElement element) throws XMLStreamException { + Set bagKeySet = new TreeSet<>(element.getParameterBagKeySet()); + for (String bagKey : bagKeySet) { + ParameterBag parameterBag = element.getParameterBag(bagKey); + boolean isEmpty = !parameterBag.hasParameters(); + writeStartStrolchElement(Tags.PARAMETER_BAG, isEmpty, parameterBag); + if (!isEmpty) { + writeParameters(parameterBag); + this.writer.writeEndElement(); + } + } + } + + 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/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToDomVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToDomVisitor.java new file mode 100644 index 000000000..77c9995aa --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToDomVisitor.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import javax.xml.parsers.DocumentBuilder; + +import li.strolch.model.Order; +import li.strolch.model.OrderVisitor; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.DomUtil; + +/** + * @author Robert von Burg + */ +public class OrderToDomVisitor implements OrderVisitor { + + private Document document; + + /** + * @return the document + */ + public Document getDocument() { + return this.document; + } + + @Override + public Document visit(Order order) { + DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder(); + Document document = documentBuilder.getDOMImplementation().createDocument(null, null, null); + + Element orderDom = order.toDom(document); + document.appendChild(orderDom); + this.document = document; + return this.document; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToSaxVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToSaxVisitor.java new file mode 100644 index 000000000..7911c16d8 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToSaxVisitor.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import java.text.MessageFormat; + +import li.strolch.model.Order; +import li.strolch.model.OrderVisitor; +import li.strolch.model.Tags; + +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +/** + * @author Robert von Burg + */ +public class OrderToSaxVisitor extends StrolchElementToSaxVisitor implements OrderVisitor { + + public OrderToSaxVisitor(ContentHandler contentHandler) { + super(contentHandler); + } + + @Override + public Void visit(Order order) { + try { + + this.contentHandler.startElement(null, null, Tags.ORDER, attributesFor(order)); + toSax(order); + this.contentHandler.endElement(null, null, Tags.ORDER); + + } catch (SAXException e) { + String msg = "Failed to transform Order {0} to XML due to {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, order.getLocator(), e.getMessage()); + throw new RuntimeException(msg, e); + } + + return null; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToSaxWriterVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToSaxWriterVisitor.java new file mode 100644 index 000000000..dc3b16d52 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/OrderToSaxWriterVisitor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import java.text.MessageFormat; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Order; +import li.strolch.model.OrderVisitor; +import li.strolch.model.Tags; + +/** + * @author Robert von Burg + */ +public class OrderToSaxWriterVisitor extends AbstractToSaxWriterVisitor implements OrderVisitor { + + public OrderToSaxWriterVisitor(XMLStreamWriter writer) { + super(writer); + } + + @Override + public Void visit(Order order) { + try { + writeElement(Tags.ORDER, order); + this.writer.flush(); + } catch (XMLStreamException e) { + String msg = "Failed to write Order {0} due to {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, order.getLocator(), e.getMessage()); + throw new StrolchException(msg, e); + } + + return null; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToDomVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToDomVisitor.java new file mode 100644 index 000000000..2942d547c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToDomVisitor.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import javax.xml.parsers.DocumentBuilder; + +import li.strolch.model.Resource; +import li.strolch.model.ResourceVisitor; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import ch.eitchnet.utils.helper.DomUtil; + +/** + * @author Robert von Burg + */ +public class ResourceToDomVisitor implements ResourceVisitor { + + private Document document; + + /** + * @return the document + */ + public Document getDocument() { + return this.document; + } + + @Override + public Document visit(Resource resource) { + DocumentBuilder documentBuilder = DomUtil.createDocumentBuilder(); + Document document = documentBuilder.getDOMImplementation().createDocument(null, null, null); + + Element resourceDom = resource.toDom(document); + document.appendChild(resourceDom); + this.document = document; + return this.document; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToSaxVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToSaxVisitor.java new file mode 100644 index 000000000..676ce6a68 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToSaxVisitor.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import java.text.MessageFormat; + +import li.strolch.model.Resource; +import li.strolch.model.ResourceVisitor; +import li.strolch.model.Tags; + +import org.xml.sax.ContentHandler; + +/** + * @author Robert von Burg + */ +public class ResourceToSaxVisitor extends StrolchElementToSaxVisitor implements ResourceVisitor { + + public ResourceToSaxVisitor(ContentHandler contentHandler) { + super(contentHandler); + } + + @Override + public Void visit(Resource res) { + try { + + this.contentHandler.startElement(null, null, Tags.RESOURCE, attributesFor(res)); + toSax(res); + this.contentHandler.endElement(null, null, Tags.RESOURCE); + + } catch (Exception e) { + String msg = "Failed to transform Resource {0} to XML due to {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, res.getLocator(), e.getMessage()); + throw new RuntimeException(msg, e); + } + + return null; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToSaxWriterVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToSaxWriterVisitor.java new file mode 100644 index 000000000..764984a14 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/ResourceToSaxWriterVisitor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import java.text.MessageFormat; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Resource; +import li.strolch.model.ResourceVisitor; +import li.strolch.model.Tags; + +/** + * @author Robert von Burg + */ +public class ResourceToSaxWriterVisitor extends AbstractToSaxWriterVisitor implements ResourceVisitor { + + public ResourceToSaxWriterVisitor(XMLStreamWriter writer) { + super(writer); + } + + @Override + public Void visit(Resource resource) { + try { + writeElement(Tags.RESOURCE, resource); + this.writer.flush(); + } catch (XMLStreamException e) { + String msg = "Failed to write Resource {0} due to {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, resource.getLocator(), e.getMessage()); + throw new StrolchException(msg, e); + } + + return null; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/SimpleStrolchElementListener.java b/li.strolch.model/src/main/java/li/strolch/model/xml/SimpleStrolchElementListener.java new file mode 100644 index 000000000..777fe2a57 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/SimpleStrolchElementListener.java @@ -0,0 +1,61 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import java.util.ArrayList; +import java.util.List; + +import li.strolch.model.Order; +import li.strolch.model.Resource; + +/** + * @author Robert von Burg + */ +public class SimpleStrolchElementListener implements StrolchElementListener { + + private List resources; + private List orders; + + @Override + public void notifyResource(Resource resource) { + if (this.resources == null) { + this.resources = new ArrayList<>(); + } + this.resources.add(resource); + } + + @Override + public void notifyOrder(Order order) { + if (this.orders == null) { + this.orders = new ArrayList<>(); + } + this.orders.add(order); + } + + /** + * @return the resources + */ + public List getResources() { + return this.resources; + } + + /** + * @return the orders + */ + public List getOrders() { + return this.orders; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/StrolchElementListener.java b/li.strolch.model/src/main/java/li/strolch/model/xml/StrolchElementListener.java new file mode 100644 index 000000000..58f1d419c --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/StrolchElementListener.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import li.strolch.model.Order; +import li.strolch.model.Resource; + +/** + * @author Robert von Burg + * + */ +public interface StrolchElementListener { + + public void notifyResource(Resource resource); + + public void notifyOrder(Order order); +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/StrolchElementToSaxVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/xml/StrolchElementToSaxVisitor.java new file mode 100644 index 000000000..6f14e598b --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/StrolchElementToSaxVisitor.java @@ -0,0 +1,99 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import static li.strolch.model.StrolchModelConstants.INTERPRETATION_NONE; +import static li.strolch.model.StrolchModelConstants.UOM_NONE; + +import java.util.Set; + +import li.strolch.model.GroupedParameterizedElement; +import li.strolch.model.Order; +import li.strolch.model.ParameterBag; +import li.strolch.model.StrolchElement; +import li.strolch.model.Tags; +import li.strolch.model.parameter.Parameter; + +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +public abstract class StrolchElementToSaxVisitor { + + protected ContentHandler contentHandler; + + protected StrolchElementToSaxVisitor(ContentHandler contentHandler) { + this.contentHandler = contentHandler; + } + + protected AttributesImpl attributesFor(StrolchElement element) { + AttributesImpl attributes = new AttributesImpl(); + attributes.addAttribute(null, null, Tags.ID, Tags.CDATA, element.getId()); + attributes.addAttribute(null, null, Tags.NAME, Tags.CDATA, element.getName()); + attributes.addAttribute(null, null, Tags.TYPE, Tags.CDATA, element.getType()); + return attributes; + } + + protected AttributesImpl attributesFor(Order order) { + AttributesImpl attributes = attributesFor((StrolchElement) order); + attributes.addAttribute(null, null, Tags.STATE, Tags.CDATA, order.getState().name()); + attributes.addAttribute(null, null, Tags.DATE, Tags.CDATA, + ISO8601FormatFactory.getInstance().formatDate(order.getDate())); + return attributes; + } + + protected AttributesImpl attributesFor(Parameter parameter) { + AttributesImpl attributes = attributesFor((StrolchElement) parameter); + attributes.addAttribute(null, null, Tags.VALUE, Tags.CDATA, parameter.getValueAsString()); + + if (!UOM_NONE.equals(parameter.getUom())) { + attributes.addAttribute(null, null, Tags.UOM, Tags.CDATA, parameter.getUom()); + } + if (!INTERPRETATION_NONE.equals(parameter.getInterpretation())) { + attributes.addAttribute(null, null, Tags.INTERPRETATION, Tags.CDATA, parameter.getInterpretation()); + } + if (parameter.isHidden()) { + attributes.addAttribute(null, null, Tags.HIDDEN, Tags.CDATA, Boolean.toString(parameter.isHidden())); + } + if (parameter.getIndex() != 0) { + attributes.addAttribute(null, null, Tags.INDEX, Tags.CDATA, Integer.toString(parameter.getIndex())); + } + + return attributes; + } + + protected void toSax(GroupedParameterizedElement parameterizedElement) throws SAXException { + Set bagKeySet = parameterizedElement.getParameterBagKeySet(); + for (String bagKey : bagKeySet) { + ParameterBag parameterBag = parameterizedElement.getParameterBag(bagKey); + this.contentHandler.startElement(null, null, Tags.PARAMETER_BAG, attributesFor(parameterBag)); + + Set parameterKeySet = parameterBag.getParameterKeySet(); + for (String paramKey : parameterKeySet) { + Parameter parameter = parameterBag.getParameter(paramKey); + this.contentHandler.startElement(null, null, Tags.PARAMETER, attributesFor(parameter)); + this.contentHandler.endElement(null, null, Tags.PARAMETER); + } + + this.contentHandler.endElement(null, null, Tags.PARAMETER_BAG); + } + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxFileReader.java b/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxFileReader.java new file mode 100644 index 000000000..e87059b6f --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxFileReader.java @@ -0,0 +1,105 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import java.io.File; +import java.io.IOException; +import java.text.MessageFormat; +import java.util.Date; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import li.strolch.exception.StrolchException; +import li.strolch.model.Tags; + +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +public class XmlModelSaxFileReader extends XmlModelSaxReader { + + private File modelFile; + + /** + * @param listener + * @param modelFile + */ + public XmlModelSaxFileReader(StrolchElementListener listener, File modelFile) { + super(listener); + this.modelFile = modelFile; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + + switch (qName) { + + case Tags.INCLUDE_FILE: + + String includeFileS = attributes.getValue(Tags.FILE); + if (StringHelper.isEmpty(includeFileS)) { + throw new IllegalArgumentException(MessageFormat.format( + "The attribute {0} is missing for IncludeFile!", Tags.FILE)); //$NON-NLS-1$ + } + File includeFile = new File(this.modelFile.getParentFile(), includeFileS); + if (!includeFile.exists() || !includeFile.canRead()) { + String msg = "The IncludeFile does not exist, or is not readable. Source model: {0} with IncludeFile: {1}"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, this.modelFile.getName(), includeFileS); + throw new IllegalArgumentException(msg); + } + + XmlModelSaxFileReader handler = new XmlModelSaxFileReader(this.listener, includeFile); + handler.parseFile(); + this.statistics.nrOfOrders += handler.statistics.nrOfOrders; + this.statistics.nrOfResources += handler.statistics.nrOfResources; + + break; + default: + super.startElement(uri, localName, qName, attributes); + } + } + + public void parseFile() { + + try { + long startNanos = System.nanoTime(); + this.statistics.startTime = new Date(); + + SAXParserFactory spf = SAXParserFactory.newInstance(); + SAXParser sp = spf.newSAXParser(); + + sp.parse(this.modelFile, this); + + long endNanos = System.nanoTime(); + this.statistics.durationNanos = endNanos - startNanos; + String msg = "SAX parsed model file {0} took {1}"; //$NON-NLS-1$ + logger.info(MessageFormat.format(msg, this.modelFile.getAbsolutePath(), + StringHelper.formatNanoDuration(this.statistics.durationNanos))); + + } catch (ParserConfigurationException | SAXException | IOException e) { + + String msg = "Parsing failed due to internal error: {0}"; //$NON-NLS-1$ + throw new StrolchException(MessageFormat.format(msg, e.getMessage()), e); + } + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxReader.java b/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxReader.java new file mode 100644 index 000000000..61ea31067 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/xml/XmlModelSaxReader.java @@ -0,0 +1,277 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model.xml; + +import java.text.MessageFormat; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import li.strolch.exception.StrolchException; +import li.strolch.model.GroupedParameterizedElement; +import li.strolch.model.ModelStatistics; +import li.strolch.model.Order; +import li.strolch.model.ParameterBag; +import li.strolch.model.Resource; +import li.strolch.model.State; +import li.strolch.model.Tags; +import li.strolch.model.parameter.BooleanParameter; +import li.strolch.model.parameter.DateParameter; +import li.strolch.model.parameter.FloatParameter; +import li.strolch.model.parameter.IntegerParameter; +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; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import ch.eitchnet.utils.helper.StringHelper; +import ch.eitchnet.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +public class XmlModelSaxReader extends DefaultHandler { + + protected static final Logger logger = LoggerFactory.getLogger(XmlModelSaxReader.class); + + protected StrolchElementListener listener; + protected ModelStatistics statistics; + + private GroupedParameterizedElement parameterizedElement; + private ParameterBag pBag; + private StrolchTimedState> state; + private String stateType; + + public XmlModelSaxReader(StrolchElementListener listener) { + this.listener = listener; + this.statistics = new ModelStatistics(); + } + + /** + * @return the statistics + */ + public ModelStatistics getStatistics() { + return this.statistics; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + + // TODO split each root object into its own file + switch (qName) { + + case Tags.STROLCH_MODEL: + break; + + case Tags.RESOURCE: + + String resId = attributes.getValue(Tags.ID); + String resName = attributes.getValue(Tags.NAME); + String resType = attributes.getValue(Tags.TYPE); + Resource resource = new Resource(resId, resName, resType); + this.parameterizedElement = resource; + break; + + case Tags.ORDER: + String orderId = attributes.getValue(Tags.ID); + String orderName = attributes.getValue(Tags.NAME); + String orderType = attributes.getValue(Tags.TYPE); + String orderDateS = attributes.getValue(Tags.DATE); + String orderStateS = attributes.getValue(Tags.STATE); + Order order = new Order(orderId, orderName, orderType); + if (orderDateS != null) { + Date orderDate = ISO8601FormatFactory.getInstance().getDateFormat().parse(orderDateS); + order.setDate(orderDate); + } + if (orderStateS != null) { + State orderState = State.valueOf(orderStateS); + order.setState(orderState); + } + this.parameterizedElement = order; + break; + + case Tags.PARAMETER_BAG: + String pBagId = attributes.getValue(Tags.ID); + String pBagName = attributes.getValue(Tags.NAME); + String pBagType = attributes.getValue(Tags.TYPE); + ParameterBag pBag = new ParameterBag(pBagId, pBagName, pBagType); + this.pBag = pBag; + this.parameterizedElement.addParameterBag(pBag); + break; + + case Tags.PARAMETER: + String paramId = attributes.getValue(Tags.ID); + String paramName = attributes.getValue(Tags.NAME); + String paramType = attributes.getValue(Tags.TYPE); + String paramValue = attributes.getValue(Tags.VALUE); + String paramHiddenS = attributes.getValue(Tags.HIDDEN); + String paramIndexS = attributes.getValue(Tags.INDEX); + try { + int index = StringHelper.isEmpty(paramIndexS) ? 0 : Integer.valueOf(paramIndexS); + boolean paramHidden = StringHelper.isEmpty(paramHiddenS) ? false : StringHelper + .parseBoolean(paramHiddenS); + String paramUom = attributes.getValue(Tags.UOM); + String paramInterpretation = attributes.getValue(Tags.INTERPRETATION); + Parameter param; + switch (paramType) { + case StringParameter.TYPE: + param = new StringParameter(paramId, paramName, paramValue); + break; + case IntegerParameter.TYPE: + param = new IntegerParameter(paramId, paramName, IntegerParameter.parseFromString(paramValue)); + break; + case BooleanParameter.TYPE: + param = new BooleanParameter(paramId, paramName, BooleanParameter.parseFromString(paramValue)); + break; + case LongParameter.TYPE: + param = new LongParameter(paramId, paramName, LongParameter.parseFromString(paramValue)); + break; + case DateParameter.TYPE: + param = new DateParameter(paramId, paramName, DateParameter.parseFromString(paramValue)); + break; + case StringListParameter.TYPE: + param = new StringListParameter(paramId, paramName, StringListParameter.parseFromString(paramValue)); + break; + case FloatParameter.TYPE: + param = new FloatParameter(paramId, paramName, FloatParameter.parseFromString(paramValue)); + break; + default: + throw new UnsupportedOperationException(MessageFormat.format( + "Parameters of type {0} are not supported!", paramType)); //$NON-NLS-1$ + } + param.setHidden(paramHidden); + param.setUom(paramUom); + param.setInterpretation(paramInterpretation); + param.setIndex(index); + this.pBag.addParameter(param); + } catch (Exception e) { + throw new StrolchException("Failed to instantiate parameter " + paramId + " for bag " + + this.pBag.getLocator() + " due to " + e.getMessage(), e); + } + 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$ + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + + switch (qName) { + case Tags.STROLCH_MODEL: + break; + case Tags.RESOURCE: + this.listener.notifyResource((Resource) this.parameterizedElement); + this.statistics.nrOfResources++; + this.parameterizedElement = null; + break; + case Tags.ORDER: + this.listener.notifyOrder((Order) this.parameterizedElement); + this.statistics.nrOfOrders++; + this.parameterizedElement = null; + break; + case Tags.PARAMETER_BAG: + this.pBag = null; + break; + case Tags.PARAMETER: + break; + case Tags.INCLUDE_FILE: + break; + case Tags.TIMED_STATE: + ((Resource) this.parameterizedElement).addTimedState(this.state); + break; + case Tags.VALUE: + break; + default: + throw new IllegalArgumentException(MessageFormat.format("The element ''{0}'' is unhandled!", qName)); //$NON-NLS-1$ + } + } +} diff --git a/li.strolch.model/src/main/resources/componentVersion.properties b/li.strolch.model/src/main/resources/componentVersion.properties new file mode 100644 index 000000000..1f050160f --- /dev/null +++ b/li.strolch.model/src/main/resources/componentVersion.properties @@ -0,0 +1,6 @@ +groupId=${project.groupId} +artifactId=${project.artifactId} +artifactVersion=${project.version} +scmRevision=r${buildNumber} +scmBranch=${scmBranch} +buildTimestamp=${buildTimestamp} \ No newline at end of file diff --git a/li.strolch.model/src/test/java/li/strolch/model/ModelTest.java b/li.strolch.model/src/test/java/li/strolch/model/ModelTest.java new file mode 100644 index 000000000..ce2fd43f0 --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/ModelTest.java @@ -0,0 +1,249 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import static li.strolch.model.ModelGenerator.BAG_ID; +import static li.strolch.model.ModelGenerator.BAG_NAME; +import static li.strolch.model.ModelGenerator.BAG_TYPE; +import static li.strolch.model.ModelGenerator.PARAM_BOOLEAN_ID; +import static li.strolch.model.ModelGenerator.PARAM_DATE_ID; +import static li.strolch.model.ModelGenerator.PARAM_FLOAT_ID; +import static li.strolch.model.ModelGenerator.PARAM_INTEGER_ID; +import static li.strolch.model.ModelGenerator.PARAM_LIST_STRING_ID; +import static li.strolch.model.ModelGenerator.PARAM_LONG_ID; +import static li.strolch.model.ModelGenerator.PARAM_STRING_ID; +import static li.strolch.model.ModelGenerator.STATE_BOOLEAN_ID; +import static li.strolch.model.ModelGenerator.STATE_BOOLEAN_TIME_0; +import static li.strolch.model.ModelGenerator.STATE_BOOLEAN_TIME_10; +import static li.strolch.model.ModelGenerator.STATE_BOOLEAN_TIME_20; +import static li.strolch.model.ModelGenerator.STATE_BOOLEAN_TIME_30; +import static li.strolch.model.ModelGenerator.STATE_FLOAT_ID; +import static li.strolch.model.ModelGenerator.STATE_FLOAT_TIME_0; +import static li.strolch.model.ModelGenerator.STATE_FLOAT_TIME_10; +import static li.strolch.model.ModelGenerator.STATE_FLOAT_TIME_20; +import static li.strolch.model.ModelGenerator.STATE_FLOAT_TIME_30; +import static li.strolch.model.ModelGenerator.STATE_INTEGER_ID; +import static li.strolch.model.ModelGenerator.STATE_INTEGER_TIME_0; +import static li.strolch.model.ModelGenerator.STATE_INTEGER_TIME_10; +import static li.strolch.model.ModelGenerator.STATE_INTEGER_TIME_20; +import static li.strolch.model.ModelGenerator.STATE_INTEGER_TIME_30; +import static li.strolch.model.ModelGenerator.STATE_STRING_ID; +import static li.strolch.model.ModelGenerator.STATE_STRING_TIME_0; +import static li.strolch.model.ModelGenerator.STATE_STRING_TIME_10; +import static li.strolch.model.ModelGenerator.STATE_STRING_TIME_20; +import static li.strolch.model.ModelGenerator.STATE_STRING_TIME_30; +import static li.strolch.model.ModelGenerator.STATE_TIME_0; +import static li.strolch.model.ModelGenerator.STATE_TIME_10; +import static li.strolch.model.ModelGenerator.STATE_TIME_20; +import static li.strolch.model.ModelGenerator.STATE_TIME_30; +import static li.strolch.model.ModelGenerator.createOrder; +import static li.strolch.model.ModelGenerator.createResource; +import static li.strolch.model.Tags.BAG; +import static li.strolch.model.Tags.ORDER; +import static li.strolch.model.Tags.RESOURCE; +import static li.strolch.model.Tags.STATE; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Date; + +import li.strolch.model.parameter.BooleanParameter; +import li.strolch.model.parameter.DateParameter; +import li.strolch.model.parameter.FloatParameter; +import li.strolch.model.parameter.IntegerParameter; +import li.strolch.model.parameter.LongParameter; +import li.strolch.model.parameter.StringListParameter; +import li.strolch.model.parameter.StringParameter; +import li.strolch.model.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; +import li.strolch.model.visitor.ResourceDeepEqualsVisitor; + +import org.junit.Test; + +@SuppressWarnings("nls") +public class ModelTest { + + @Test + public void shouldCreateResource() { + + Resource resource = createResource("@res01", "Test resource", "MyType"); + ParameterBag bag = resource.getParameterBag(BAG_ID); + validateBag(bag); + validateStates(resource); + } + + @Test + public void shouldCreateOrder() { + + 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 = 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()); + } + + @Test + public void shouldFailDeepResourceEquals1() { + 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(PARAM_FLOAT_ID); + fParam.setValue(23434234.234); + fParam.setName("Ohla"); + ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(srcRes); + visitor.visit(dstRes); + assertFalse("Resource should not be same if param is changed!", visitor.isEqual()); + assertEquals("Three changes should be registered", 3, visitor.getMismatchedLocators().size()); + } + + @Test + public void shouldFailDeepResourceEquals2() { + 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); + visitor.visit(dstRes); + assertFalse("Resource should not be same if param is changed!", visitor.isEqual()); + assertEquals("One change should be registered!", 1, visitor.getMismatchedLocators().size()); + } + + @Test + public void shouldPerformDeepOrderEquals() { + Date date = new Date(); + 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()); + } + + public static void validateBag(ParameterBag bag) { + + assertNotNull(bag); + + 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(PARAM_BOOLEAN_ID); + assertNotNull("Boolean Param missing with id " + PARAM_BOOLEAN_ID, boolParam); + assertEquals(true, boolParam.getValue().booleanValue()); + + 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(PARAM_INTEGER_ID); + assertNotNull("Integer Param missing with id " + PARAM_INTEGER_ID, integerParam); + assertEquals(77, integerParam.getValue().intValue()); + + 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(PARAM_STRING_ID); + assertNotNull("String Param missing with id " + PARAM_STRING_ID, stringParam); + assertEquals("Strolch", stringParam.getValue()); + + 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(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()); + } +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java b/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java new file mode 100644 index 000000000..35f299bb9 --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import li.strolch.model.xml.StrolchElementListener; +import li.strolch.model.xml.XmlModelSaxFileReader; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ch.eitchnet.utils.helper.StringHelper; + +/** + * @author Robert von Burg + * + */ +@SuppressWarnings("nls") +public class XmlModelDefaultHandlerTest { + + private static final Logger logger = LoggerFactory.getLogger(XmlModelDefaultHandlerTest.class); + + @Test + public void shouldParseXmlModelFile() { + + final Map resourceMap = new HashMap<>(); + final Map orderMap = new HashMap<>(); + + File file = new File("src/test/resources/data/StrolchModel.xml"); + StrolchElementListener listener = new StrolchElementListener() { + @Override + public void notifyResource(Resource resource) { + resourceMap.put(resource.getId(), resource); + } + + @Override + public void notifyOrder(Order order) { + orderMap.put(order.getId(), order); + } + }; + XmlModelSaxFileReader handler = new XmlModelSaxFileReader(listener, file); + handler.parseFile(); + + assertEquals(3, resourceMap.size()); + assertEquals(3, orderMap.size()); + + ModelStatistics statistics = handler.getStatistics(); + logger.info("Parsing took " + StringHelper.formatNanoDuration(statistics.durationNanos)); + assertEquals(3, statistics.nrOfOrders); + assertEquals(3, statistics.nrOfResources); + } +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/XmlToDomTest.java b/li.strolch.model/src/test/java/li/strolch/model/XmlToDomTest.java new file mode 100644 index 000000000..ecbd00fa8 --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/XmlToDomTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.model; + +import static org.junit.Assert.assertTrue; +import li.strolch.model.visitor.OrderDeepEqualsVisitor; +import li.strolch.model.visitor.ResourceDeepEqualsVisitor; +import li.strolch.model.xml.OrderToDomVisitor; +import li.strolch.model.xml.ResourceToDomVisitor; + +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * @author Robert von Burg + * + */ +@SuppressWarnings("nls") +public class XmlToDomTest extends ModelTest { + + @Test + public void shouldFormatAndParseOrder() { + + Order order = ModelGenerator.createOrder("@1", "My Order 1", "MyOrder"); + + OrderToDomVisitor domVisitor = new OrderToDomVisitor(); + domVisitor.visit(order); + Document document = domVisitor.getDocument(); + + Element rootElement = document.getDocumentElement(); + Order parsedOrder = new Order(rootElement); + + OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(order); + visitor.visit(parsedOrder); + assertTrue("To DOM and back should equal same Order:\n" + visitor.getMismatchedLocators(), visitor.isEqual()); + } + + @Test + public void shouldFormatAndParseResource() { + + Resource resource = ModelGenerator.createResource("@1", "My Resource 1", "MyResource"); + + ResourceToDomVisitor domVisitor = new ResourceToDomVisitor(); + domVisitor.visit(resource); + Document document = domVisitor.getDocument(); + + Element rootElement = document.getDocumentElement(); + Resource parsedResource = new Resource(rootElement); + + ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(resource); + visitor.visit(parsedResource); + assertTrue("To DOM and back should equal same Resource:\n" + visitor.getMismatchedLocators(), visitor.isEqual()); + } +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/timedstate/StrolchTimedStateTest.java b/li.strolch.model/src/test/java/li/strolch/model/timedstate/StrolchTimedStateTest.java new file mode 100644 index 000000000..1cbd914b3 --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/timedstate/StrolchTimedStateTest.java @@ -0,0 +1,120 @@ +/* + * 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.timedstate; + +import static org.junit.Assert.assertEquals; + +import java.util.HashSet; +import java.util.Set; + +import li.strolch.model.ModelGenerator; +import li.strolch.model.Resource; +import li.strolch.model.timevalue.ITimeValue; +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.junit.Test; + +/** + * @author Robert von Burg + */ +public class StrolchTimedStateTest { + + @Test + public void testFloatState() { + + Resource myRes = ModelGenerator.createResource("@1", "Test With States", "Stated"); + + FloatTimedState floatState = myRes.getTimedState(ModelGenerator.STATE_FLOAT_ID); + ITimeValue valueAt0 = floatState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_0); + assertEquals(ModelGenerator.STATE_FLOAT_TIME_0, valueAt0.getValue().getValue()); + + ITimeValue valueAt10 = floatState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_10); + assertEquals(ModelGenerator.STATE_FLOAT_TIME_10, valueAt10.getValue().getValue()); + + ITimeValue valueAt20 = floatState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_20); + assertEquals(ModelGenerator.STATE_FLOAT_TIME_20, valueAt20.getValue().getValue()); + + ITimeValue valueAt30 = floatState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_30); + assertEquals(ModelGenerator.STATE_FLOAT_TIME_30, valueAt30.getValue().getValue()); + } + + @Test + public void testIntegerState() { + + Resource myRes = ModelGenerator.createResource("@1", "Test With States", "Stated"); + + IntegerTimedState integerState = myRes.getTimedState(ModelGenerator.STATE_INTEGER_ID); + ITimeValue valueAt0 = integerState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_0); + assertEquals(ModelGenerator.STATE_INTEGER_TIME_0, valueAt0.getValue().getValue()); + + ITimeValue valueAt10 = integerState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_10); + assertEquals(ModelGenerator.STATE_INTEGER_TIME_10, valueAt10.getValue().getValue()); + + ITimeValue valueAt20 = integerState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_20); + assertEquals(ModelGenerator.STATE_INTEGER_TIME_20, valueAt20.getValue().getValue()); + + ITimeValue valueAt30 = integerState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_30); + assertEquals(ModelGenerator.STATE_INTEGER_TIME_30, valueAt30.getValue().getValue()); + } + + @Test + public void testBooleanState() { + + Resource myRes = ModelGenerator.createResource("@1", "Test With States", "Stated"); + + BooleanTimedState booleanState = myRes.getTimedState(ModelGenerator.STATE_BOOLEAN_ID); + ITimeValue valueAt0 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_0); + assertEquals(ModelGenerator.STATE_BOOLEAN_TIME_0, valueAt0.getValue().getValue()); + + ITimeValue valueAt10 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_10); + assertEquals(ModelGenerator.STATE_BOOLEAN_TIME_10, valueAt10.getValue().getValue()); + + ITimeValue valueAt20 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_20); + assertEquals(ModelGenerator.STATE_BOOLEAN_TIME_20, valueAt20.getValue().getValue()); + + ITimeValue valueAt30 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_30); + assertEquals(ModelGenerator.STATE_BOOLEAN_TIME_30, valueAt30.getValue().getValue()); + } + + @Test + public void testStringSetState() { + + Resource myRes = ModelGenerator.createResource("@1", "Test With States", "Stated"); + + StringSetTimedState booleanState = myRes.getTimedState(ModelGenerator.STATE_STRING_ID); + ITimeValue valueAt0 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_0); + assertEquals(asSet(ModelGenerator.STATE_STRING_TIME_0), valueAt0.getValue().getValue()); + + ITimeValue valueAt10 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_10); + assertEquals(asSet(ModelGenerator.STATE_STRING_TIME_10), valueAt10.getValue().getValue()); + + ITimeValue valueAt20 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_20); + assertEquals(asSet(ModelGenerator.STATE_STRING_TIME_20), valueAt20.getValue().getValue()); + + ITimeValue valueAt30 = booleanState.getTimeEvolution().getValueAt(ModelGenerator.STATE_TIME_30); + assertEquals(asSet(ModelGenerator.STATE_STRING_TIME_30), valueAt30.getValue().getValue()); + } + + private static Set asSet(String value) { + HashSet hashSet = new HashSet<>(); + hashSet.add(new AString(value)); + return hashSet; + } +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/timedstate/TimeStateTest.java b/li.strolch.model/src/test/java/li/strolch/model/timedstate/TimeStateTest.java new file mode 100644 index 000000000..2654fb216 --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/timedstate/TimeStateTest.java @@ -0,0 +1,111 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timedstate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import li.strolch.model.timevalue.ITimeValue; +import li.strolch.model.timevalue.IValueChange; +import li.strolch.model.timevalue.impl.FloatValue; +import li.strolch.model.timevalue.impl.ValueChange; + +import org.junit.Before; +import org.junit.Test; + +public class TimeStateTest { + + private ITimedState state = new TimedState(); + + final FloatValue expectedValue1 = new FloatValue(Double.valueOf(100D)); + final FloatValue expectedValue2 = new FloatValue(Double.valueOf(200D)); + + final Long t0 = Long.valueOf(0); + final Long t10 = Long.valueOf(10); + final Long t20 = Long.valueOf(20); + final Long t30 = Long.valueOf(30); + final Long t100 = Long.valueOf(100); + + @Before + public void before() { + + final IValueChange change1 = new ValueChange(this.t10, this.expectedValue1); + this.state.applyChange(change1); + + final ITimeValue stateAt9 = this.state.getStateAt(9L); + assertNull(stateAt9); + + final ITimeValue stateAt11 = this.state.getStateAt(11L); + assertNotNull(stateAt11); + assertEquals(true, stateAt11.getValue().matches(this.expectedValue1)); + + final IValueChange change2 = new ValueChange(this.t30, this.expectedValue1); + this.state.applyChange(change2); + + final ITimeValue stateAt31 = this.state.getStateAt(31L); + assertNotNull(stateAt31); + assertEquals(true, stateAt31.getValue().matches(this.expectedValue2)); + } + + @Test + public void testGetNextMatch() { + + ITimeValue nextMatch = this.state.getNextMatch(this.t0, this.expectedValue1); + assertNotNull(nextMatch); + assertEquals(this.t10, nextMatch.getTime()); + + nextMatch = this.state.getNextMatch(this.t20, this.expectedValue1); + assertNull(nextMatch); + + nextMatch = this.state.getNextMatch(this.t20, this.expectedValue2); + assertNotNull(nextMatch); + assertEquals(this.t30, nextMatch.getTime()); + + nextMatch = this.state.getNextMatch(this.t30, this.expectedValue2); + assertNotNull(nextMatch); + assertEquals(this.t30, nextMatch.getTime()); + + nextMatch = this.state.getNextMatch(this.t100, this.expectedValue1); + assertNull(nextMatch); + + nextMatch = this.state.getNextMatch(this.t100, this.expectedValue2); + assertNull(nextMatch); + + } + + @Test + public void testGetPreviousMatch() { + + ITimeValue previousMatch = this.state.getPreviousMatch(this.t100, this.expectedValue2); + assertNotNull(previousMatch); + assertEquals(this.t30, previousMatch.getTime()); + + previousMatch = this.state.getPreviousMatch(this.t30, this.expectedValue2); + assertNull(previousMatch); + + previousMatch = this.state.getPreviousMatch(this.t20, this.expectedValue2); + assertNull(previousMatch); + + previousMatch = this.state.getPreviousMatch(this.t20, this.expectedValue1); + assertNotNull(previousMatch); + assertEquals(this.t10, previousMatch.getTime()); + + previousMatch = this.state.getPreviousMatch(this.t10, this.expectedValue1); + assertNull(previousMatch); + + } + +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/timevalue/FloatTimeVariableTest.java b/li.strolch.model/src/test/java/li/strolch/model/timevalue/FloatTimeVariableTest.java new file mode 100644 index 000000000..0e07f940e --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/timevalue/FloatTimeVariableTest.java @@ -0,0 +1,150 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.SortedSet; + +import li.strolch.model.timevalue.impl.FloatValue; +import li.strolch.model.timevalue.impl.TimeVariable; +import li.strolch.model.timevalue.impl.ValueChange; + +import org.junit.Before; +import org.junit.Test; + +public class FloatTimeVariableTest { + + private static final Long MAX = 100L; + private static final Long STEP = 10L; + private static final Long PICK = 50L; + + private TimeVariable timeVariable; + + /** + * set the values ascending with a difference of STEP + */ + @Before + public void init() { + this.timeVariable = new TimeVariable(); + for (long i = 0; i < MAX; i += STEP) { + this.timeVariable.setValueAt(Long.valueOf(i), new FloatValue(i)); + } + } + + @Test + public void testGetValueAt() { + ITimeValue valueAt = this.timeVariable.getValueAt(PICK); + assertEquals(PICK.doubleValue(), valueAt.getValue().getValue(), 0.0001); + } + + /** + * test, that the future values start with the PICK time and are ascending + */ + @Test + public void testGetFutureValues() { + Collection> futureValues = this.timeVariable.getFutureValues(PICK); + Long expectedTime = PICK; + Double expectedValue = PICK.doubleValue(); + for (ITimeValue value : futureValues) { + assertEquals(expectedTime, value.getTime()); + assertTrue(value.getValue().matches(new FloatValue(expectedValue))); + expectedTime += STEP; + expectedValue += STEP.doubleValue(); + } + } + + /** + * test, that the past values time fields start with 0 and are strictly smaller than PICK + */ + @Test + public void testGetPastValues() { + Collection> pastValues = this.timeVariable.getPastValues(MAX); + Long expectedTime = 0L; + Double expectedValue = expectedTime.doubleValue(); + for (ITimeValue value : pastValues) { + assertEquals(expectedTime, value.getTime()); + assertTrue(value.getValue().matches(new FloatValue(expectedValue))); + expectedTime += STEP; + expectedValue += STEP.doubleValue(); + } + } + + /** + * apply a change and check that the future values are all changed + */ + @Test + public void testApplyChange() { + + FloatValue doubleValue = new FloatValue(STEP.doubleValue()); + + IValueChange change = new ValueChange(PICK, doubleValue); + this.timeVariable.applyChange(change); + + Collection> futureValues = this.timeVariable.getFutureValues(PICK); + Long expectedTime = PICK; + + IValue expectedValue = new FloatValue(PICK.doubleValue() + change.getValue().getValue()); + + for (ITimeValue value : futureValues) { + assertEquals(expectedTime, value.getTime()); + assertTrue(expectedValue.matches(value.getValue())); + expectedTime += STEP; + expectedValue = expectedValue.add(STEP.doubleValue()); + } + } + + /** + * apply a change to an empty time variable + */ + @Test + public void testApply2Change() { + + this.timeVariable = new TimeVariable(); + + FloatValue doubleValue = new FloatValue(STEP.doubleValue()); + + IValueChange change = new ValueChange(PICK, doubleValue); + this.timeVariable.applyChange(change); + + ITimeValue actual = this.timeVariable.getValueAt(PICK); + assertNotNull(actual); + + IValue expectedValue = new FloatValue(STEP.doubleValue()); + assertEquals(true, actual.getValue().matches(expectedValue)); + } + + /** + * test that successors matching the values of their predecessors are removed + */ + @Test + public void testCompact() { + + this.timeVariable = new TimeVariable(); + for (Long i = 0L; i < MAX; i += STEP) { + this.timeVariable.setValueAt(i, new FloatValue(STEP.doubleValue())); + } + // call + this.timeVariable.compact(); + // check + SortedSet> futureValues = this.timeVariable.getFutureValues(0L); + assertEquals(1, futureValues.size()); + } + +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/timevalue/IntegerTimeVariableTest.java b/li.strolch.model/src/test/java/li/strolch/model/timevalue/IntegerTimeVariableTest.java new file mode 100644 index 000000000..323c7c38e --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/timevalue/IntegerTimeVariableTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedSet; + +import li.strolch.model.timevalue.impl.IntegerValue; +import li.strolch.model.timevalue.impl.TimeVariable; +import li.strolch.model.timevalue.impl.ValueChange; + +import org.junit.Before; +import org.junit.Test; + +/** + * Basic tests for a {@link TimeVariable} with integer values. + * + * @author martin_smock + */ +public class IntegerTimeVariableTest { + + private static final Long MAX = 100L; + private static final Integer STEP = 10; + private static final Long PICK = 50L; + + private TimeVariable timeVariable; + private Map expectedValues = new HashMap(); + + /** + * set the values ascending with a difference of STEP + */ + @Before + public void init() { + this.timeVariable = new TimeVariable(); + for (int i = 0; i < MAX; i += STEP) { + IntegerValue expectedValue = new IntegerValue(i); + Long time = Long.valueOf(i); + this.expectedValues.put(time, expectedValue); + this.timeVariable.setValueAt(time, expectedValue); + } + } + + @Test + public void testGetValueAt() { + ITimeValue valueAt = this.timeVariable.getValueAt(PICK); + assertEquals(this.expectedValues.get(PICK), valueAt.getValue()); + } + + /** + * test, that the future values start with the PICK time and are ascending + */ + @Test + public void testGetFutureValues() { + Collection> futureValues = this.timeVariable.getFutureValues(PICK); + Long expectedTime = PICK; + Integer expectedValue = PICK.intValue(); + for (ITimeValue value : futureValues) { + assertEquals(expectedTime, value.getTime()); + assertTrue(value.getValue().matches(new IntegerValue(expectedValue))); + expectedTime += STEP; + expectedValue += STEP.intValue(); + } + } + + /** + * test, that the past values time fields start with 0 and are strictly smaller than PICK + */ + @Test + public void testGetPastValues() { + Collection> pastValues = this.timeVariable.getPastValues(MAX); + Long expectedTime = 0L; + Integer expectedValue = expectedTime.intValue(); + for (ITimeValue value : pastValues) { + assertEquals(expectedTime, value.getTime()); + assertTrue(value.getValue().matches(new IntegerValue(expectedValue))); + expectedTime += STEP; + expectedValue += STEP.intValue(); + } + } + + /** + * apply a change and check that the future values are all changed + */ + @Test + public void testApplyChange() { + + IntegerValue integerValue = new IntegerValue(STEP.intValue()); + + IValueChange change = new ValueChange(PICK, integerValue); + this.timeVariable.applyChange(change); + + Collection> futureValues = this.timeVariable.getFutureValues(PICK); + Long expectedTime = PICK; + + IValue expectedValue = new IntegerValue(PICK.intValue() + change.getValue().getValue()); + for (ITimeValue value : futureValues) { + assertEquals(expectedTime, value.getTime()); + assertTrue(expectedValue.matches(value.getValue())); + expectedTime += STEP; + expectedValue = expectedValue.add(STEP.intValue()); + } + } + + /** + * test that successors matching the values of their predecessors are removed + */ + @Test + public void testCompact() { + this.timeVariable = new TimeVariable(); + for (Long i = 0L; i < MAX; i += STEP) { + this.timeVariable.setValueAt(i, new IntegerValue(STEP.intValue())); + } + + // call + this.timeVariable.compact(); + + // check + SortedSet> futureValues = this.timeVariable.getFutureValues(0L); + assertEquals(1, futureValues.size()); + + ITimeValue next = futureValues.iterator().next(); + assertEquals(Long.valueOf(0), next.getTime()); + } + +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/timevalue/StringTimeVariableTest.java b/li.strolch.model/src/test/java/li/strolch/model/timevalue/StringTimeVariableTest.java new file mode 100644 index 000000000..f8a8143ff --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/timevalue/StringTimeVariableTest.java @@ -0,0 +1,132 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; + +import li.strolch.model.timevalue.impl.AString; +import li.strolch.model.timevalue.impl.StringSetValue; +import li.strolch.model.timevalue.impl.TimeVariable; +import li.strolch.model.timevalue.impl.ValueChange; + +import org.junit.Before; +import org.junit.Test; + +public class StringTimeVariableTest { + + private static final Long MAX = 100L; + private static final Long STEP = 10L; + private static final Long PICK = 50L; + + private TimeVariable>> timeVariable; + + private Map testSets = new HashMap(); + + @Before + public void init() { + this.timeVariable = new TimeVariable>>(); + for (Long i = 0L; i < MAX; i += STEP) { + Set testSet = new HashSet(); + StringSetValue testValue = new StringSetValue(testSet); + this.testSets.put(i, testValue); + testSet.add(new AString("string " + i)); //$NON-NLS-1$ + this.timeVariable.setValueAt(i, new StringSetValue(testSet)); + } + } + + @Test + public void testGetValueAt() { + ITimeValue>> valueAt = this.timeVariable.getValueAt(PICK); + assertEquals(true, valueAt.getValue().matches(this.testSets.get(PICK))); + } + + @Test + public void testGetFutureValues() { + Collection>>> futureValues = this.timeVariable.getFutureValues(PICK); + for (ITimeValue>> iTimeValue : futureValues) { + Long time = iTimeValue.getTime(); + assertEquals(true, time >= PICK); + assertNotNull(iTimeValue.getValue()); + assertEquals(true, iTimeValue.getValue().matches(this.testSets.get(time))); + } + } + + @Test + public void testGetPastValues() { + Collection>>> pastValues = this.timeVariable.getPastValues(PICK); + for (ITimeValue>> iTimeValue : pastValues) { + Long time = iTimeValue.getTime(); + assertEquals(true, time < PICK); + assertNotNull(iTimeValue.getValue()); + assertEquals(true, iTimeValue.getValue().matches(this.testSets.get(time))); + } + } + + @Test + public void testApplyChange() { + + Set testSet = new HashSet(); + testSet.add(new AString("Martin")); //$NON-NLS-1$ + StringSetValue testValue = new StringSetValue(testSet); + + this.timeVariable = new TimeVariable>>(); + this.timeVariable.setValueAt(PICK, testValue); + + IValue> inverseTestValue = testValue.getInverse(); + IValueChange>> change = new ValueChange>>(PICK, inverseTestValue); + this.timeVariable.applyChange(change); + + // check the future values + Collection>>> futureValues = this.timeVariable.getFutureValues(0L); + for (ITimeValue>> iTimeValue : futureValues) { + System.out.println("++ " + iTimeValue); //$NON-NLS-1$ + } + + assertEquals(1, futureValues.size()); // a empty one is left + + } + + @Test + public void testCompact() { + + this.timeVariable = new TimeVariable>>(); + for (Long i = 0L; i < MAX; i += STEP) { + Set testSet = new HashSet(); + StringSetValue testValue = new StringSetValue(testSet); + this.testSets.put(i, testValue); + testSet.add(new AString("same string")); //$NON-NLS-1$ + this.timeVariable.setValueAt(i, new StringSetValue(testSet)); + } + + SortedSet>>> valuesInitial = this.timeVariable.getFutureValues(0L); + assertEquals(true, valuesInitial.size() > 1); + + this.timeVariable.compact(); + + SortedSet>>> valuesCompacted = this.timeVariable.getFutureValues(0L); + assertEquals(1, valuesCompacted.size()); + + } + +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/timevalue/ValueTests.java b/li.strolch.model/src/test/java/li/strolch/model/timevalue/ValueTests.java new file mode 100644 index 000000000..0be352166 --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/timevalue/ValueTests.java @@ -0,0 +1,92 @@ +/* + * Copyright 2013 Martin Smock + * + * 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.timevalue; + +import static org.junit.Assert.assertEquals; + +import java.util.HashSet; +import java.util.Set; + +import li.strolch.model.timevalue.impl.AString; +import li.strolch.model.timevalue.impl.FloatValue; +import li.strolch.model.timevalue.impl.IntegerValue; +import li.strolch.model.timevalue.impl.StringSetValue; + +import org.junit.Test; + +public class ValueTests { + + /** + * check, that adding the inverse results in the neutral element (=0) + */ + @Test + public void testDoubleInverse() { + FloatValue value = new FloatValue(10.0d); + FloatValue inverse = value.getInverse(); + assertEquals(Double.valueOf(-10.0d), inverse.getValue()); + assertEquals(Double.valueOf(0), value.add(inverse.getValue()).getValue()); + } + + /** + * check, that adding the inverse results in the neutral element (=0) + */ + @Test + public void testIntegerInverse() { + IntegerValue value = new IntegerValue(10); + IntegerValue inverse = value.getInverse(); + assertEquals(Integer.valueOf(-10), inverse.getValue()); + assertEquals(Integer.valueOf(0), value.add(inverse.getValue()).getValue()); + } + + /** + * check, that adding the inverse results in the neutral element (empty Set) + */ + @Test + public void testStringSetInverse() { + Set aStrings = new HashSet(); + for (int i = 0; i < 10; i++) { + aStrings.add(new AString("string " + i)); //$NON-NLS-1$ + } + IValue> value = new StringSetValue(aStrings); + IValue> inverse = value.getInverse(); + assertEquals(true, value.matches(inverse.getInverse())); + assertEquals(0, value.add(inverse.getValue()).getValue().size()); + } + + /** + * check, that the difference left is as expected + */ + @Test + public void testStringSetNearInverse() { + + Set aStrings1 = new HashSet(); + for (int i = 0; i < 10; i++) { + aStrings1.add(new AString("string " + i)); //$NON-NLS-1$ + } + IValue> value1 = new StringSetValue(aStrings1); + + Set aStrings2 = new HashSet(); + for (int i = 0; i < 9; i++) { + aStrings2.add(new AString("string " + i, true)); //$NON-NLS-1$ + } + IValue> value2 = new StringSetValue(aStrings2); + + assertEquals(false, value1.matches(value2)); + assertEquals(1, value1.add(value2.getValue()).getValue().size()); + assertEquals(10, value1.add(value2.getInverse().getValue()).getValue().size()); + } + +} diff --git a/li.strolch.model/src/test/resources/data/StrolchModel.xml b/li.strolch.model/src/test/resources/data/StrolchModel.xml new file mode 100644 index 000000000..818cccb2d --- /dev/null +++ b/li.strolch.model/src/test/resources/data/StrolchModel.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/li.strolch.model/src/test/resources/data/orders/Orders.xml b/li.strolch.model/src/test/resources/data/orders/Orders.xml new file mode 100644 index 000000000..1e4b66d00 --- /dev/null +++ b/li.strolch.model/src/test/resources/data/orders/Orders.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/li.strolch.model/src/test/resources/data/orders/Templates.xml b/li.strolch.model/src/test/resources/data/orders/Templates.xml new file mode 100644 index 000000000..bd86a6925 --- /dev/null +++ b/li.strolch.model/src/test/resources/data/orders/Templates.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/li.strolch.model/src/test/resources/data/resources/Resources.xml b/li.strolch.model/src/test/resources/data/resources/Resources.xml new file mode 100644 index 000000000..9ac7b632a --- /dev/null +++ b/li.strolch.model/src/test/resources/data/resources/Resources.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/li.strolch.model/src/test/resources/data/resources/Templates.xml b/li.strolch.model/src/test/resources/data/resources/Templates.xml new file mode 100644 index 000000000..f122f0346 --- /dev/null +++ b/li.strolch.model/src/test/resources/data/resources/Templates.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/li.strolch.model/src/test/resources/log4j.xml b/li.strolch.model/src/test/resources/log4j.xml new file mode 100644 index 000000000..0a2a73d06 --- /dev/null +++ b/li.strolch.model/src/test/resources/log4j.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +