Package org.ofbiz.service.eca

Source Code of org.ofbiz.service.eca.ServiceEcaAction

/*******************************************************************************
* 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.service.eca;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.transaction.xa.XAException;

import javolution.util.FastMap;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ModelService;
import org.ofbiz.service.ServiceUtil;
import org.ofbiz.service.ServiceXaWrapper;
import org.w3c.dom.Element;

/**
* ServiceEcaAction
*/
@SuppressWarnings("serial")
public class ServiceEcaAction implements java.io.Serializable {

    public static final String module = ServiceEcaAction.class.getName();

    protected String eventName = null;
    protected String serviceName = null;
    protected String serviceMode = null;
    protected String resultMapName = null;
    protected String runAsUser = null;

    protected boolean newTransaction = false;
    protected boolean resultToContext = true;
    protected boolean resultToResult = false;
    protected boolean ignoreFailure = false;
    protected boolean ignoreError = false;
    protected boolean persist = false;

    protected ServiceEcaAction() {}

    public ServiceEcaAction(Element action, String event) {
        this.eventName = event;
        this.serviceName = action.getAttribute("service");
        this.serviceMode = action.getAttribute("mode");
        this.runAsUser = action.getAttribute("run-as-user");
        // support the old, inconsistent attribute name
        if (UtilValidate.isEmpty(this.runAsUser)) this.runAsUser = action.getAttribute("runAsUser");
        this.resultMapName = action.getAttribute("result-map-name");

        // default is true, so anything but false is true
        this.resultToContext = !"false".equals(action.getAttribute("result-to-context"));
        // default is false, so anything but true is false
        this.resultToResult = "true".equals(action.getAttribute("result-to-result"));
        this.newTransaction = !"false".equals(action.getAttribute("new-transaction"));
        this.ignoreFailure = !"false".equals(action.getAttribute("ignore-failure"));
        this.ignoreError = !"false".equals(action.getAttribute("ignore-error"));
        this.persist = "true".equals(action.getAttribute("persist"));
    }

    public String getServiceName() {
        return this.serviceName;
    }

    public String getServiceMode() {
        return this.serviceMode;
    }

    public boolean isPersist() {
        return this.persist;
    }

    public String getShortDisplayDescription() {
        return this.serviceName + "[" + this.serviceMode + (this.persist ? "-persist" : "") + "]";
    }

    public boolean runAction(String selfService, DispatchContext dctx, Map<String, Object> context, Map<String, Object> result) throws GenericServiceException {
        if (serviceName.equals(selfService)) {
            throw new GenericServiceException("Cannot invoke self on ECA.");
        }

        // pull out context parameters needed for this service.
        Map<String, Object> actionContext = dctx.getModelService(serviceName).makeValid(context, ModelService.IN_PARAM);

        // set the userLogin object in the context
        actionContext.put("userLogin", ServiceUtil.getUserLogin(dctx, actionContext, runAsUser));

        Map<String, Object> actionResult = null;
        LocalDispatcher dispatcher = dctx.getDispatcher();
        // if SECAs have been turned off, then just return true which has same effect as if secas ran successfully
        if (dispatcher.isEcasDisabled()) {
            Debug.logWarning("SECAs have been disabled on purpose and will not be run for [" + serviceName + "]", module);
            return true;
        }

        if (eventName.startsWith("global-")) {
            // XA resource ECA
            ServiceXaWrapper xaw = new ServiceXaWrapper(dctx);
            if (eventName.equals("global-rollback")) {
                xaw.setRollbackService(serviceName, runAsUser, context, "async".equals(serviceMode), persist); // using the actual context so we get updates
            } else if (eventName.equals("global-commit")) {
                xaw.setCommitService(serviceName, runAsUser, context, "async".equals(serviceMode), persist);   // using the actual context so we get updates
            } else if (eventName.equals("global-commit-post-run")) {
                xaw.setCommitService(serviceName, runAsUser, context, "async".equals(serviceMode), persist);   // using the actual context so we get updates
            }
            try {
                xaw.enlist();
            } catch (XAException e) {
                throw new GenericServiceException("Unable to enlist ServiceXaWrapper with transaction", e);
            }
        } else {
            // standard ECA
            if (this.serviceMode.equals("sync")) {
                if (newTransaction) {
                    actionResult = dispatcher.runSync(this.serviceName, actionContext, -1, true);
                } else {
                    actionResult = dispatcher.runSync(this.serviceName, actionContext);
                }
            } else if (this.serviceMode.equals("async")) {
                dispatcher.runAsync(serviceName, actionContext, persist);
            }
        }

        // put the results in to the defined map
        if (UtilValidate.isNotEmpty(resultMapName)) {
            Map<String, Object> resultMap = UtilGenerics.checkMap(context.get(resultMapName));
            if (resultMap == null) {
                resultMap = FastMap.newInstance();
            }
            resultMap.putAll(dctx.getModelService(this.serviceName).makeValid(actionResult, ModelService.OUT_PARAM, false, null));
            context.put(resultMapName, resultMap);
        }

        // use the result to update the context fields.
        if (resultToContext) {
            context.putAll(dctx.getModelService(this.serviceName).makeValid(actionResult, ModelService.OUT_PARAM, false, null));
        }

        // use the result to update the result fields
        if (resultToResult) {
            Map<String, Object> normalizedActionResult = dctx.getModelService(selfService).makeValid(actionResult, ModelService.OUT_PARAM, false, null);
            // don't copy over the error messages, use the combining code to do that later
            normalizedActionResult.remove(ModelService.ERROR_MESSAGE);
            normalizedActionResult.remove(ModelService.ERROR_MESSAGE_LIST);
            normalizedActionResult.remove(ModelService.ERROR_MESSAGE_MAP);
            normalizedActionResult.remove("failMessage");
            result.putAll(normalizedActionResult);
        }

        // if we aren't ignoring errors check it here...
        boolean success = true;
        // don't do this if resultToResult, will already be copied over
        if (actionResult != null && !resultToResult) {
            if (!ignoreFailure) {
                if (ModelService.RESPOND_FAIL.equals(actionResult.get(ModelService.RESPONSE_MESSAGE))) {
                    if (result != null) {
                        result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_FAIL);
                    }
                    success = false;
                }
            }
            if (!ignoreError) {
                if (ModelService.RESPOND_ERROR.equals(actionResult.get(ModelService.RESPONSE_MESSAGE))) {
                    if (result != null) {
                        result.put(ModelService.RESPONSE_MESSAGE, ModelService.RESPOND_ERROR);
                    }
                    success = false;
                }
            }
        }

