001/*
002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     vpasquier <vpasquier@nuxeo.com>
018 *     slacoin <slacoin@nuxeo.com>
019 */
020package org.nuxeo.ecm.automation.core.trace;
021
022import java.util.Arrays;
023import java.util.HashMap;
024import java.util.LinkedList;
025import java.util.List;
026import java.util.Map;
027
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.nuxeo.ecm.automation.OperationContext;
031import org.nuxeo.ecm.automation.OperationType;
032import org.nuxeo.ecm.automation.core.impl.InvokableMethod;
033import org.nuxeo.ecm.automation.core.scripting.Expression;
034
035/**
036 * @since 5.7.3
037 */
038public class Call {
039
040    private static final Log log = LogFactory.getLog(Call.class);
041
042    /**
043     * Black listing of mvel expressions which should not be evaluated by the Automation traces for debugging
044     * purpose
045     *
046     * @since 8.1
047     */
048    public static final String[] MVEL_BLACK_LIST_EXPR = new String[] { "getNextId" };
049
050    protected final String chainId;
051
052    protected final String aliases;
053
054    protected final OperationType type;
055
056    protected final InvokableMethod method;
057
058    protected final Map<String, Object> parameters;
059
060    protected final Map<String, Object> variables;
061
062    protected final List<Trace> nested = new LinkedList<Trace>();
063
064    protected final Object input;
065
066    public Call(OperationType chain, OperationContext context, OperationType type, InvokableMethod method,
067            Map<String, Object> parms) {
068        this.type = type;
069        variables = (context != null) ? new HashMap<>(context) : null;
070        this.method = method;
071        input = (context != null) ? context.getInput() : null;
072        parameters = new HashMap<>();
073        if (parms != null) {
074            for (String paramId : parms.keySet()) {
075                Object paramValue = parms.get(paramId);
076                if (paramValue instanceof Expression) {
077                    try {
078                        ExpressionParameter expressionParameter = null;
079                        for (String mvelExpr : MVEL_BLACK_LIST_EXPR) {
080                            if (((Expression) paramValue).getExpr().contains(mvelExpr)) {
081                                expressionParameter = new ExpressionParameter(paramId, String.format(
082                                        "Cannot be evaluated in traces when using '%s' expression", mvelExpr));
083                                parameters.put(paramId, expressionParameter);
084                                break;
085                            }
086                        }
087                        if (parameters.get(paramId) == null) {
088                            expressionParameter = new ExpressionParameter(paramId,
089                                    ((Expression) paramValue).eval(context));
090                            parameters.put(paramId, expressionParameter);
091
092                        }
093                    } catch (RuntimeException e) {
094                        log.warn("Cannot evaluate mvel expression for parameter: " + paramId, e);
095                    }
096                } else {
097                    parameters.put(paramId, paramValue);
098                }
099            }
100        }
101        chainId = (chain != null) ? chain.getId() : "Not bound to a chain";
102        aliases = (chain != null) ? Arrays.toString(chain.getAliases()) : null;
103    }
104
105    /**
106     * @since 7.1
107     */
108    public class ExpressionParameter {
109
110        protected final String parameterId;
111
112        protected final Object parameterValue;
113
114        public ExpressionParameter(String parameterId, Object parameterValue) {
115            this.parameterId = parameterId;
116            this.parameterValue = parameterValue;
117        }
118
119        public Object getParameterValue() {
120            return parameterValue;
121        }
122
123        public String getParameterId() {
124
125            return parameterId;
126        }
127    }
128
129    public OperationType getType() {
130        return type;
131    }
132
133    public InvokableMethod getMethod() {
134        return method;
135    }
136
137    public Map<String, Object> getParmeters() {
138        return parameters;
139    }
140
141    public Map<String, Object> getVariables() {
142        return variables;
143    }
144
145    public Object getInput() {
146        return input;
147    }
148
149    public List<Trace> getNested() {
150        return nested;
151    }
152
153    public String getChainId() {
154        return chainId;
155    }
156
157    public String getAliases() {
158        return aliases;
159    }
160
161}