| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.ofbiz.widget.model; |
| |
| import java.io.Serializable; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.TimeZone; |
| |
| import org.apache.oro.text.regex.MalformedPatternException; |
| import org.apache.oro.text.regex.Pattern; |
| import org.apache.oro.text.regex.PatternMatcher; |
| import org.apache.oro.text.regex.Perl5Matcher; |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.GeneralException; |
| import org.apache.ofbiz.base.util.ObjectType; |
| import org.apache.ofbiz.base.util.PatternFactory; |
| import org.apache.ofbiz.base.util.UtilGenerics; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.base.util.UtilXml; |
| import org.apache.ofbiz.base.util.collections.FlexibleMapAccessor; |
| import org.apache.ofbiz.base.util.string.FlexibleStringExpander; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entityext.permission.EntityPermissionChecker; |
| import org.apache.ofbiz.minilang.operation.BaseCompare; |
| import org.apache.ofbiz.security.Security; |
| import org.apache.ofbiz.service.DispatchContext; |
| import org.apache.ofbiz.service.GenericServiceException; |
| import org.apache.ofbiz.service.LocalDispatcher; |
| import org.apache.ofbiz.service.ModelService; |
| import org.apache.ofbiz.service.ServiceUtil; |
| import org.w3c.dom.Element; |
| |
| /** |
| * Abstract base class for the condition models. |
| */ |
| @SuppressWarnings("serial") |
| public abstract class ModelWidgetCondition implements Serializable { |
| |
| /* |
| * ----------------------------------------------------------------------- * |
| * DEVELOPERS PLEASE READ |
| * ----------------------------------------------------------------------- * |
| * |
| * This model is intended to be a read-only data structure that represents |
| * an XML element. Outside of object construction, the class should not |
| * have any behaviors. |
| * |
| * Instances of this class will be shared by multiple threads - therefore |
| * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME! |
| * |
| */ |
| |
| public static final String module = ModelWidgetCondition.class.getName(); |
| public static final ConditionFactory DEFAULT_CONDITION_FACTORY = new DefaultConditionFactory(); |
| |
| private final ModelWidget modelWidget; |
| private final Condition rootCondition; |
| |
| protected ModelWidgetCondition(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) { |
| this.modelWidget = modelWidget; |
| Element firstChildElement = UtilXml.firstChildElement(conditionElement); |
| this.rootCondition = factory.newInstance(modelWidget, firstChildElement); |
| } |
| |
| public boolean eval(Map<String, Object> context) { |
| return rootCondition.eval(context); |
| } |
| |
| public ModelWidget getModelWidget() { |
| return modelWidget; |
| } |
| |
| public static List<Condition> readSubConditions(ConditionFactory factory, ModelWidget modelWidget, Element conditionElement) { |
| List<? extends Element> subElementList = UtilXml.childElementList(conditionElement); |
| List<Condition> condList = new ArrayList<Condition>(subElementList.size()); |
| for (Element subElement : subElementList) { |
| condList.add(factory.newInstance(modelWidget, subElement)); |
| } |
| return Collections.unmodifiableList(condList); |
| } |
| |
| /** |
| * Models the <and> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class And extends ModelWidgetCondition implements Condition { |
| private final List<Condition> subConditions; |
| |
| private And(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| this.subConditions = readSubConditions(factory, modelWidget, condElement); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| // return false for the first one in the list that is false, basic and algo |
| for (Condition subCondition : this.subConditions) { |
| if (!subCondition.eval(context)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| |
| public static interface Condition { |
| boolean eval(Map<String, Object> context); |
| } |
| |
| /** |
| * A factory for <code>Condition</code> instances. |
| * |
| */ |
| public static interface ConditionFactory { |
| /** |
| * Returns a new <code>Condition</code> instance built from <code>conditionElement</code>. |
| * |
| * @param modelWidget The <code>ModelWidget</code> that contains the <code>Condition</code> instance. |
| * @param conditionElement The XML element used to build the <code>Condition</code> instance. |
| * @return A new <code>Condition</code> instance built from <code>conditionElement</code>. |
| * @throws IllegalArgumentException if no model was found for the XML element |
| */ |
| Condition newInstance(ModelWidget modelWidget, Element conditionElement); |
| } |
| |
| public static class DefaultConditionFactory implements ConditionFactory { |
| public static final Condition TRUE = new Condition() { |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| return true; |
| } |
| }; |
| public static final Condition FALSE = new Condition() { |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| return false; |
| } |
| }; |
| |
| public Condition newInstance(ModelWidget modelWidget, Element conditionElement) { |
| if (conditionElement == null) { |
| return TRUE; |
| } |
| if ("and".equals(conditionElement.getNodeName())) { |
| return new And(this, modelWidget, conditionElement); |
| } else if ("xor".equals(conditionElement.getNodeName())) { |
| return new Xor(this, modelWidget, conditionElement); |
| } else if ("or".equals(conditionElement.getNodeName())) { |
| return new Or(this, modelWidget, conditionElement); |
| } else if ("not".equals(conditionElement.getNodeName())) { |
| return new Not(this, modelWidget, conditionElement); |
| } else if ("if-service-permission".equals(conditionElement.getNodeName())) { |
| return new IfServicePermission(this, modelWidget, conditionElement); |
| } else if ("if-has-permission".equals(conditionElement.getNodeName())) { |
| return new IfHasPermission(this, modelWidget, conditionElement); |
| } else if ("if-validate-method".equals(conditionElement.getNodeName())) { |
| return new IfValidateMethod(this, modelWidget, conditionElement); |
| } else if ("if-compare".equals(conditionElement.getNodeName())) { |
| return new IfCompare(this, modelWidget, conditionElement); |
| } else if ("if-compare-field".equals(conditionElement.getNodeName())) { |
| return new IfCompareField(this, modelWidget, conditionElement); |
| } else if ("if-regexp".equals(conditionElement.getNodeName())) { |
| return new IfRegexp(this, modelWidget, conditionElement); |
| } else if ("if-empty".equals(conditionElement.getNodeName())) { |
| return new IfEmpty(this, modelWidget, conditionElement); |
| } else if ("if-entity-permission".equals(conditionElement.getNodeName())) { |
| return new IfEntityPermission(this, modelWidget, conditionElement); |
| } else { |
| throw new IllegalArgumentException("Condition element not supported with name: " + conditionElement.getNodeName()); |
| } |
| } |
| } |
| |
| /** |
| * Models the <if-compare> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfCompare extends ModelWidgetCondition implements Condition { |
| private final FlexibleMapAccessor<Object> fieldAcsr; |
| private final FlexibleStringExpander formatExdr; |
| private final String operator; |
| private final String type; |
| private final FlexibleStringExpander valueExdr; |
| |
| private IfCompare(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| String fieldAcsr = condElement.getAttribute("field"); |
| if (fieldAcsr.isEmpty()) |
| fieldAcsr = condElement.getAttribute("field-name"); |
| this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); |
| this.valueExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("value")); |
| this.operator = condElement.getAttribute("operator"); |
| this.type = condElement.getAttribute("type"); |
| this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format")); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| String value = this.valueExdr.expandString(context); |
| String format = this.formatExdr.expandString(context); |
| Object fieldVal = this.fieldAcsr.get(context); |
| // always use an empty string by default |
| if (fieldVal == null) { |
| fieldVal = ""; |
| } |
| List<Object> messages = new LinkedList<Object>(); |
| Boolean resultBool = BaseCompare.doRealCompare(fieldVal, value, operator, type, format, messages, null, null, true); |
| if (messages.size() > 0) { |
| messages.add(0, "Error with comparison in if-compare between field [" + fieldAcsr.toString() + "] with value [" |
| + fieldVal + "] and value [" + value + "] with operator [" + operator + "] and type [" + type + "]: "); |
| |
| StringBuilder fullString = new StringBuilder(); |
| for (Object item : messages) { |
| fullString.append(item.toString()); |
| } |
| Debug.logWarning(fullString.toString(), module); |
| throw new IllegalArgumentException(fullString.toString()); |
| } |
| return resultBool.booleanValue(); |
| } |
| } |
| |
| /** |
| * Models the <if-compare-field> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfCompareField extends ModelWidgetCondition implements Condition { |
| private final FlexibleMapAccessor<Object> fieldAcsr; |
| private final FlexibleStringExpander formatExdr; |
| private final String operator; |
| private final FlexibleMapAccessor<Object> toFieldAcsr; |
| private final String type; |
| |
| private IfCompareField(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| String fieldAcsr = condElement.getAttribute("field"); |
| if (fieldAcsr.isEmpty()) |
| fieldAcsr = condElement.getAttribute("field-name"); |
| this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); |
| String toFieldAcsr = condElement.getAttribute("to-field"); |
| if (toFieldAcsr.isEmpty()) |
| toFieldAcsr = condElement.getAttribute("to-field-name"); |
| this.toFieldAcsr = FlexibleMapAccessor.getInstance(toFieldAcsr); |
| this.operator = condElement.getAttribute("operator"); |
| this.type = condElement.getAttribute("type"); |
| this.formatExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("format")); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| String format = this.formatExdr.expandString(context); |
| Object fieldVal = this.fieldAcsr.get(context); |
| Object toFieldVal = this.toFieldAcsr.get(context); |
| // always use an empty string by default |
| if (fieldVal == null) { |
| fieldVal = ""; |
| } |
| List<Object> messages = new LinkedList<Object>(); |
| Boolean resultBool = BaseCompare.doRealCompare(fieldVal, toFieldVal, operator, type, format, messages, null, null, |
| false); |
| if (messages.size() > 0) { |
| messages.add(0, "Error with comparison in if-compare-field between field [" + fieldAcsr.toString() |
| + "] with value [" + fieldVal + "] and to-field [" + toFieldAcsr.toString() + "] with value [" |
| + toFieldVal + "] with operator [" + operator + "] and type [" + type + "]: "); |
| |
| StringBuilder fullString = new StringBuilder(); |
| for (Object item : messages) { |
| fullString.append(item.toString()); |
| } |
| Debug.logWarning(fullString.toString(), module); |
| throw new IllegalArgumentException(fullString.toString()); |
| } |
| return resultBool.booleanValue(); |
| } |
| } |
| |
| /** |
| * Models the <if-empty> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfEmpty extends ModelWidgetCondition implements Condition { |
| private final FlexibleMapAccessor<Object> fieldAcsr; |
| |
| private IfEmpty(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| String fieldAcsr = condElement.getAttribute("field"); |
| if (fieldAcsr.isEmpty()) |
| fieldAcsr = condElement.getAttribute("field-name"); |
| this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| Object fieldVal = this.fieldAcsr.get(context); |
| return ObjectType.isEmpty(fieldVal); |
| } |
| } |
| |
| /** |
| * Models the <if-entity-permission> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfEntityPermission extends ModelWidgetCondition implements Condition { |
| private final EntityPermissionChecker permissionChecker; |
| |
| private IfEntityPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| this.permissionChecker = new EntityPermissionChecker(condElement); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| return permissionChecker.runPermissionCheck(context); |
| } |
| } |
| |
| /** |
| * Models the <if-has-permission> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfHasPermission extends ModelWidgetCondition implements Condition { |
| private final FlexibleStringExpander actionExdr; |
| private final FlexibleStringExpander permissionExdr; |
| |
| private IfHasPermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| this.permissionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("permission")); |
| this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("action")); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| // if no user is logged in, treat as if the user does not have permission |
| GenericValue userLogin = (GenericValue) context.get("userLogin"); |
| if (userLogin != null) { |
| String permission = permissionExdr.expandString(context); |
| String action = actionExdr.expandString(context); |
| Security security = (Security) context.get("security"); |
| if (UtilValidate.isNotEmpty(action)) { |
| // run hasEntityPermission |
| if (security.hasEntityPermission(permission, action, userLogin)) { |
| return true; |
| } |
| } else { |
| // run hasPermission |
| if (security.hasPermission(permission, userLogin)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Models the <if-regexp> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfRegexp extends ModelWidgetCondition implements Condition { |
| private final FlexibleStringExpander exprExdr; |
| private final FlexibleMapAccessor<Object> fieldAcsr; |
| |
| private IfRegexp(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| String fieldAcsr = condElement.getAttribute("field"); |
| if (fieldAcsr.isEmpty()) |
| fieldAcsr = condElement.getAttribute("field-name"); |
| this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); |
| this.exprExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("expr")); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| Object fieldVal = this.fieldAcsr.get(context); |
| String expr = this.exprExdr.expandString(context); |
| Pattern pattern; |
| try { |
| pattern = PatternFactory.createOrGetPerl5CompiledPattern(expr, true); |
| } catch (MalformedPatternException e) { |
| String errMsg = "Error in evaluation in if-regexp in screen: " + e.toString(); |
| Debug.logError(e, errMsg, module); |
| throw new IllegalArgumentException(errMsg); |
| } |
| String fieldString = null; |
| try { |
| fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, (TimeZone) context.get("timeZone"), |
| (Locale) context.get("locale"), true); |
| } catch (GeneralException e) { |
| Debug.logError(e, "Could not convert object to String, using empty String", module); |
| } |
| // always use an empty string by default |
| if (fieldString == null) |
| fieldString = ""; |
| PatternMatcher matcher = new Perl5Matcher(); |
| return matcher.matches(fieldString, pattern); |
| } |
| } |
| |
| /** |
| * Models the <if-service-permission> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfServicePermission extends ModelWidgetCondition implements Condition { |
| private final FlexibleStringExpander actionExdr; |
| private final FlexibleStringExpander ctxMapExdr; |
| private final FlexibleStringExpander resExdr; |
| private final FlexibleStringExpander serviceExdr; |
| |
| private IfServicePermission(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| this.serviceExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("service-name")); |
| this.actionExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("main-action")); |
| this.ctxMapExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("context-map")); |
| this.resExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("resource-description")); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| // if no user is logged in, treat as if the user does not have permission |
| GenericValue userLogin = (GenericValue) context.get("userLogin"); |
| if (userLogin != null) { |
| String serviceName = serviceExdr.expandString(context); |
| String mainAction = actionExdr.expandString(context); |
| String contextMap = ctxMapExdr.expandString(context); |
| String resource = resExdr.expandString(context); |
| if (UtilValidate.isEmpty(resource)) { |
| resource = serviceName; |
| } |
| if (UtilValidate.isEmpty(serviceName)) { |
| Debug.logWarning("No permission service-name specified!", module); |
| return false; |
| } |
| Map<String, Object> serviceContext = UtilGenerics.toMap(context.get(contextMap)); |
| if (serviceContext != null) { |
| // copy the required internal fields |
| serviceContext.put("userLogin", context.get("userLogin")); |
| serviceContext.put("locale", context.get("locale")); |
| } else { |
| serviceContext = context; |
| } |
| // get the service engine objects |
| LocalDispatcher dispatcher = (LocalDispatcher) context.get("dispatcher"); |
| DispatchContext dctx = dispatcher.getDispatchContext(); |
| // get the service |
| ModelService permService; |
| try { |
| permService = dctx.getModelService(serviceName); |
| } catch (GenericServiceException e) { |
| Debug.logError(e, module); |
| return false; |
| } |
| if (permService != null) { |
| // build the context |
| Map<String, Object> svcCtx = permService.makeValid(serviceContext, ModelService.IN_PARAM); |
| svcCtx.put("resourceDescription", resource); |
| if (UtilValidate.isNotEmpty(mainAction)) { |
| svcCtx.put("mainAction", mainAction); |
| } |
| // invoke the service |
| Map<String, Object> resp; |
| try { |
| resp = dispatcher.runSync(permService.name, svcCtx, 300, true); |
| } catch (GenericServiceException e) { |
| Debug.logError(e, module); |
| return false; |
| } |
| if (ServiceUtil.isError(resp) || ServiceUtil.isFailure(resp)) { |
| Debug.logError(ServiceUtil.getErrorMessage(resp), module); |
| return false; |
| } |
| Boolean hasPermission = (Boolean) resp.get("hasPermission"); |
| if (hasPermission != null) { |
| return hasPermission.booleanValue(); |
| } |
| } |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Models the <if-validate-method> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class IfValidateMethod extends ModelWidgetCondition implements Condition { |
| private final FlexibleStringExpander classExdr; |
| private final FlexibleMapAccessor<Object> fieldAcsr; |
| private final FlexibleStringExpander methodExdr; |
| |
| private IfValidateMethod(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| String fieldAcsr = condElement.getAttribute("field"); |
| if (fieldAcsr.isEmpty()) |
| fieldAcsr = condElement.getAttribute("field-name"); |
| this.fieldAcsr = FlexibleMapAccessor.getInstance(fieldAcsr); |
| this.methodExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("method")); |
| this.classExdr = FlexibleStringExpander.getInstance(condElement.getAttribute("class")); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| String methodName = this.methodExdr.expandString(context); |
| String className = this.classExdr.expandString(context); |
| Object fieldVal = this.fieldAcsr.get(context); |
| String fieldString = null; |
| if (fieldVal != null) { |
| try { |
| fieldString = (String) ObjectType.simpleTypeConvert(fieldVal, "String", null, |
| (TimeZone) context.get("timeZone"), (Locale) context.get("locale"), true); |
| } catch (GeneralException e) { |
| Debug.logError(e, "Could not convert object to String, using empty String", module); |
| } |
| } |
| // always use an empty string by default |
| if (fieldString == null) |
| fieldString = ""; |
| Class<?>[] paramTypes = new Class[] { String.class }; |
| Object[] params = new Object[] { fieldString }; |
| Class<?> valClass; |
| try { |
| valClass = ObjectType.loadClass(className); |
| } catch (ClassNotFoundException cnfe) { |
| Debug.logError("Could not find validation class: " + className, module); |
| return false; |
| } |
| Method valMethod; |
| try { |
| valMethod = valClass.getMethod(methodName, paramTypes); |
| } catch (NoSuchMethodException cnfe) { |
| Debug.logError("Could not find validation method: " + methodName + " of class " + className, module); |
| return false; |
| } |
| Boolean resultBool = Boolean.FALSE; |
| try { |
| resultBool = (Boolean) valMethod.invoke(null, params); |
| } catch (Exception e) { |
| Debug.logError(e, "Error in IfValidationMethod " + methodName + " of class " + className |
| + ", defaulting to false ", module); |
| } |
| return resultBool.booleanValue(); |
| } |
| } |
| |
| /** |
| * Models the <not> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class Not extends ModelWidgetCondition implements Condition { |
| private final Condition subCondition; |
| |
| private Not(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| Element firstChildElement = UtilXml.firstChildElement(condElement); |
| this.subCondition = factory.newInstance(modelWidget, firstChildElement); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| return !this.subCondition.eval(context); |
| } |
| } |
| |
| /** |
| * Models the <or> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class Or extends ModelWidgetCondition implements Condition { |
| private final List<Condition> subConditions; |
| |
| private Or(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| this.subConditions = readSubConditions(factory, modelWidget, condElement); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| // return true for the first one in the list that is true, basic or algo |
| for (Condition subCondition : this.subConditions) { |
| if (subCondition.eval(context)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Models the <xor> element. |
| * |
| * @see <code>widget-common.xsd</code> |
| */ |
| public static class Xor extends ModelWidgetCondition implements Condition { |
| private final List<Condition> subConditions; |
| |
| private Xor(ConditionFactory factory, ModelWidget modelWidget, Element condElement) { |
| super(factory, modelWidget, condElement); |
| this.subConditions = readSubConditions(factory, modelWidget, condElement); |
| } |
| |
| @Override |
| public boolean eval(Map<String, Object> context) { |
| // if more than one is true stop immediately and return false; if all are false return false; if only one is true return true |
| boolean foundOneTrue = false; |
| for (Condition subCondition : this.subConditions) { |
| if (subCondition.eval(context)) { |
| if (foundOneTrue) { |
| // now found two true, so return false |
| return false; |
| } else { |
| foundOneTrue = true; |
| } |
| } |
| } |
| return foundOneTrue; |
| } |
| } |
| } |