        // copy/combine error messages on error/failure (!success) or on resultToResult to combine any error info coming out, regardless of success status
        if ((!success || resultToResult) && UtilValidate.isNotEmpty(actionResult)) {
            String errorMessage = (String) actionResult.get(ModelService.ERROR_MESSAGE);
            String failMessage = (String) actionResult.get("failMessage");
            List<? extends Object> errorMessageList = UtilGenerics.checkList(actionResult.get(ModelService.ERROR_MESSAGE_LIST));
            Map<String, ? extends Object> errorMessageMap = UtilGenerics.checkMap(actionResult.get(ModelService.ERROR_MESSAGE_MAP));

            // do something with the errorMessage
            if (UtilValidate.isNotEmpty(errorMessage)) {
                if (UtilValidate.isEmpty(result.get(ModelService.ERROR_MESSAGE))) {
                    result.put(ModelService.ERROR_MESSAGE, errorMessage);
                } else {
                    List<Object> origErrorMessageList = UtilGenerics.checkList(result.get(ModelService.ERROR_MESSAGE_LIST));
                    if (origErrorMessageList == null) {
                        origErrorMessageList = new LinkedList<Object>();
                        result.put(ModelService.ERROR_MESSAGE_LIST, origErrorMessageList);
                    }
                    origErrorMessageList.add(0, errorMessage);
                }
            }
            // do something with the errorMessageList
            if (UtilValidate.isNotEmpty(errorMessageList)) {
                List<Object> origErrorMessageList = UtilGenerics.checkList(result.get(ModelService.ERROR_MESSAGE_LIST));
                if (origErrorMessageList == null) {
                    result.put(ModelService.ERROR_MESSAGE_LIST, errorMessageList);
                } else {
                    origErrorMessageList.addAll(errorMessageList);
                }
            }
            // do something with the errorMessageMap
            if (UtilValidate.isNotEmpty(errorMessageMap)) {
                Map<String, Object> origErrorMessageMap = UtilGenerics.checkMap(result.get(ModelService.ERROR_MESSAGE_MAP));
                if (origErrorMessageMap == null) {
                    result.put(ModelService.ERROR_MESSAGE_MAP, errorMessageMap);
                } else {
                    origErrorMessageMap.putAll(errorMessageMap);
                }
            }
            // do something with the fail message
            if (UtilValidate.isNotEmpty(failMessage)) {
                String origFailMessage = (String) result.get("failMessage");
                if (UtilValidate.isEmpty(origFailMessage)) {
                    result.put("failMessage", failMessage);
                } else {
                    result.put("failMessage", origFailMessage + ", " + failMessage);
                }
            }
        }

        return success;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof ServiceEcaAction) {
            ServiceEcaAction other = (ServiceEcaAction) obj;

            if (!UtilValidate.areEqual(this.eventName, other.eventName)) return false;
            if (!UtilValidate.areEqual(this.serviceName, other.serviceName)) return false;
            if (!UtilValidate.areEqual(this.serviceMode, other.serviceMode)) return false;
            if (!UtilValidate.areEqual(this.resultMapName, other.resultMapName)) return false;
            if (!UtilValidate.areEqual(this.runAsUser, other.runAsUser)) return false;

            if (this.newTransaction != other.newTransaction) return false;
            if (this.resultToContext != other.resultToContext) return false;
            if (this.resultToResult != other.resultToResult) return false;
            if (this.ignoreFailure != other.ignoreFailure) return false;
            if (this.ignoreError != other.ignoreError) return false;
            if (this.persist != other.persist) return false;

            return true;
        } else {
            return false;
        }
    }
}
TOP

Related Classes of org.ofbiz.service.eca.ServiceEcaAction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.