| /******************************************************************************* |
| * 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.common.scripting; |
| |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.script.ScriptContext; |
| import javax.script.ScriptException; |
| |
| import org.apache.ofbiz.base.util.Assert; |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.ScriptHelper; |
| import org.apache.ofbiz.base.util.UtilGenerics; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.entity.Delegator; |
| import org.apache.ofbiz.entity.GenericEntityException; |
| import org.apache.ofbiz.entity.GenericPK; |
| import org.apache.ofbiz.entity.GenericValue; |
| import org.apache.ofbiz.entity.model.ModelEntity; |
| import org.apache.ofbiz.entity.util.EntityQuery; |
| import org.apache.ofbiz.service.GenericServiceException; |
| import org.apache.ofbiz.service.ModelService; |
| import org.apache.ofbiz.service.ServiceUtil; |
| |
| /** |
| * An implementation of the <code>ScriptHelper</code> interface. |
| */ |
| public final class ScriptHelperImpl implements ScriptHelper { |
| |
| public static final String module = ScriptHelperImpl.class.getName(); |
| private static final Map<String, ? extends Object> EMPTY_ARGS = Collections.unmodifiableMap(new HashMap<String, Object>()); |
| |
| private static GenericValue runFindByPrimaryKey(ModelEntity modelEntity, ContextHelper ctxHelper, boolean useCache, boolean autoFieldMap, |
| Map<String, ? extends Object> fieldMap, List<String> selectFieldList) throws ScriptException { |
| Map<String, Object> entityContext = new HashMap<String, Object>(); |
| Delegator delegator = ctxHelper.getDelegator(); |
| Map<String, Object> context = ctxHelper.getBindings(); |
| if (autoFieldMap) { |
| GenericValue tempVal = delegator.makeValue(modelEntity.getEntityName()); |
| Object parametersObj = context.get("parameters"); |
| if (parametersObj != null && parametersObj instanceof Map<?, ?>) { |
| tempVal.setAllFields(UtilGenerics.checkMap(parametersObj), true, null, Boolean.TRUE); |
| } |
| tempVal.setAllFields(context, true, null, Boolean.TRUE); |
| entityContext.putAll(tempVal); |
| } |
| if (fieldMap != null) { |
| entityContext.putAll(fieldMap); |
| } |
| entityContext.put("locale", context.get("locale")); |
| entityContext.put("timeZone", context.get("timeZone")); |
| modelEntity.convertFieldMapInPlace(entityContext, delegator); |
| entityContext.remove("locale"); |
| entityContext.remove("timeZone"); |
| Set<String> fieldsToSelect = null; |
| if (selectFieldList != null) { |
| fieldsToSelect = new HashSet<String>(selectFieldList); |
| } |
| if (fieldsToSelect != null && useCache) { |
| String errMsg = "Error running script " + ctxHelper.getScriptName() + ": Problem invoking the findOne method: Cannot specify selectFieldList argument when useCache is set to true "; |
| Debug.logWarning(errMsg, module); |
| throw new ScriptException(errMsg); |
| } |
| GenericValue valueOut = null; |
| GenericPK entityPK = delegator.makePK(modelEntity.getEntityName(), entityContext); |
| if (entityPK.containsPrimaryKey(true)) { |
| try { |
| if (useCache) { |
| valueOut = EntityQuery.use(delegator).from(entityPK.getEntityName()).where(entityPK).cache(true).queryOne(); |
| } else { |
| if (fieldsToSelect != null) { |
| valueOut = delegator.findByPrimaryKeyPartial(entityPK, fieldsToSelect); |
| } else { |
| valueOut = EntityQuery.use(delegator).from(entityPK.getEntityName()).where(entityPK).queryOne(); |
| } |
| } |
| } catch (GenericEntityException e) { |
| String errMsg = "Error running script " + ctxHelper.getScriptName() + ": Problem invoking the findOne method: " + e.getMessage(); |
| Debug.logWarning(e, errMsg, module); |
| throw new ScriptException(errMsg); |
| } |
| } else { |
| if (Debug.warningOn()) { |
| Debug.logWarning("Error running script " + ctxHelper.getScriptName() + ": Returning null because found incomplete primary key in find: " + entityPK, module); |
| } |
| } |
| return valueOut; |
| } |
| |
| private final ContextHelper ctxHelper; |
| |
| public ScriptHelperImpl(ScriptContext context) { |
| this.ctxHelper = new ContextHelper(context); |
| } |
| |
| public Map<String, ? extends Object> createServiceMap(String serviceName, Map<String, ? extends Object> inputMap) throws ScriptException { |
| Assert.notNull("serviceName", serviceName, "inputMap", inputMap); |
| Map<String, Object> toMap = new HashMap<String, Object>(); |
| ModelService modelService = null; |
| try { |
| modelService = ctxHelper.getDispatcher().getDispatchContext().getModelService(serviceName); |
| } catch (GenericServiceException e) { |
| String errMsg = "Error running script " + ctxHelper.getScriptName() + ": Problem invoking the createServiceMap method: get service definition for service name [" + serviceName + "]: " + e.getMessage(); |
| Debug.logWarning(e, errMsg, module); |
| throw new ScriptException(errMsg); |
| } |
| toMap.putAll(modelService.makeValid(inputMap, "IN", true, UtilGenerics.checkList(ctxHelper.getErrorMessages()), ctxHelper.getTimeZone(), ctxHelper.getLocale())); |
| return toMap; |
| } |
| |
| @Override |
| public void error(String message) { |
| if (ctxHelper.isEvent()) { |
| ctxHelper.putResult("_error_message_", ctxHelper.expandString(message)); |
| ctxHelper.putResult("_response_code_", "error"); |
| } else if (ctxHelper.isService()) { |
| ctxHelper.putResults(ServiceUtil.returnError(ctxHelper.expandString(message))); |
| } |
| } |
| |
| @Override |
| public String evalString(String original) { |
| return ctxHelper.expandString(original); |
| } |
| |
| @Override |
| public void failure(String message) { |
| if (ctxHelper.isEvent()) { |
| ctxHelper.putResult("_error_message_", ctxHelper.expandString(message)); |
| ctxHelper.putResult("_response_code_", "fail"); |
| } else if (ctxHelper.isService()) { |
| ctxHelper.putResults(ServiceUtil.returnFailure(ctxHelper.expandString(message))); |
| } |
| } |
| |
| public List<Map<String, Object>> findList(String entityName, Map<String, ? extends Object> fields) throws ScriptException { |
| try { |
| return UtilGenerics.checkList(ctxHelper.getDelegator().findByAnd(entityName, fields, null, false)); |
| } catch (GenericEntityException e) { |
| String errMsg = "Error running script " + ctxHelper.getScriptName() + ": Problem invoking the findList method: " + e.getMessage(); |
| Debug.logWarning(e, errMsg, module); |
| throw new ScriptException(errMsg); |
| } |
| } |
| |
| public Map<String, Object> findOne(String entityName) throws ScriptException { |
| return findOne(entityName, null, EMPTY_ARGS); |
| } |
| |
| public Map<String, Object> findOne(String entityName, Map<String, ? extends Object> fields, Map<String, ? extends Object> args) throws ScriptException { |
| Assert.notNull("entityName", entityName); |
| if (args == null) { |
| args = EMPTY_ARGS; |
| } |
| boolean useCache = "true".equals(args.get("useCache")); |
| boolean autoFieldMap = !"false".equals(args.get("autoFieldMap")); |
| List<String> selectFieldList = UtilGenerics.checkList(args.get("selectFieldList")); |
| ModelEntity modelEntity = ctxHelper.getDelegator().getModelEntity(entityName); |
| if (modelEntity == null) { |
| throw new ScriptException("Error running script " + ctxHelper.getScriptName() + " - no entity definition found for entity name [" + entityName + "]"); |
| } |
| return runFindByPrimaryKey(modelEntity, ctxHelper, useCache, autoFieldMap, fields, selectFieldList); |
| } |
| |
| public void logError(String message) { |
| String expandedMessage = ctxHelper.expandString(message); |
| Debug.logError("[".concat(ctxHelper.getScriptName()).concat("] ").concat(expandedMessage), module); |
| } |
| |
| public void logInfo(String message) { |
| String expandedMessage = ctxHelper.expandString(message); |
| Debug.logInfo("[".concat(ctxHelper.getScriptName()).concat("] ").concat(expandedMessage), module); |
| } |
| |
| public void logWarning(String message) { |
| String expandedMessage = ctxHelper.expandString(message); |
| Debug.logWarning("[".concat(ctxHelper.getScriptName()).concat("] ").concat(expandedMessage), module); |
| } |
| |
| public Map<String, Object> makeValue(String entityName) throws ScriptException { |
| return ctxHelper.getDelegator().makeValidValue(entityName); |
| } |
| |
| public Map<String, Object> makeValue(String entityName, Map<String, Object> fields) throws ScriptException { |
| return ctxHelper.getDelegator().makeValidValue(entityName, fields); |
| } |
| |
| public Map<String, ? extends Object> runService(String serviceName, Map<String, ? extends Object> inputMap) throws ScriptException { |
| return runService(serviceName, inputMap, EMPTY_ARGS); |
| } |
| |
| public Map<String, ? extends Object> runService(String serviceName, Map<String, ? extends Object> inputMap, Map<String, ? extends Object> args) throws ScriptException { |
| Assert.notNull("serviceName", serviceName, "args", args); |
| boolean includeUserLogin = !"false".equals(args.get("includeUserLoginStr")); |
| String requireNewTransactionStr = (String) args.get("requireNewTransaction"); |
| int transactionTimeout = -1; |
| if (UtilValidate.isNotEmpty(requireNewTransactionStr)) { |
| String timeoutStr = (String) args.get("transactionTimout"); |
| if (UtilValidate.isNotEmpty(timeoutStr)) { |
| try { |
| transactionTimeout = Integer.parseInt(timeoutStr); |
| } catch (NumberFormatException e) { |
| Debug.logWarning(e, "Setting timeout to 0 (default)", module); |
| transactionTimeout = 0; |
| } |
| } |
| } |
| Map<String, Object> inMap = new HashMap<String, Object>(inputMap); |
| if (includeUserLogin && !inMap.containsKey("userLogin")) { |
| GenericValue userLogin = ctxHelper.getUserLogin(); |
| if (userLogin != null) { |
| inMap.put("userLogin", userLogin); |
| } |
| } |
| if (!inMap.containsKey("locale") && ctxHelper.getLocale() != null) { |
| inMap.put("locale", ctxHelper.getLocale()); |
| } |
| if (!inMap.containsKey("timeZone") && ctxHelper.getTimeZone() != null) { |
| inMap.put("timeZone", ctxHelper.getTimeZone()); |
| } |
| Map<String, Object> result = null; |
| try { |
| if (UtilValidate.isEmpty(requireNewTransactionStr) && transactionTimeout < 0) { |
| result = ctxHelper.getDispatcher().runSync(serviceName, inMap); |
| } else { |
| ModelService modelService = ctxHelper.getDispatcher().getDispatchContext().getModelService(serviceName); |
| boolean requireNewTransaction = modelService.requireNewTransaction; |
| int timeout = modelService.transactionTimeout; |
| if (UtilValidate.isNotEmpty(requireNewTransactionStr)) { |
| requireNewTransaction = "true".equals(requireNewTransactionStr); |
| } |
| if (transactionTimeout >= 0) { |
| timeout = transactionTimeout; |
| } |
| result = ctxHelper.getDispatcher().runSync(serviceName, inMap, timeout, requireNewTransaction); |
| } |
| } catch (GenericServiceException e) { |
| String errMsg = "Error running script " + ctxHelper.getScriptName() + " [problem invoking the [" + serviceName + "] service: " + e.getMessage(); |
| Debug.logWarning(e, errMsg, module); |
| throw new ScriptException(errMsg); |
| } |
| return result; |
| } |
| |
| @Override |
| public void success() { |
| if (ctxHelper.isEvent()) { |
| ctxHelper.putResult("_response_code_", "success"); |
| } else if (ctxHelper.isService()) { |
| ctxHelper.putResults(ServiceUtil.returnSuccess()); |
| } |
| } |
| |
| @Override |
| public void success(String message) { |
| if (ctxHelper.isEvent()) { |
| ctxHelper.putResult("_event_message_", ctxHelper.expandString(message)); |
| ctxHelper.putResult("_response_code_", "success"); |
| } else if (ctxHelper.isService()) { |
| ctxHelper.putResults(ServiceUtil.returnSuccess(ctxHelper.expandString(message))); |
| } |
| } |
| } |