use of org.apache.ofbiz.service.DispatchContext in project ofbiz-framework by apache.
the class ServiceEventHandler method invoke.
/**
* @see org.apache.ofbiz.webapp.event.EventHandler#invoke(ConfigXMLReader.Event, ConfigXMLReader.RequestMap, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
public String invoke(Event event, RequestMap requestMap, HttpServletRequest request, HttpServletResponse response) throws EventHandlerException {
// make sure we have a valid reference to the Service Engine
LocalDispatcher dispatcher = (LocalDispatcher) request.getAttribute("dispatcher");
if (dispatcher == null) {
throw new EventHandlerException("The local service dispatcher is null");
}
DispatchContext dctx = dispatcher.getDispatchContext();
if (dctx == null) {
throw new EventHandlerException("Dispatch context cannot be found");
}
// get the details for the service(s) to call
String mode = SYNC;
String serviceName = null;
if (UtilValidate.isEmpty(event.path)) {
mode = SYNC;
} else {
mode = event.path;
}
// make sure we have a defined service to call
serviceName = event.invoke;
if (serviceName == null) {
throw new EventHandlerException("Service name (eventMethod) cannot be null");
}
if (Debug.verboseOn())
Debug.logVerbose("[Set mode/service]: " + mode + "/" + serviceName, module);
// some needed info for when running the service
Locale locale = UtilHttp.getLocale(request);
TimeZone timeZone = UtilHttp.getTimeZone(request);
VisualTheme visualTheme = UtilHttp.getVisualTheme(request);
HttpSession session = request.getSession();
GenericValue userLogin = (GenericValue) session.getAttribute("userLogin");
// get the service model to generate context
ModelService model = null;
try {
model = dctx.getModelService(serviceName);
} catch (GenericServiceException e) {
throw new EventHandlerException("Problems getting the service model", e);
}
if (model == null) {
throw new EventHandlerException("Problems getting the service model");
}
if (Debug.verboseOn()) {
Debug.logVerbose("[Processing]: SERVICE Event", module);
Debug.logVerbose("[Using delegator]: " + dispatcher.getDelegator().getDelegatorName(), module);
}
boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
Map<String, Object> multiPartMap = new HashMap<String, Object>();
if (isMultiPart) {
// get the http upload configuration
String maxSizeStr = EntityUtilProperties.getPropertyValue("general", "http.upload.max.size", "-1", dctx.getDelegator());
long maxUploadSize = -1;
try {
maxUploadSize = Long.parseLong(maxSizeStr);
} catch (NumberFormatException e) {
Debug.logError(e, "Unable to obtain the max upload size from general.properties; using default -1", module);
maxUploadSize = -1;
}
// get the http size threshold configuration - files bigger than this will be
// temporarly stored on disk during upload
String sizeThresholdStr = EntityUtilProperties.getPropertyValue("general", "http.upload.max.sizethreshold", "10240", dctx.getDelegator());
// 10K
int sizeThreshold = 10240;
try {
sizeThreshold = Integer.parseInt(sizeThresholdStr);
} catch (NumberFormatException e) {
Debug.logError(e, "Unable to obtain the threshold size from general.properties; using default 10K", module);
sizeThreshold = -1;
}
// directory used to temporarily store files that are larger than the configured size threshold
String tmpUploadRepository = EntityUtilProperties.getPropertyValue("general", "http.upload.tmprepository", "runtime/tmp", dctx.getDelegator());
String encoding = request.getCharacterEncoding();
// check for multipart content types which may have uploaded items
ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory(sizeThreshold, new File(tmpUploadRepository)));
// create the progress listener and add it to the session
FileUploadProgressListener listener = new FileUploadProgressListener();
upload.setProgressListener(listener);
session.setAttribute("uploadProgressListener", listener);
if (encoding != null) {
upload.setHeaderEncoding(encoding);
}
upload.setSizeMax(maxUploadSize);
List<FileItem> uploadedItems = null;
try {
uploadedItems = UtilGenerics.<FileItem>checkList(upload.parseRequest(request));
} catch (FileUploadException e) {
throw new EventHandlerException("Problems reading uploaded data", e);
}
if (uploadedItems != null) {
for (FileItem item : uploadedItems) {
String fieldName = item.getFieldName();
/*
Debug.logInfo("Item Info [" + fieldName + "] : " + item.getName() + " / " + item.getSize() + " / " +
item.getContentType() + " FF: " + item.isFormField(), module);
*/
if (item.isFormField() || item.getName() == null) {
if (multiPartMap.containsKey(fieldName)) {
Object mapValue = multiPartMap.get(fieldName);
if (mapValue instanceof List<?>) {
checkList(mapValue, Object.class).add(item.getString());
} else if (mapValue instanceof String) {
List<String> newList = new LinkedList<String>();
newList.add((String) mapValue);
newList.add(item.getString());
multiPartMap.put(fieldName, newList);
} else {
Debug.logWarning("Form field found [" + fieldName + "] which was not handled!", module);
}
} else {
if (encoding != null) {
try {
multiPartMap.put(fieldName, item.getString(encoding));
} catch (java.io.UnsupportedEncodingException uee) {
Debug.logError(uee, "Unsupported Encoding, using deafault", module);
multiPartMap.put(fieldName, item.getString());
}
} else {
multiPartMap.put(fieldName, item.getString());
}
}
} else {
String fileName = item.getName();
if (fileName.indexOf('\\') > -1 || fileName.indexOf('/') > -1) {
// get just the file name IE and other browsers also pass in the local path
int lastIndex = fileName.lastIndexOf('\\');
if (lastIndex == -1) {
lastIndex = fileName.lastIndexOf('/');
}
if (lastIndex > -1) {
fileName = fileName.substring(lastIndex + 1);
}
}
multiPartMap.put(fieldName, ByteBuffer.wrap(item.get()));
multiPartMap.put("_" + fieldName + "_size", Long.valueOf(item.getSize()));
multiPartMap.put("_" + fieldName + "_fileName", fileName);
multiPartMap.put("_" + fieldName + "_contentType", item.getContentType());
}
}
}
}
// store the multi-part map as an attribute so we can access the parameters
request.setAttribute("multiPartMap", multiPartMap);
Map<String, Object> rawParametersMap = UtilHttp.getCombinedMap(request);
Set<String> urlOnlyParameterNames = UtilHttp.getUrlOnlyParameterMap(request).keySet();
// we have a service and the model; build the context
Map<String, Object> serviceContext = new HashMap<String, Object>();
for (ModelParam modelParam : model.getInModelParamList()) {
String name = modelParam.name;
// don't include userLogin, that's taken care of below
if ("userLogin".equals(name))
continue;
// don't include locale, that is also taken care of below
if ("locale".equals(name))
continue;
// don't include timeZone, that is also taken care of below
if ("timeZone".equals(name))
continue;
// don't include theme, that is also taken care of below
if ("visualTheme".equals(name))
continue;
Object value = null;
if (UtilValidate.isNotEmpty(modelParam.stringMapPrefix)) {
Map<String, Object> paramMap = UtilHttp.makeParamMapWithPrefix(request, multiPartMap, modelParam.stringMapPrefix, null);
value = paramMap;
if (Debug.verboseOn())
Debug.logVerbose("Set [" + modelParam.name + "]: " + paramMap, module);
} else if (UtilValidate.isNotEmpty(modelParam.stringListSuffix)) {
List<Object> paramList = UtilHttp.makeParamListWithSuffix(request, multiPartMap, modelParam.stringListSuffix, null);
value = paramList;
} else {
// first check the multi-part map
value = multiPartMap.get(name);
// next check attributes; do this before parameters so that attribute which can be changed by code can override parameters which can't
if (UtilValidate.isEmpty(value)) {
Object tempVal = request.getAttribute(UtilValidate.isEmpty(modelParam.requestAttributeName) ? name : modelParam.requestAttributeName);
if (tempVal != null) {
value = tempVal;
}
}
// check the request parameters
if (UtilValidate.isEmpty(value)) {
ServiceEventHandler.checkSecureParameter(requestMap, urlOnlyParameterNames, name, session, serviceName, dctx.getDelegator());
// if the service modelParam has allow-html="any" then get this direct from the request instead of in the parameters Map so there will be no canonicalization possibly messing things up
if ("any".equals(modelParam.allowHtml)) {
value = request.getParameter(name);
} else {
// use the rawParametersMap from UtilHttp in order to also get pathInfo parameters, do canonicalization, etc
value = rawParametersMap.get(name);
}
// make any composite parameter data (e.g., from a set of parameters {name_c_date, name_c_hour, name_c_minutes})
if (value == null) {
value = UtilHttp.makeParamValueFromComposite(request, name, locale);
}
}
// then session
if (UtilValidate.isEmpty(value)) {
Object tempVal = request.getSession().getAttribute(UtilValidate.isEmpty(modelParam.sessionAttributeName) ? name : modelParam.sessionAttributeName);
if (tempVal != null) {
value = tempVal;
}
}
// no field found
if (value == null) {
// still null, give up for this one
continue;
}
if (value instanceof String && ((String) value).length() == 0) {
// interpreting empty fields as null values for each in back end handling...
value = null;
}
}
// set even if null so that values will get nulled in the db later on
serviceContext.put(name, value);
}
// get only the parameters for this service - converted to proper type
// TODO: pass in a list for error messages, like could not convert type or not a proper X, return immediately with messages if there are any
List<Object> errorMessages = new LinkedList<Object>();
serviceContext = model.makeValid(serviceContext, ModelService.IN_PARAM, true, errorMessages, timeZone, locale);
if (errorMessages.size() > 0) {
// uh-oh, had some problems...
request.setAttribute("_ERROR_MESSAGE_LIST_", errorMessages);
return "error";
}
// include the UserLogin value object
if (userLogin != null) {
serviceContext.put("userLogin", userLogin);
}
// include the Locale object
if (locale != null) {
serviceContext.put("locale", locale);
}
// include the TimeZone object
if (timeZone != null) {
serviceContext.put("timeZone", timeZone);
}
// include the Theme object
if (visualTheme != null) {
serviceContext.put("visualTheme", visualTheme);
}
// invoke the service
Map<String, Object> result = null;
try {
if (ASYNC.equalsIgnoreCase(mode)) {
dispatcher.runAsync(serviceName, serviceContext);
} else {
result = dispatcher.runSync(serviceName, serviceContext);
}
} catch (ServiceAuthException e) {
// not logging since the service engine already did
request.setAttribute("_ERROR_MESSAGE_", e.getNonNestedMessage());
return "error";
} catch (ServiceValidationException e) {
// not logging since the service engine already did
request.setAttribute("serviceValidationException", e);
if (e.getMessageList() != null) {
request.setAttribute("_ERROR_MESSAGE_LIST_", e.getMessageList());
} else {
request.setAttribute("_ERROR_MESSAGE_", e.getNonNestedMessage());
}
return "error";
} catch (GenericServiceException e) {
Debug.logError(e, "Service invocation error", module);
throw new EventHandlerException("Service invocation error", e.getNested());
}
String responseString = null;
if (result == null) {
responseString = ModelService.RESPOND_SUCCESS;
} else {
if (!result.containsKey(ModelService.RESPONSE_MESSAGE)) {
responseString = ModelService.RESPOND_SUCCESS;
} else {
responseString = (String) result.get(ModelService.RESPONSE_MESSAGE);
}
// set the messages in the request; this will be picked up by messages.ftl and displayed
request.setAttribute("_ERROR_MESSAGE_LIST_", result.get(ModelService.ERROR_MESSAGE_LIST));
request.setAttribute("_ERROR_MESSAGE_MAP_", result.get(ModelService.ERROR_MESSAGE_MAP));
request.setAttribute("_ERROR_MESSAGE_", result.get(ModelService.ERROR_MESSAGE));
request.setAttribute("_EVENT_MESSAGE_LIST_", result.get(ModelService.SUCCESS_MESSAGE_LIST));
request.setAttribute("_EVENT_MESSAGE_", result.get(ModelService.SUCCESS_MESSAGE));
// set the results in the request
for (Map.Entry<String, Object> rme : result.entrySet()) {
String resultKey = rme.getKey();
Object resultValue = rme.getValue();
if (resultKey != null && !ModelService.RESPONSE_MESSAGE.equals(resultKey) && !ModelService.ERROR_MESSAGE.equals(resultKey) && !ModelService.ERROR_MESSAGE_LIST.equals(resultKey) && !ModelService.ERROR_MESSAGE_MAP.equals(resultKey) && !ModelService.SUCCESS_MESSAGE.equals(resultKey) && !ModelService.SUCCESS_MESSAGE_LIST.equals(resultKey)) {
request.setAttribute(resultKey, resultValue);
}
}
}
if (Debug.verboseOn())
Debug.logVerbose("[Event Return]: " + responseString, module);
return responseString;
}
use of org.apache.ofbiz.service.DispatchContext in project ofbiz-framework by apache.
the class EntityAutoEngine method runSync.
/**
* @see org.apache.ofbiz.service.engine.GenericEngine#runSync(java.lang.String, org.apache.ofbiz.service.ModelService, java.util.Map)
*/
@Override
public Map<String, Object> runSync(String localName, ModelService modelService, Map<String, Object> parameters) throws GenericServiceException {
// static java service methods should be: public Map<String, Object> methodName(DispatchContext dctx, Map<String, Object> context)
DispatchContext dctx = dispatcher.getLocalContext(localName);
Locale locale = (Locale) parameters.get("locale");
Map<String, Object> result = ServiceUtil.returnSuccess();
// check the package and method names
if (modelService.invoke == null || !availableInvokeActionNames.contains(modelService.invoke)) {
throw new GenericServiceException("In Service [" + modelService.name + "] the invoke value must be create, update, or delete for entity-auto engine");
}
if (UtilValidate.isEmpty(modelService.defaultEntityName)) {
throw new GenericServiceException("In Service [" + modelService.name + "] you must specify a default-entity-name for entity-auto engine");
}
ModelEntity modelEntity = dctx.getDelegator().getModelEntity(modelService.defaultEntityName);
if (modelEntity == null) {
throw new GenericServiceException("In Service [" + modelService.name + "] the specified default-entity-name [" + modelService.defaultEntityName + "] is not valid");
}
try {
boolean allPksInOnly = true;
List<String> pkFieldNameOutOnly = null;
/* Check for each pk if it's :
* 1. part IN
* 2. or part IN and OUT, but without value but present on parameters map
* Help the engine to determinate the operation to realize for a create call or validate that
* any pk is present for update/delete call.
*/
for (ModelField pkField : modelEntity.getPkFieldsUnmodifiable()) {
ModelParam pkParam = modelService.getParam(pkField.getName());
boolean pkValueInParameters = pkParam.isIn() && UtilValidate.isNotEmpty(parameters.get(pkParam.getFieldName()));
if (pkParam.isOut() && !pkValueInParameters) {
if (pkFieldNameOutOnly == null) {
pkFieldNameOutOnly = new LinkedList<>();
allPksInOnly = false;
}
pkFieldNameOutOnly.add(pkField.getName());
}
}
switch(modelService.invoke) {
case "create":
result = invokeCreate(dctx, parameters, modelService, modelEntity, allPksInOnly, pkFieldNameOutOnly);
break;
case "update":
result = invokeUpdate(dctx, parameters, modelService, modelEntity, allPksInOnly);
break;
case "delete":
result = invokeDelete(dctx, parameters, modelService, modelEntity, allPksInOnly);
break;
case "expire":
result = invokeExpire(dctx, parameters, modelService, modelEntity, allPksInOnly);
if (ServiceUtil.isSuccess(result)) {
result = invokeUpdate(dctx, parameters, modelService, modelEntity, allPksInOnly);
}
break;
default:
break;
}
GenericValue crudValue = (GenericValue) result.get("crudValue");
if (crudValue != null) {
result.remove("crudValue");
result.putAll(modelService.makeValid(crudValue, ModelService.OUT_PARAM));
}
} catch (GeneralException e) {
Debug.logError(e, "Error doing entity-auto operation for entity [" + modelEntity.getEntityName() + "] in service [" + modelService.name + "]: " + e.toString(), module);
return ServiceUtil.returnError(UtilProperties.getMessage(resource, "ServiceEntityAutoOperation", UtilMisc.toMap("entityName", modelEntity.getEntityName(), "serviceName", modelService.name, "errorString", e.toString()), locale));
}
result.put(ModelService.SUCCESS_MESSAGE, ServiceUtil.makeSuccessMessage(result, "", "", "", ""));
return result;
}
use of org.apache.ofbiz.service.DispatchContext in project ofbiz-framework by apache.
the class GroovyEngine method serviceInvoker.
private Map<String, Object> serviceInvoker(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
if (UtilValidate.isEmpty(modelService.location)) {
throw new GenericServiceException("Cannot run Groovy service with empty location");
}
Map<String, Object> params = new HashMap<>();
params.putAll(context);
Map<String, Object> gContext = new HashMap<>();
gContext.putAll(context);
gContext.put(ScriptUtil.PARAMETERS_KEY, params);
DispatchContext dctx = dispatcher.getLocalContext(localName);
gContext.put("dctx", dctx);
gContext.put("security", dctx.getSecurity());
gContext.put("dispatcher", dctx.getDispatcher());
gContext.put("delegator", dispatcher.getDelegator());
try {
ScriptContext scriptContext = ScriptUtil.createScriptContext(gContext, protectedKeys);
ScriptHelper scriptHelper = (ScriptHelper) scriptContext.getAttribute(ScriptUtil.SCRIPT_HELPER_KEY);
if (scriptHelper != null) {
gContext.put(ScriptUtil.SCRIPT_HELPER_KEY, scriptHelper);
}
Script script = InvokerHelper.createScript(GroovyUtil.getScriptClassFromLocation(this.getLocation(modelService)), GroovyUtil.getBinding(gContext));
Object resultObj = null;
if (UtilValidate.isEmpty(modelService.invoke)) {
resultObj = script.run();
} else {
resultObj = script.invokeMethod(modelService.invoke, EMPTY_ARGS);
}
if (resultObj == null) {
resultObj = scriptContext.getAttribute(ScriptUtil.RESULT_KEY);
}
if (resultObj != null && resultObj instanceof Map<?, ?>) {
return cast(resultObj);
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.putAll(modelService.makeValid(scriptContext.getBindings(ScriptContext.ENGINE_SCOPE), ModelService.OUT_PARAM));
return result;
} catch (GeneralException ge) {
throw new GenericServiceException(ge);
} catch (Exception e) {
// make spotting problems very difficult. Disabling this for now in favor of returning a proper exception.
throw new GenericServiceException("Error running Groovy method [" + modelService.invoke + "] in Groovy file [" + modelService.location + "]: ", e);
}
}
use of org.apache.ofbiz.service.DispatchContext in project ofbiz-framework by apache.
the class ScriptEngine method runSync.
@Override
public Map<String, Object> runSync(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
Assert.notNull("localName", localName, "modelService.location", modelService.location, "context", context);
Map<String, Object> params = new HashMap<>();
params.putAll(context);
context.put(ScriptUtil.PARAMETERS_KEY, params);
DispatchContext dctx = dispatcher.getLocalContext(localName);
context.put("dctx", dctx);
context.put("dispatcher", dctx.getDispatcher());
context.put("delegator", dispatcher.getDelegator());
try {
ScriptContext scriptContext = ScriptUtil.createScriptContext(context, protectedKeys);
Object resultObj = ScriptUtil.executeScript(getLocation(modelService), modelService.invoke, scriptContext, null);
if (resultObj == null) {
resultObj = scriptContext.getAttribute(ScriptUtil.RESULT_KEY);
}
if (resultObj != null && resultObj instanceof Map<?, ?>) {
return cast(resultObj);
}
Map<String, Object> result = ServiceUtil.returnSuccess();
result.putAll(modelService.makeValid(scriptContext.getBindings(ScriptContext.ENGINE_SCOPE), ModelService.OUT_PARAM));
return result;
} catch (ScriptException se) {
return ServiceUtil.returnError(se.getMessage());
} catch (Exception e) {
Debug.logWarning(e, "Error invoking service " + modelService.name + ": ", module);
throw new GenericServiceException(e);
}
}
use of org.apache.ofbiz.service.DispatchContext in project ofbiz-framework by apache.
the class StandardJavaEngine method serviceInvoker.
// Invoke the static java method service.
private Object serviceInvoker(String localName, ModelService modelService, Map<String, Object> context) throws GenericServiceException {
// static java service methods should be: public Map<String, Object> methodName(DispatchContext dctx, Map<String, Object> context)
DispatchContext dctx = dispatcher.getLocalContext(localName);
if (modelService == null) {
Debug.logError("ERROR: Null Model Service.", module);
}
if (dctx == null) {
Debug.logError("ERROR: Null DispatchContext.", module);
}
if (context == null) {
Debug.logError("ERROR: Null Service Context.", module);
}
Object result = null;
// check the package and method names
if (modelService.location == null || modelService.invoke == null) {
throw new GenericServiceException("Service [" + modelService.name + "] is missing location and/or invoke values which are required for execution.");
}
// get the classloader to use
ClassLoader cl = null;
if (dctx == null) {
cl = this.getClass().getClassLoader();
} else {
cl = dctx.getClassLoader();
}
try {
Class<?> c = cl.loadClass(this.getLocation(modelService));
Method m = c.getMethod(modelService.invoke, DispatchContext.class, Map.class);
if (Modifier.isStatic(m.getModifiers())) {
result = m.invoke(null, dctx, context);
} else {
result = m.invoke(c.newInstance(), dctx, context);
}
} catch (ClassNotFoundException cnfe) {
throw new GenericServiceException("Cannot find service [" + modelService.name + "] location class", cnfe);
} catch (NoSuchMethodException nsme) {
throw new GenericServiceException("Service [" + modelService.name + "] specified Java method (invoke attribute) does not exist", nsme);
} catch (SecurityException se) {
throw new GenericServiceException("Service [" + modelService.name + "] Access denied", se);
} catch (IllegalAccessException iae) {
throw new GenericServiceException("Service [" + modelService.name + "] Method not accessible", iae);
} catch (IllegalArgumentException iarge) {
throw new GenericServiceException("Service [" + modelService.name + "] Invalid parameter match", iarge);
} catch (InvocationTargetException ite) {
throw new GenericServiceException("Service [" + modelService.name + "] target threw an unexpected exception", ite.getTargetException());
} catch (NullPointerException npe) {
throw new GenericServiceException("Service [" + modelService.name + "] ran into an unexpected null object", npe);
} catch (ExceptionInInitializerError eie) {
throw new GenericServiceException("Service [" + modelService.name + "] Initialization failed", eie);
} catch (Throwable th) {
throw new GenericServiceException("Service [" + modelService.name + "] Error or unknown exception", th);
}
return result;
}
Aggregations