/*
* Copyright 2013 Robert von Burg <eitch@eitchnet.ch>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.strolch.model.visitor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
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.activity.Action;
import li.strolch.model.activity.Activity;
import li.strolch.model.activity.IActivityElement;
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.ITimeVariable;
import li.strolch.utils.dbc.DBC;
/**
* @author Robert von Burg <eitch@eitchnet.ch>
*
*/
public class StrolchElementDeepEqualsVisitor {
private List<Locator> mismatchedLocators;
public StrolchElementDeepEqualsVisitor() {
this.mismatchedLocators = new ArrayList<>();
}
/**
* @return the mismatchedLocators
*/
public List<Locator> getMismatchedLocators() {
return this.mismatchedLocators;
}
public boolean isEqual() {
return this.mismatchedLocators.isEmpty();
}
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());
}
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);
if (srcOrder.hasPolicyDefs() && dstOrder.hasPolicyDefs())
deepEquals(srcOrder.getPolicyDefs(), dstOrder.getPolicyDefs());
else if (srcOrder.hasPolicyDefs() != dstOrder.hasPolicyDefs())
this.mismatchedLocators.add(srcOrder.getLocator());
}
private void deepEquals(PolicyDefs srcPolicyDefs, PolicyDefs dstPolicyDefs) {
Set<String> srcTypes = srcPolicyDefs.getPolicyTypes();
for (String srcType : srcTypes) {
PolicyDef srcPolicyDef = srcPolicyDefs.getPolicyDef(srcType);
if (!dstPolicyDefs.hasPolicyDef(srcType)) {
this.mismatchedLocators.add(dstPolicyDefs.getParent().getLocator());
continue;
}
PolicyDef dstPolicyDef = dstPolicyDefs.getPolicyDef(srcType);
if (srcPolicyDef.getClass() != dstPolicyDef.getClass())
this.mismatchedLocators.add(dstPolicyDefs.getParent().getLocator());
if (!srcPolicyDef.getValue().equals(dstPolicyDef.getValue()))
this.mismatchedLocators.add(dstPolicyDefs.getParent().getLocator());
}
Set<String> dstTypes = dstPolicyDefs.getPolicyTypes();
for (String dstType : dstTypes) {
if (!srcPolicyDefs.hasPolicyDef(dstType)) {
this.mismatchedLocators.add(srcPolicyDefs.getParent().getLocator());
}
}
}
protected void deepEquals(Resource srcRes, Resource dstRes) {
deepEquals((StrolchElement) srcRes, (StrolchElement) dstRes);
deepEquals((GroupedParameterizedElement) srcRes, (GroupedParameterizedElement) dstRes);
if (srcRes.hasPolicyDefs() && dstRes.hasPolicyDefs())
deepEquals(srcRes.getPolicyDefs(), dstRes.getPolicyDefs());
else if (srcRes.hasPolicyDefs() != dstRes.hasPolicyDefs())
this.mismatchedLocators.add(srcRes.getLocator());
Set<String> 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<String> dstTimedStateKeySet = dstRes.getTimedStateKeySet();
for (String timedStateKey : dstTimedStateKeySet) {
if (!srcRes.hasTimedState(timedStateKey)) {
StrolchTimedState<?> dstTimedState = dstRes.getTimedState(timedStateKey);
this.mismatchedLocators.add(dstTimedState.getLocator());
}
}
}
protected void deepEquals(Activity srcActivity, Activity dstActivity) {
deepEquals((StrolchElement) srcActivity, (StrolchElement) dstActivity);
deepEquals((GroupedParameterizedElement) srcActivity, (GroupedParameterizedElement) dstActivity);
if (srcActivity.hasPolicyDefs() && dstActivity.hasPolicyDefs())
deepEquals(srcActivity.getPolicyDefs(), dstActivity.getPolicyDefs());
else if (srcActivity.hasPolicyDefs() != dstActivity.hasPolicyDefs())
this.mismatchedLocators.add(srcActivity.getLocator());
Iterator<Entry<String, IActivityElement>> iter = srcActivity.elementIterator();
while (iter.hasNext()) {
IActivityElement srcActivityElement = iter.next().getValue();
if (!dstActivity.hasElement(srcActivityElement.getId())) {
this.mismatchedLocators.add(srcActivityElement.getLocator());
continue;
}
IActivityElement dstActivityElement = dstActivity.getElement(srcActivityElement.getId());
if (!srcActivityElement.getClass().equals(dstActivityElement.getClass())) {
this.mismatchedLocators.add(srcActivityElement.getLocator());
continue;
}
if (srcActivityElement instanceof Activity) {
deepEquals((Activity) srcActivityElement, (Activity) dstActivityElement);
} else if (srcActivityElement instanceof Action) {
deepEquals((Action) srcActivityElement, (Action) dstActivityElement);
} else {
throw new UnsupportedOperationException("Unhandled instance type " + srcActivityElement.getClass());
}
}
iter = dstActivity.elementIterator();
while (iter.hasNext()) {
IActivityElement activityElement = iter.next().getValue();
if (!srcActivity.hasElement(activityElement.getId())) {
this.mismatchedLocators.add(activityElement.getLocator());
}
}
}
protected void deepEquals(Action srcAction, Action dstAction) {
deepEquals((StrolchElement) srcAction, (StrolchElement) dstAction);
deepEquals((GroupedParameterizedElement) srcAction, (GroupedParameterizedElement) dstAction);
if (!srcAction.getResourceId().equals(dstAction.getResourceId())) {
this.mismatchedLocators.add(dstAction.getLocator());
}
if (!srcAction.getResourceType().equals(dstAction.getResourceType())) {
this.mismatchedLocators.add(dstAction.getLocator());
}
if (!srcAction.getState().equals(dstAction.getState())) {
this.mismatchedLocators.add(dstAction.getLocator());
}
if ((srcAction.getParent() == null && srcAction.getParent() != null)
|| (srcAction.getParent() != null && srcAction.getParent() == null)) {
this.mismatchedLocators.add(dstAction.getLocator());
} else if (!srcAction.getParent().getId().equals(dstAction.getParent().getId())) {
this.mismatchedLocators.add(dstAction.getLocator());
} else if (!srcAction.getParent().getType().equals(dstAction.getParent().getType())) {
this.mismatchedLocators.add(dstAction.getLocator());
}
if (srcAction.hasChanges() != dstAction.hasChanges()) {
this.mismatchedLocators.add(dstAction.getLocator());
} else if (!srcAction.getChanges().equals(dstAction.getChanges())) {
this.mismatchedLocators.add(dstAction.getLocator());
}
}
protected void deepEquals(GroupedParameterizedElement srcElement, GroupedParameterizedElement dstElement) {
Set<String> 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<String> 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<String> 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<String> 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();
}
}