TimeZone timeZone = UtilHttp.getTimeZone(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);
if (Debug.verboseOn()) Debug.logVerbose("[Using delegator]: " + dispatcher.getDelegator().getDelegatorName(), module);
// get the http upload configuration
String maxSizeStr = UtilProperties.getPropertyValue("general.properties", "http.upload.max.size", "-1");
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 = UtilProperties.getPropertyValue("general.properties", "http.upload.max.sizethreshold", "10240");
int sizeThreshold = 10240; // 10K
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 = UtilProperties.getPropertyValue("general.properties", "http.upload.tmprepository", "runtime/tmp");
String encoding = request.getCharacterEncoding();
// check for multipart content types which may have uploaded items
boolean isMultiPart = ServletFileUpload.isMultipartContent(request);
Map<String, Object> multiPartMap = FastMap.newInstance();
if (isMultiPart) {
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();
//byte[] itemBytes = item.get();
/*
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 = FastList.newInstance();
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.getParameterMap(request, null, null);
Set<String> urlOnlyParameterNames = UtilHttp.getUrlOnlyParameterMap(request).keySet();
// we have a service and the model; build the context
Map<String, Object> serviceContext = FastMap.newInstance();
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;
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(name);
if (tempVal != null) {
value = tempVal;
}
}
// check the request parameters
if (UtilValidate.isEmpty(value)) {
ServiceEventHandler.checkSecureParameter(requestMap, urlOnlyParameterNames, name, session, serviceName);
// 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(name);
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 = FastList.newInstance();
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";
}