| /******************************************************************************* |
| * 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.ofbiz.entityext.eca; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javolution.util.FastList; |
| import javolution.util.FastMap; |
| import javolution.util.FastSet; |
| |
| import org.ofbiz.base.util.Debug; |
| import org.ofbiz.base.util.UtilXml; |
| import org.ofbiz.entity.GenericEntity; |
| import org.ofbiz.entity.GenericEntityException; |
| import org.ofbiz.service.DispatchContext; |
| import org.w3c.dom.Element; |
| |
| /** |
| * EntityEcaRule |
| */ |
| public class EntityEcaRule implements java.io.Serializable { |
| |
| public static final String module = EntityEcaRule.class.getName(); |
| |
| protected String entityName = null; |
| protected String operationName = null; |
| protected String eventName = null; |
| protected boolean runOnError = false; |
| protected List<EntityEcaCondition> conditions = FastList.newInstance(); |
| protected List<Object> actionsAndSets = FastList.newInstance(); |
| protected boolean enabled = true; |
| |
| protected EntityEcaRule() {} |
| |
| public EntityEcaRule(Element eca) { |
| this.entityName = eca.getAttribute("entity"); |
| this.operationName = eca.getAttribute("operation"); |
| this.eventName = eca.getAttribute("event"); |
| this.runOnError = "true".equals(eca.getAttribute("run-on-error")); |
| |
| for (Element element: UtilXml.childElementList(eca, "condition")) { |
| conditions.add(new EntityEcaCondition(element, true)); |
| } |
| |
| for (Element element: UtilXml.childElementList(eca, "condition-field")) { |
| conditions.add(new EntityEcaCondition(element, false)); |
| } |
| |
| if (Debug.verboseOn()) Debug.logVerbose("Conditions: " + conditions, module); |
| |
| Set<String> nameSet = FastSet.newInstance(); |
| nameSet.add("set"); |
| nameSet.add("action"); |
| for (Element actionOrSetElement: UtilXml.childElementList(eca, nameSet)) { |
| if ("action".equals(actionOrSetElement.getNodeName())) { |
| this.actionsAndSets.add(new EntityEcaAction(actionOrSetElement)); |
| } else { |
| this.actionsAndSets.add(new EntityEcaSetField(actionOrSetElement)); |
| } |
| } |
| |
| if (Debug.verboseOn()) Debug.logVerbose("actions and sets (intermixed): " + actionsAndSets, module); |
| } |
| |
| public void eval(String currentOperation, DispatchContext dctx, GenericEntity value, boolean isError, Set<String> actionsRun) throws GenericEntityException { |
| if (!enabled) { |
| Debug.logInfo("Entity ECA [" + this.entityName + "] on [" + this.eventName + "] is disabled; not running.", module); |
| return; |
| } |
| |
| //Debug.logInfo("eval eeca rule: operation=" + currentOperation + ", in event=" + this.eventName + ", on entity=" + this.entityName + ", for value=" + value, module); |
| if (isError && !this.runOnError) { |
| return; |
| } |
| |
| if (!"any".equals(this.operationName) && this.operationName.indexOf(currentOperation) == -1) { |
| return; |
| } |
| |
| Map<String, Object> context = FastMap.newInstance(); |
| context.putAll(value); |
| |
| boolean allCondTrue = true; |
| for (EntityEcaCondition ec: conditions) { |
| if (!ec.eval(dctx, value)) { |
| allCondTrue = false; |
| break; |
| } |
| } |
| |
| if (allCondTrue) { |
| for (Object actionOrSet: actionsAndSets) { |
| if (actionOrSet instanceof EntityEcaAction) { |
| EntityEcaAction ea = (EntityEcaAction) actionOrSet; |
| // in order to enable OR logic without multiple calls to the given service, |
| //only execute a given service name once per service call phase |
| if (!actionsRun.contains(ea.serviceName)) { |
| if (Debug.infoOn()) Debug.logInfo("Running Entity ECA Service: " + ea.serviceName + ", triggered by rule on Entity: " + value.getEntityName(), module); |
| ea.runAction(dctx, context, value); |
| actionsRun.add(ea.serviceName); |
| } |
| } else { |
| EntityEcaSetField sf = (EntityEcaSetField) actionOrSet; |
| sf.eval(context); |
| } |
| } |
| } |
| } |
| |
| public void setEnabled(boolean enabled) { |
| this.enabled = enabled; |
| } |
| |
| public boolean isEnabled() { |
| return this.enabled; |
| } |
| } |