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 index 765c3b6b7..958c0bac0 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java +++ b/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java @@ -315,7 +315,7 @@ public class ModelGenerator { */ public static PolicyDefs createPolicyDefs() { PolicyDefs policyDefs = new PolicyDefs(); - PolicyDef policyDef = new JavaPolicyDef("ObjectPolicy", "java.lang.Object"); + PolicyDef policyDef = new JavaPolicyDef("ObjectPolicy", Object.class.getName()); policyDefs.addOrUpdate(policyDef); return policyDefs; } 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 index d10ed93a8..ec8cc6efa 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/Tags.java +++ b/li.strolch.model/src/main/java/li/strolch/model/Tags.java @@ -54,6 +54,7 @@ public class Tags { public static final String ACTION = "Action"; public static final String START = "Start"; public static final String END = "End"; + public static final String VALUE_CHANGES = "ValueChanges"; public static final String VALUE_CHANGE = "ValueChange"; public static final String RESOURCE_ID = "ResourceId"; public static final String RESOURCE_TYPE = "ResourceType"; diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/ActivityFromJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/ActivityFromJsonVisitor.java new file mode 100644 index 000000000..46865272d --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/json/ActivityFromJsonVisitor.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016 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.json; + +import com.google.gson.JsonObject; + +import li.strolch.model.activity.Activity; + +/** + * @author Robert von Burg + */ +public class ActivityFromJsonVisitor extends StrolchElementFromJsonVisitor { + + public Activity visit(JsonObject jsonObject) { + Activity activity = new Activity(); + fillElement(jsonObject, activity); + return activity; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/ActivityToJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/ActivityToJsonVisitor.java index 02d364ae3..9dab761de 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/json/ActivityToJsonVisitor.java +++ b/li.strolch.model/src/main/java/li/strolch/model/json/ActivityToJsonVisitor.java @@ -8,12 +8,16 @@ import li.strolch.model.activity.Activity; public class ActivityToJsonVisitor extends StrolchElementToJsonVisitor implements ActivityVisitor { + private JsonObject jsonObject; + + public JsonObject getJsonObject() { + return this.jsonObject; + } + @Override public JsonObject visit(Activity element) { - - JsonObject rootJ = toJson(element); - - return rootJ; + this.jsonObject = toJson(element); + return this.jsonObject; } public static String toJsonString(Activity element) { diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/OrderFromJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/OrderFromJsonVisitor.java new file mode 100644 index 000000000..4ca53b602 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/json/OrderFromJsonVisitor.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016 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.json; + +import com.google.gson.JsonObject; + +import li.strolch.model.Order; + +/** + * @author Robert von Burg + */ +public class OrderFromJsonVisitor extends StrolchElementFromJsonVisitor { + + public Order visit(JsonObject jsonObject) { + Order order = new Order(); + fillElement(jsonObject, order); + return order; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/OrderToJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/OrderToJsonVisitor.java index 11a6ad925..e7781fdb2 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/json/OrderToJsonVisitor.java +++ b/li.strolch.model/src/main/java/li/strolch/model/json/OrderToJsonVisitor.java @@ -8,12 +8,16 @@ import li.strolch.model.OrderVisitor; public class OrderToJsonVisitor extends StrolchElementToJsonVisitor implements OrderVisitor { + private JsonObject jsonObject; + + public JsonObject getJsonObject() { + return this.jsonObject; + } + @Override public JsonObject visit(Order element) { - - JsonObject rootJ = toJson(element); - - return rootJ; + this.jsonObject = toJson(element); + return this.jsonObject; } public static String toJsonString(Order element) { diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/ResourceFromJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/ResourceFromJsonVisitor.java new file mode 100644 index 000000000..d96655fd6 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/json/ResourceFromJsonVisitor.java @@ -0,0 +1,32 @@ +/* + * Copyright 2016 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.json; + +import com.google.gson.JsonObject; + +import li.strolch.model.Resource; + +/** + * @author Robert von Burg + */ +public class ResourceFromJsonVisitor extends StrolchElementFromJsonVisitor { + + public Resource visit(JsonObject jsonObject) { + Resource resource = new Resource(); + fillElement(jsonObject, resource); + return resource; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/ResourceToJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/ResourceToJsonVisitor.java index 171c706bc..7673253a0 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/json/ResourceToJsonVisitor.java +++ b/li.strolch.model/src/main/java/li/strolch/model/json/ResourceToJsonVisitor.java @@ -8,12 +8,16 @@ import li.strolch.model.ResourceVisitor; public class ResourceToJsonVisitor extends StrolchElementToJsonVisitor implements ResourceVisitor { + private JsonObject jsonObject; + + public JsonObject getJsonObject() { + return this.jsonObject; + } + @Override public JsonObject visit(Resource element) { - - JsonObject rootJ = toJson(element); - - return rootJ; + this.jsonObject = toJson(element); + return this.jsonObject; } public static String toJsonString(Resource element) { diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/StrolchElementFromJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/StrolchElementFromJsonVisitor.java new file mode 100644 index 000000000..af94b80b4 --- /dev/null +++ b/li.strolch.model/src/main/java/li/strolch/model/json/StrolchElementFromJsonVisitor.java @@ -0,0 +1,352 @@ +/* + * Copyright 2015 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.json; + +import java.text.MessageFormat; +import java.util.Map.Entry; +import java.util.Set; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import li.strolch.exception.StrolchException; +import li.strolch.model.AbstractStrolchElement; +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.State; +import li.strolch.model.StrolchValueType; +import li.strolch.model.Tags; +import li.strolch.model.activity.Action; +import li.strolch.model.activity.Activity; +import li.strolch.model.parameter.Parameter; +import li.strolch.model.policy.PolicyDef; +import li.strolch.model.policy.PolicyDefs; +import li.strolch.model.timedstate.StrolchTimedState; +import li.strolch.model.timevalue.IValue; +import li.strolch.model.timevalue.impl.ValueChange; +import li.strolch.utils.dbc.DBC; +import li.strolch.utils.iso8601.ISO8601FormatFactory; + +/** + * @author Robert von Burg + */ +public class StrolchElementFromJsonVisitor { + + public void fillElement(JsonObject jsonObject, Order order) { + fillElement(jsonObject, (GroupedParameterizedElement) order); + + // policies + PolicyDefs defs = parsePolicies(jsonObject); + if (defs.hasPolicyDefs()) + order.setPolicyDefs(defs); + + // attributes + if (jsonObject.has(Tags.DATE)) { + String date = jsonObject.get(Tags.DATE).getAsString(); + order.setDate(ISO8601FormatFactory.getInstance().getDateFormat().parse(date)); + } else { + order.setDate(ISO8601FormatFactory.getInstance().getDateFormat().parse("-")); //$NON-NLS-1$ + } + + if (jsonObject.has(Tags.STATE)) { + order.setState(State.valueOf(jsonObject.get(Tags.STATE).getAsString())); + } else { + order.setState(State.CREATED); + } + } + + public void fillElement(JsonObject jsonObject, Resource resource) { + fillElement(jsonObject, (GroupedParameterizedElement) resource); + + // policies + PolicyDefs defs = parsePolicies(jsonObject); + if (defs.hasPolicyDefs()) + resource.setPolicyDefs(defs); + + // time states + if (!jsonObject.has(Tags.TIMED_STATES)) + return; + + JsonObject timedStatesJ = jsonObject.getAsJsonObject(Tags.TIMED_STATES); + Set> entrySet = timedStatesJ.entrySet(); + for (Entry entry : entrySet) { + + String stateId = entry.getKey(); + JsonObject timeStateJ = entry.getValue().getAsJsonObject(); + + // evaluate type of TimedState + String typeS = timeStateJ.get(Tags.TYPE).getAsString(); + DBC.PRE.assertNotEmpty("Type must be set on TimedState for resource with id " + resource.getId(), typeS); + StrolchValueType valueType = StrolchValueType.parse(typeS); + StrolchTimedState> timedState = valueType.timedStateInstance(); + + // attributes + fillElement(timeStateJ, (AbstractStrolchElement) timedState); + + // consistency of JSON key and object.id + if (!stateId.equals(timedState.getId())) { + String msg = "Check the values of the jsonElement: {0} JsonObject key not same as object.id!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, timeStateJ); + throw new StrolchException(msg); + } + + // further attributes + if (timeStateJ.has(Tags.INTERPRETATION)) + timedState.setInterpretation(timeStateJ.get(Tags.INTERPRETATION).getAsString()); + if (timeStateJ.has(Tags.UOM)) + timedState.setUom(timeStateJ.get(Tags.UOM).getAsString()); + if (timeStateJ.has(Tags.INDEX)) + timedState.setIndex(timeStateJ.get(Tags.INDEX).getAsInt()); + if (timeStateJ.has(Tags.HIDDEN)) + timedState.setHidden(timeStateJ.get(Tags.HIDDEN).getAsBoolean()); + + resource.addTimedState(timedState); + + if (!timeStateJ.has(Tags.VALUES)) + continue; + + JsonArray valuesJ = timeStateJ.getAsJsonArray(Tags.VALUES); + valuesJ.forEach(e -> { + + JsonObject timeValueJ = e.getAsJsonObject(); + + String timeS = timeValueJ.get(Tags.TIME).getAsString(); + long time = ISO8601FormatFactory.getInstance().parseDate(timeS).getTime(); + + String valueS = timeValueJ.get(Tags.VALUE).getAsString(); + timedState.setStateFromStringAt(time, valueS); + }); + } + } + + public void fillElement(JsonObject jsonObject, Activity activity) { + fillElement(jsonObject, (GroupedParameterizedElement) activity); + + // policies + PolicyDefs defs = parsePolicies(jsonObject); + if (defs.hasPolicyDefs()) + activity.setPolicyDefs(defs); + + if (!jsonObject.has(Tags.ELEMENTS)) + return; + + JsonArray elementsJsonArray = jsonObject.getAsJsonArray(Tags.ELEMENTS); + elementsJsonArray.forEach(e -> { + + JsonObject elementJsonObject = e.getAsJsonObject(); + String objectType = elementJsonObject.get(Tags.OBJECT_TYPE).getAsString(); + + switch (objectType) { + case Tags.ACTIVITY: + Activity childActivity = new Activity(); + fillElement(elementJsonObject, childActivity); + activity.addElement(childActivity); + break; + + case Tags.ACTION: + Action childAction = new Action(); + fillElement(elementJsonObject, childAction); + activity.addElement(childAction); + break; + + default: + String msg = "Check the values of the jsonObject: {0} unknown object Type {1} !"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, elementJsonObject, objectType); + throw new StrolchException(msg); + } + }); + } + + protected void fillElement(JsonObject jsonObject, AbstractStrolchElement strolchElement) { + if (jsonObject.has(Tags.ID) && jsonObject.has(Tags.NAME)) { + strolchElement.setId(jsonObject.get(Tags.ID).getAsString()); + strolchElement.setName(jsonObject.get(Tags.NAME).getAsString()); + } else { + String msg = "Check the values of the jsonObject: {0} either id or name attribute is null!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, jsonObject); + throw new StrolchException(msg); + } + } + + protected void fillElement(JsonObject jsonObject, GroupedParameterizedElement groupedParameterizedElement) { + fillElement(jsonObject, (AbstractStrolchElement) groupedParameterizedElement); + + if (jsonObject.has(Tags.TYPE)) { + groupedParameterizedElement.setType(jsonObject.get(Tags.TYPE).getAsString()); + } else { + String msg = "Check the values of the jsonObject: {0} type attribute is null!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, jsonObject); + throw new StrolchException(msg); + } + + // add all the parameter bags + if (!jsonObject.has(Tags.PARAMETER_BAGS)) + return; + + JsonObject bagsJsonObject = jsonObject.getAsJsonObject(Tags.PARAMETER_BAGS); + + Set> bags = bagsJsonObject.entrySet(); + for (Entry entry : bags) { + String bagId = entry.getKey(); + JsonElement jsonElement = entry.getValue(); + if (!jsonElement.isJsonObject()) { + String msg = "Check the values of the jsonElement: {0} it is not a JsonObject!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, jsonElement); + throw new StrolchException(msg); + } + + JsonObject bagJsonObject = jsonElement.getAsJsonObject(); + ParameterBag bag = new ParameterBag(); + fillElement(bagJsonObject, bag); + if (!bagId.equals(bag.getId())) { + String msg = "Check the values of the jsonElement: {0} JsonObject key not same as object.id!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, jsonElement); + throw new StrolchException(msg); + } + + groupedParameterizedElement.addParameterBag(bag); + } + } + + protected void fillElement(JsonObject jsonObject, ParameterizedElement parameterizedElement) { + fillElement(jsonObject, (AbstractStrolchElement) parameterizedElement); + + if (jsonObject.has(Tags.TYPE)) { + parameterizedElement.setType(jsonObject.get(Tags.TYPE).getAsString()); + } else { + String msg = "Check the values of the jsonObject: {0} type attribute is null!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, jsonObject); + throw new StrolchException(msg); + } + + // add all the parameters + if (!jsonObject.has(Tags.PARAMETERS)) + return; + + JsonObject parametersJsonObject = jsonObject.getAsJsonObject(Tags.PARAMETERS); + Set> parameters = parametersJsonObject.entrySet(); + for (Entry entry : parameters) { + String paramId = entry.getKey(); + JsonElement jsonElement = entry.getValue(); + if (!jsonElement.isJsonObject()) { + String msg = "Check the values of the jsonElement: {0} it is not a JsonObject!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, jsonElement); + throw new StrolchException(msg); + } + + JsonObject paramJsonObject = jsonElement.getAsJsonObject(); + String paramtype = paramJsonObject.get(Tags.TYPE).getAsString(); + + StrolchValueType paramValueType = StrolchValueType.parse(paramtype); + Parameter parameter = paramValueType.parameterInstance(); + fillElement(paramJsonObject, parameter); + if (!paramId.equals(parameter.getId())) { + String msg = "Check the values of the jsonElement: {0} JsonObject key not same as object.id!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, jsonElement); + throw new StrolchException(msg); + } + + parameterizedElement.addParameter(parameter); + } + } + + protected void fillElement(JsonObject jsonObject, Parameter param) { + fillElement(jsonObject, (AbstractStrolchElement) param); + + if (jsonObject.has(Tags.INTERPRETATION)) + param.setInterpretation(jsonObject.get(Tags.INTERPRETATION).getAsString()); + if (jsonObject.has(Tags.UOM)) + param.setUom(jsonObject.get(Tags.UOM).getAsString()); + if (jsonObject.has(Tags.INDEX)) + param.setIndex(jsonObject.get(Tags.INDEX).getAsInt()); + if (jsonObject.has(Tags.HIDDEN)) + param.setHidden(jsonObject.get(Tags.HIDDEN).getAsBoolean()); + + String value = jsonObject.get(Tags.VALUE).getAsString(); + param.setValueFromString(value); + } + + protected void fillElement(JsonObject jsonObject, Action action) { + fillElement(jsonObject, (GroupedParameterizedElement) action); + + // attributes + if (jsonObject.has(Tags.RESOURCE_ID)) + action.setResourceId(jsonObject.get(Tags.RESOURCE_ID).getAsString()); + if (jsonObject.has(Tags.RESOURCE_TYPE)) + action.setResourceType(jsonObject.get(Tags.RESOURCE_TYPE).getAsString()); + if (jsonObject.has(Tags.STATE)) + action.setState(State.valueOf(jsonObject.get(Tags.STATE).getAsString())); + + // policies + PolicyDefs defs = parsePolicies(jsonObject); + if (defs.hasPolicyDefs()) + action.setPolicyDefs(defs); + + // value changes + if (!jsonObject.has(Tags.VALUE_CHANGES)) + return; + + JsonArray valueChangesJ = jsonObject.getAsJsonArray(Tags.VALUE_CHANGES); + valueChangesJ.forEach(e -> { + try { + JsonObject valueChangeJ = e.getAsJsonObject(); + + String stateId = valueChangeJ.get(Tags.STATE_ID).getAsString(); + String timeS = valueChangeJ.get(Tags.TIME).getAsString(); + String valueS = valueChangeJ.get(Tags.VALUE).getAsString(); + String typeS = valueChangeJ.get(Tags.TYPE).getAsString(); + + StrolchValueType type = StrolchValueType.parse(typeS); + IValue value = type.valueInstance(valueS); + + long time = ISO8601FormatFactory.getInstance().getDateFormat().parse(timeS).getTime(); + ValueChange> valueChange = new ValueChange<>(time, value, stateId); + + action.addChange(valueChange); + + } catch (Exception e1) { + String msg = "Check the values of the jsonElement: {0} Fields invalid!"; //$NON-NLS-1$ + msg = MessageFormat.format(msg, e); + throw new StrolchException(msg, e1); + } + }); + } + + protected PolicyDefs parsePolicies(JsonObject jsonObject) { + + PolicyDefs policyDefs = new PolicyDefs(); + + if (!jsonObject.has(Tags.POLICIES)) + return policyDefs; + + JsonObject policiesJsonObject = jsonObject.getAsJsonObject(Tags.POLICIES); + + Set> entrySet = policiesJsonObject.entrySet(); + for (Entry entry : entrySet) { + + String type = entry.getKey(); + String value = entry.getValue().getAsString(); + + policyDefs.addOrUpdate(PolicyDef.valueOf(type, value)); + } + + return policyDefs; + } +} diff --git a/li.strolch.model/src/main/java/li/strolch/model/json/StrolchElementToJsonVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/json/StrolchElementToJsonVisitor.java index fa2519bee..4d25c9c2f 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/json/StrolchElementToJsonVisitor.java +++ b/li.strolch.model/src/main/java/li/strolch/model/json/StrolchElementToJsonVisitor.java @@ -11,7 +11,9 @@ import li.strolch.model.AbstractStrolchElement; import li.strolch.model.GroupedParameterizedElement; import li.strolch.model.Order; import li.strolch.model.ParameterBag; +import li.strolch.model.PolicyContainer; import li.strolch.model.Resource; +import li.strolch.model.StrolchModelConstants; import li.strolch.model.Tags; import li.strolch.model.activity.Action; import li.strolch.model.activity.Activity; @@ -22,6 +24,7 @@ import li.strolch.model.policy.PolicyDefs; import li.strolch.model.timedstate.StrolchTimedState; import li.strolch.model.timevalue.ITimeValue; import li.strolch.model.timevalue.IValue; +import li.strolch.model.timevalue.IValueChange; import li.strolch.utils.iso8601.ISO8601FormatFactory; public class StrolchElementToJsonVisitor { @@ -34,11 +37,8 @@ public class StrolchElementToJsonVisitor { toJson(element, rootJ); addParameterBags(element, rootJ); - addTimedStates(element, rootJ); - - if (element.hasPolicyDefs()) - addPolicies(element.getPolicyDefs(), rootJ); + addPolicies(element, rootJ); return rootJ; } @@ -53,9 +53,7 @@ public class StrolchElementToJsonVisitor { rootJ.addProperty(Tags.STATE, element.getState().name()); addParameterBags(element, rootJ); - - if (element.hasPolicyDefs()) - addPolicies(element.getPolicyDefs(), rootJ); + addPolicies(element, rootJ); return rootJ; } @@ -77,9 +75,7 @@ public class StrolchElementToJsonVisitor { toJson((AbstractStrolchElement) element, rootJ); addParameterBags(element, rootJ); - - if (element.hasPolicyDefs()) - addPolicies(element.getPolicyDefs(), rootJ); + addPolicies(element, rootJ); Iterator> iter = element.elementIterator(); if (iter.hasNext()) { @@ -110,29 +106,51 @@ public class StrolchElementToJsonVisitor { rootJ.addProperty(Tags.OBJECT_TYPE, Tags.ACTION); + // attributes toJson((AbstractStrolchElement) element, rootJ); rootJ.addProperty(Tags.RESOURCE_ID, element.getResourceId()); rootJ.addProperty(Tags.RESOURCE_TYPE, element.getResourceType()); rootJ.addProperty(Tags.STATE, element.getState().name()); addParameterBags(element, rootJ); + addPolicies(element, rootJ); - if (element.hasPolicyDefs()) - addPolicies(element.getPolicyDefs(), rootJ); + // value changes + Iterator>> iter = element.getChanges().iterator(); + if (iter.hasNext()) { + + JsonArray changesJ = new JsonArray(); + rootJ.add(Tags.VALUE_CHANGES, changesJ); + + while (iter.hasNext()) { + IValueChange> valueChange = iter.next(); + + JsonObject changeJ = new JsonObject(); + + changeJ.addProperty(Tags.STATE_ID, valueChange.getStateId()); + changeJ.addProperty(Tags.TIME, ISO8601FormatFactory.getInstance().formatDate(valueChange.getTime())); + changeJ.addProperty(Tags.VALUE, valueChange.getValue().getValueAsString()); + changeJ.addProperty(Tags.TYPE, valueChange.getValue().getType()); + + changesJ.add(changeJ); + } + } return rootJ; } - protected void addPolicies(PolicyDefs policyDefs, JsonObject rootJ) { - if (!policyDefs.hasPolicyDefs()) + protected void addPolicies(PolicyContainer policyContainer, JsonObject rootJ) { + if (!policyContainer.hasPolicyDefs() || !policyContainer.getPolicyDefs().hasPolicyDefs()) return; + PolicyDefs policyDefs = policyContainer.getPolicyDefs(); + JsonObject policyDefsJ = new JsonObject(); rootJ.add(Tags.POLICIES, policyDefsJ); for (String type : policyDefs.getPolicyTypes()) { PolicyDef policyDef = policyDefs.getPolicyDef(type); - policyDefsJ.addProperty(policyDef.getType(), policyDef.getValue()); + policyDefsJ.addProperty(policyDef.getType(), policyDef.getValueForXml()); } } @@ -161,27 +179,34 @@ public class StrolchElementToJsonVisitor { toJson(bag, bagJ); - addParameters(bag, bagJ); - } - } + if (!bag.hasParameters()) + continue; - protected void addParameters(ParameterBag bag, JsonObject bagJ) { + JsonObject paramsJ = new JsonObject(); + bagJ.add(Tags.PARAMETERS, paramsJ); - if (!bag.hasParameters()) - return; + for (String paramKey : bag.getParameterKeySet()) { + Parameter param = bag.getParameter(paramKey); - JsonObject paramsJ = new JsonObject(); - bagJ.add(Tags.PARAMETERS, paramsJ); + JsonObject paramJ = new JsonObject(); + paramsJ.add(paramKey, paramJ); - for (String paramKey : bag.getParameterKeySet()) { - Parameter param = bag.getParameter(paramKey); + toJson((AbstractStrolchElement) param, paramJ); - JsonObject paramJ = new JsonObject(); - paramsJ.add(paramKey, paramJ); + if (!StrolchModelConstants.INTERPRETATION_NONE.equals(param.getInterpretation())) + paramJ.addProperty(Tags.INTERPRETATION, param.getInterpretation()); - toJson((AbstractStrolchElement) param, paramJ); + if (param.isHidden()) + paramJ.addProperty(Tags.HIDDEN, param.isHidden()); - paramJ.addProperty(Tags.VALUE, param.getValueAsString()); + if (!StrolchModelConstants.UOM_NONE.equals(param.getUom())) + paramJ.addProperty(Tags.UOM, param.getUom()); + + if (param.getIndex() != 0) + paramJ.addProperty(Tags.INDEX, param.getIndex()); + + paramJ.addProperty(Tags.VALUE, param.getValueAsString()); + } } } diff --git a/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDef.java b/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDef.java index 718ca3a7d..3163696f6 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDef.java +++ b/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDef.java @@ -119,9 +119,8 @@ public abstract class PolicyDef { try { Class.forName(value); - } catch (ClassNotFoundException e) { - throw new StrolchPolicyException("Invalid policy configuration. Policy does not exist: " + value); + throw new StrolchPolicyException("Invalid policy configuration. Policy does not exist: " + value, e); } return new JavaPolicyDef(type, value); diff --git a/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDefs.java b/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDefs.java index b3e6e372a..abe929974 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDefs.java +++ b/li.strolch.model/src/main/java/li/strolch/model/policy/PolicyDefs.java @@ -20,8 +20,10 @@ import java.util.Map; import java.util.Set; import li.strolch.exception.StrolchPolicyException; +import li.strolch.model.Locator; import li.strolch.model.StrolchElement; import li.strolch.model.StrolchRootElement; +import li.strolch.model.Tags; import li.strolch.utils.dbc.DBC; /** @@ -99,4 +101,10 @@ public class PolicyDefs { } return clone; } + + public Locator getLocator() { + if (this.parent == null) + return Locator.valueOf(Tags.POLICIES); + return this.parent.getLocator().append(Tags.POLICIES); + } } 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 index eea7cdfcd..ccefb96a0 100644 --- 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 @@ -27,6 +27,7 @@ import li.strolch.model.Order; import li.strolch.model.ParameterBag; import li.strolch.model.Resource; import li.strolch.model.StrolchElement; +import li.strolch.model.Tags; import li.strolch.model.activity.Action; import li.strolch.model.activity.Activity; import li.strolch.model.activity.IActivityElement; @@ -63,20 +64,20 @@ public class StrolchElementDeepEqualsVisitor { protected void deepEquals(StrolchElement srcElement, StrolchElement dstElement) { DBC.PRE.assertEquals("Both elements should have the same ID", srcElement.getId(), dstElement.getId()); if (!srcElement.getName().equals(dstElement.getName())) { - this.mismatchedLocators.add(dstElement.getLocator()); + this.mismatchedLocators.add(dstElement.getLocator().append(Tags.NAME)); } if (!srcElement.getType().equals(dstElement.getType())) { - this.mismatchedLocators.add(dstElement.getLocator()); + this.mismatchedLocators.add(dstElement.getLocator().append(Tags.TYPE)); } } protected void deepEquals(Order srcOrder, Order dstOrder) { deepEquals((StrolchElement) srcOrder, (StrolchElement) dstOrder); if (!srcOrder.getState().equals(dstOrder.getState())) { - this.mismatchedLocators.add(dstOrder.getLocator()); + this.mismatchedLocators.add(dstOrder.getLocator().append(Tags.STATE)); } if (!srcOrder.getDate().equals(dstOrder.getDate())) { - this.mismatchedLocators.add(dstOrder.getLocator()); + this.mismatchedLocators.add(dstOrder.getLocator().append(Tags.DATE)); } deepEquals((GroupedParameterizedElement) srcOrder, (GroupedParameterizedElement) dstOrder); @@ -84,7 +85,7 @@ public class StrolchElementDeepEqualsVisitor { if (srcOrder.hasPolicyDefs() && dstOrder.hasPolicyDefs()) deepEquals(srcOrder.getPolicyDefs(), dstOrder.getPolicyDefs()); else if (srcOrder.hasPolicyDefs() != dstOrder.hasPolicyDefs()) - this.mismatchedLocators.add(srcOrder.getLocator()); + this.mismatchedLocators.add(srcOrder.getPolicyDefs().getLocator()); } private void deepEquals(PolicyDefs srcPolicyDefs, PolicyDefs dstPolicyDefs) { @@ -94,22 +95,22 @@ public class StrolchElementDeepEqualsVisitor { PolicyDef srcPolicyDef = srcPolicyDefs.getPolicyDef(srcType); if (!dstPolicyDefs.hasPolicyDef(srcType)) { - this.mismatchedLocators.add(dstPolicyDefs.getParent().getLocator()); + this.mismatchedLocators.add(dstPolicyDefs.getLocator().append(srcType)); continue; } PolicyDef dstPolicyDef = dstPolicyDefs.getPolicyDef(srcType); if (srcPolicyDef.getClass() != dstPolicyDef.getClass()) - this.mismatchedLocators.add(dstPolicyDefs.getParent().getLocator()); + this.mismatchedLocators.add(dstPolicyDefs.getLocator().append(srcType)); if (!srcPolicyDef.getValue().equals(dstPolicyDef.getValue())) - this.mismatchedLocators.add(dstPolicyDefs.getParent().getLocator()); + this.mismatchedLocators.add(dstPolicyDefs.getLocator().append(srcType)); } Set dstTypes = dstPolicyDefs.getPolicyTypes(); for (String dstType : dstTypes) { if (!srcPolicyDefs.hasPolicyDef(dstType)) { - this.mismatchedLocators.add(srcPolicyDefs.getParent().getLocator()); + this.mismatchedLocators.add(srcPolicyDefs.getLocator().append(dstType)); } } } @@ -121,7 +122,7 @@ public class StrolchElementDeepEqualsVisitor { if (srcRes.hasPolicyDefs() && dstRes.hasPolicyDefs()) deepEquals(srcRes.getPolicyDefs(), dstRes.getPolicyDefs()); else if (srcRes.hasPolicyDefs() != dstRes.hasPolicyDefs()) - this.mismatchedLocators.add(srcRes.getLocator()); + this.mismatchedLocators.add(srcRes.getPolicyDefs().getLocator()); Set srcTimedStateKeySet = srcRes.getTimedStateKeySet(); for (String timedStateKey : srcTimedStateKeySet) { @@ -152,7 +153,7 @@ public class StrolchElementDeepEqualsVisitor { if (srcActivity.hasPolicyDefs() && dstActivity.hasPolicyDefs()) deepEquals(srcActivity.getPolicyDefs(), dstActivity.getPolicyDefs()); else if (srcActivity.hasPolicyDefs() != dstActivity.hasPolicyDefs()) - this.mismatchedLocators.add(srcActivity.getLocator()); + this.mismatchedLocators.add(srcActivity.getPolicyDefs().getLocator()); Iterator> iter = srcActivity.elementIterator(); while (iter.hasNext()) { @@ -193,13 +194,13 @@ public class StrolchElementDeepEqualsVisitor { deepEquals((GroupedParameterizedElement) srcAction, (GroupedParameterizedElement) dstAction); if (!srcAction.getResourceId().equals(dstAction.getResourceId())) { - this.mismatchedLocators.add(dstAction.getLocator()); + this.mismatchedLocators.add(dstAction.getLocator().append(Tags.RESOURCE_ID)); } if (!srcAction.getResourceType().equals(dstAction.getResourceType())) { - this.mismatchedLocators.add(dstAction.getLocator()); + this.mismatchedLocators.add(dstAction.getLocator().append(Tags.RESOURCE_TYPE)); } if (!srcAction.getState().equals(dstAction.getState())) { - this.mismatchedLocators.add(dstAction.getLocator()); + this.mismatchedLocators.add(dstAction.getLocator().append(Tags.STATE)); } if ((srcAction.getParent() == null && srcAction.getParent() != null) @@ -212,10 +213,15 @@ public class StrolchElementDeepEqualsVisitor { } if (srcAction.hasChanges() != dstAction.hasChanges()) { - this.mismatchedLocators.add(dstAction.getLocator()); + this.mismatchedLocators.add(dstAction.getLocator().append(Tags.VALUE_CHANGES)); } else if (!srcAction.getChanges().equals(dstAction.getChanges())) { - this.mismatchedLocators.add(dstAction.getLocator()); + this.mismatchedLocators.add(dstAction.getLocator().append(Tags.VALUE_CHANGES)); } + + if (srcAction.hasPolicyDefs() && dstAction.hasPolicyDefs()) + deepEquals(srcAction.getPolicyDefs(), dstAction.getPolicyDefs()); + else if (srcAction.hasPolicyDefs() != dstAction.hasPolicyDefs()) + this.mismatchedLocators.add(dstAction.getPolicyDefs().getLocator()); } protected void deepEquals(GroupedParameterizedElement srcElement, GroupedParameterizedElement dstElement) { @@ -291,7 +297,7 @@ public class StrolchElementDeepEqualsVisitor { final ITimeVariable dstTimeEvolution = dstState.getTimeEvolution(); if (!srcTimeEvolution.getValues().equals(dstTimeEvolution.getValues())) { - this.mismatchedLocators.add(dstState.getLocator()); + this.mismatchedLocators.add(dstState.getLocator().append(Tags.VALUES)); } } diff --git a/li.strolch.model/src/test/java/li/strolch/model/XmlToDomTest.java b/li.strolch.model/src/test/java/li/strolch/model/ModelToDomTest.java similarity index 98% rename from li.strolch.model/src/test/java/li/strolch/model/XmlToDomTest.java rename to li.strolch.model/src/test/java/li/strolch/model/ModelToDomTest.java index 56505d3eb..a4ddce3e9 100644 --- a/li.strolch.model/src/test/java/li/strolch/model/XmlToDomTest.java +++ b/li.strolch.model/src/test/java/li/strolch/model/ModelToDomTest.java @@ -35,7 +35,7 @@ import li.strolch.model.xml.ResourceToDomVisitor; * @author Robert von Burg */ @SuppressWarnings("nls") -public class XmlToDomTest extends ModelTest { +public class ModelToDomTest extends ModelTest { @Test public void shouldFormatAndParseOrder() { diff --git a/li.strolch.model/src/test/java/li/strolch/model/ModelToJsonTest.java b/li.strolch.model/src/test/java/li/strolch/model/ModelToJsonTest.java new file mode 100644 index 000000000..58749e188 --- /dev/null +++ b/li.strolch.model/src/test/java/li/strolch/model/ModelToJsonTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2016 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 org.junit.Test; + +import com.google.gson.JsonObject; + +import li.strolch.model.activity.Activity; +import li.strolch.model.json.ActivityFromJsonVisitor; +import li.strolch.model.json.ActivityToJsonVisitor; +import li.strolch.model.json.OrderFromJsonVisitor; +import li.strolch.model.json.OrderToJsonVisitor; +import li.strolch.model.json.ResourceFromJsonVisitor; +import li.strolch.model.json.ResourceToJsonVisitor; +import li.strolch.model.visitor.ActivityDeepEqualsVisitor; +import li.strolch.model.visitor.OrderDeepEqualsVisitor; +import li.strolch.model.visitor.ResourceDeepEqualsVisitor; + +public class ModelToJsonTest { + + @Test + public void shouldFormatAndParseOrder() { + + Order order = ModelGenerator.createOrder("@1", "My Order 1", "MyOrder"); + + OrderToJsonVisitor jsonVisitor = new OrderToJsonVisitor(); + jsonVisitor.visit(order); + JsonObject jsonObject = jsonVisitor.getJsonObject(); + + Order parsedOrder = new OrderFromJsonVisitor().visit(jsonObject); + + OrderDeepEqualsVisitor visitor = new OrderDeepEqualsVisitor(order); + visitor.visit(parsedOrder); + assertTrue("To JSON and back should equal same Order:\n" + visitor.getMismatchedLocators(), visitor.isEqual()); + } + + @Test + public void shouldFormatAndParseResource() { + + Resource resource = ModelGenerator.createResource("@1", "My Resource 1", "MyResource"); + + ResourceToJsonVisitor jsonVisitor = new ResourceToJsonVisitor(); + jsonVisitor.visit(resource); + JsonObject jsonObject = jsonVisitor.getJsonObject(); + + Resource parsedResource = new ResourceFromJsonVisitor().visit(jsonObject); + + ResourceDeepEqualsVisitor visitor = new ResourceDeepEqualsVisitor(resource); + visitor.visit(parsedResource); + assertTrue("To JSON and back should equal same Resource:\n" + visitor.getMismatchedLocators(), + visitor.isEqual()); + } + + @Test + public void shouldFormatAndParseActivity() { + + Activity activity = ModelGenerator.createActivity("@1", "My Activity 1", "Transport"); + + ActivityToJsonVisitor jsonVisitor = new ActivityToJsonVisitor(); + jsonVisitor.visit(activity); + JsonObject jsonObject = jsonVisitor.getJsonObject(); + + Activity parsedActivity = new ActivityFromJsonVisitor().visit(jsonObject); + + ActivityDeepEqualsVisitor visitor = new ActivityDeepEqualsVisitor(activity); + visitor.visit(parsedActivity); + assertTrue("To JSON and back should equal same Activity:\n" + visitor.getMismatchedLocators(), + visitor.isEqual()); + } +} diff --git a/li.strolch.model/src/test/java/li/strolch/model/XmlToSaxTest.java b/li.strolch.model/src/test/java/li/strolch/model/ModelToSaxTest.java similarity index 99% rename from li.strolch.model/src/test/java/li/strolch/model/XmlToSaxTest.java rename to li.strolch.model/src/test/java/li/strolch/model/ModelToSaxTest.java index 6336c538d..b126f237c 100644 --- a/li.strolch.model/src/test/java/li/strolch/model/XmlToSaxTest.java +++ b/li.strolch.model/src/test/java/li/strolch/model/ModelToSaxTest.java @@ -44,7 +44,7 @@ import org.junit.Test; * @author Robert von Burg */ @SuppressWarnings("nls") -public class XmlToSaxTest extends ModelTest { +public class ModelToSaxTest extends ModelTest { @Test public void shouldFormatAndParseOrder() { diff --git a/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java b/li.strolch.model/src/test/java/li/strolch/model/XmlModelSaxFileReaderTest.java similarity index 96% rename from li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java rename to li.strolch.model/src/test/java/li/strolch/model/XmlModelSaxFileReaderTest.java index 91c996474..fd7c488e1 100644 --- a/li.strolch.model/src/test/java/li/strolch/model/XmlModelDefaultHandlerTest.java +++ b/li.strolch.model/src/test/java/li/strolch/model/XmlModelSaxFileReaderTest.java @@ -34,9 +34,9 @@ import org.slf4j.LoggerFactory; * @author Robert von Burg */ @SuppressWarnings("nls") -public class XmlModelDefaultHandlerTest { +public class XmlModelSaxFileReaderTest { - private static final Logger logger = LoggerFactory.getLogger(XmlModelDefaultHandlerTest.class); + private static final Logger logger = LoggerFactory.getLogger(XmlModelSaxFileReaderTest.class); @Test public void shouldParseXmlModelFile() { diff --git a/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java b/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java index 4d9bd5716..88c724162 100644 --- a/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java +++ b/li.strolch.model/src/test/java/li/strolch/model/activity/ActivityTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2016 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.activity; import java.io.StringWriter;