Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,10 @@ public CommandController(final String theViewName) {
*
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public ModelAndView handle(final HttpServletRequest request,
final HttpServletResponse response, final Object command,
final BindException errors) {
Object result = ((Command) command).execute();
Object result = ((Command<?>) command).execute();
ModelAndView mav = new ModelAndView(viewName);
mav.addObject(RESULT_NAME, result);
mav.addObject(COMMAND_NAME, command);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.globant.katari.core.spring.controller;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.Validate;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;

/** This parameter processor maps the values from the client (Request) into
* the current parameters.
*
* Also, allows Servlet: request & parameter overriding.
* Example:
*
* The original request comes with 2 parameters:
*
* 1) the_name => 'the name'
* 2) the_last_name => 'the last name'
*
* if this processor is initialized with the constructor with the argument:
* <code>map(String, String)</code> (the key represents the main 'Key, and
* the value, the replacement for that key).
*
* Continuing with the example, let's override those properties.
*
* <code>
* Map<String, String> overrider = new HashMap();
* overrider.put("the_name", "name");
* overrider.put("the_last_name", "lastName");
* new DefaultRequestParameterProcessor(overrider);
* </code>
*
* The result of this code, will propagate a map with the values:
*
* 1) name => 'the name'
* 2) lastName => 'the last name'
*
* @author waabox (waabox[at]gmail[dot]com)
*/
public class DefaultRequestParameterProcessor implements ParameterProcessor {

/** The properties (Origin as key, destiny as value), It's never null.*/
private final Map<String, String> properties;

/** Creates a new instance of the request parameter definition.*/
public DefaultRequestParameterProcessor() {
properties = new HashMap<String, String>();
}

/** Creates a new instance of the request parameter definition.
*
* @param theProperties the properties to override.
*/
public DefaultRequestParameterProcessor(
final Map<String, String> theProperties) {
Validate.notNull(theProperties, "The properties cannot be null");
properties = theProperties;
}

/** {@inheritDoc}.
*
* Process the request and attributes parameters and add it back to the
* given map.
* Also, allows attribute & parameters overriding.
*
*/
@SuppressWarnings("unchecked")
public void process(final HttpServletRequest request,
final HttpServletResponse response,
final Map<String, Object> theParameters) {

Map<String, Object> params = new TreeMap<String, Object>();
Enumeration<String> parameters = request.getParameterNames();
Enumeration<String> attributes = request.getAttributeNames();

while (parameters.hasMoreElements()) {
String name = parameters.nextElement();
String[] values = request.getParameterValues(name);
String realName = resolveName(name);
if (!ArrayUtils.isEmpty(values)) {
if (values.length > 1) {
params.put(realName, values);
} else {
params.put(realName, values[0]);
}
}
}

while(attributes.hasMoreElements()) {
String name = attributes.nextElement();
Object value = request.getAttribute(name);
String realName = resolveName(name);
params.put(realName, value);
}

theParameters.putAll(params);

}

/** Resolves the name if there are an override defined.
* @param name the name of the request parameter to override.
* @return the overridden name or the same value.
*/
private String resolveName(final String name) {
String newName = properties.get(name);
if (newName != null) {
return newName;
}
return name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ protected ModelAndView handle(final HttpServletRequest request,
jsonCommand = (Command<JsonRepresentation>) command;
response.addHeader("Content-type", "application/json; charset=UTF-8");
JsonRepresentation result = jsonCommand.execute();
if (result == null) {
throw new RuntimeException("The result of executing the command"
if (result == null) {
throw new RuntimeException("The result of executing the command"
+ " cannnot be null. If your command may return nullt, then you"
+ " should use another controller");
}
}
result.write(response.getWriter());

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.globant.katari.core.spring.controller;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/** Retrieves from the response the output stream and store it into the
* request parameter called: outputStream.
*
* @author waabox (waabox[at]gmail[dot]com)
*/
public class OutputStreamParameterProcessor implements ParameterProcessor {

/** The parameter name.*/
private static final String PARAMETER_NAME = "outputStream";

/** {@inheritDoc}.*/
public void process(final HttpServletRequest request,
final HttpServletResponse response,
final Map<String, Object> parameters) {
try {
parameters.put(PARAMETER_NAME, response.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.globant.katari.core.spring.controller;

import java.util.Map;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;

/** The parameter definition interfaces allows to modify parameters within
* a Servlet context.
*
* The typical scenario is: add new parameters into the current request.
* For example: infrastructure support, such as output streams, cookies, etc.
*
* @author waabox (waabox[at]gmail[dot]com)
*/
public interface ParameterProcessor {

/** This method allows to redefine, change, remove or any kind of operation
* related to the parameters received in the parameters map.
*
* @param request the HTTP Servlet request, cannot be null.
* @param response the HTTP Servlet response, cannot be null.
* @param parameters the map of parameters, cannot be null.
*/
void process(final HttpServletRequest request,
final HttpServletResponse response, final Map<String, Object> parameters);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package com.globant.katari.core.spring.controller;

import java.beans.PropertyEditorSupport;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/** Factory class (binder) for the spring Property Editor Support.
*
* Should we call it Factory? Binder? Mapper? ideas...?
*
* @author waabox (emiliano[dot]arango[at]globant[dot]com)
*/
public class PropertyEditorBinder implements ApplicationContextAware,
InitializingBean {

/** The class logger.*/
private static Logger log =
LoggerFactory.getLogger(PropertyEditorBinder.class);

/** The target class of the bean, It's never null. */
private Class<?> targetClass;

/** The target field of the bean, Can be null. */
private String targetField;

/** The property editor class, It's never null. */
private Class<PropertyEditorSupport> propertyEditorClass;

/** The property editor bean name, It's never null. */
private String propertyEditorBeanName;

/** The spring application context, It's never null. */
private ApplicationContext applicationContext;

/** {@inheritDoc} .*/
public void afterPropertiesSet() throws Exception {
Validate.notNull(targetClass, "The target class cannot be null");

if (StringUtils.isBlank(propertyEditorBeanName)
&& propertyEditorClass == null) {
throw new IllegalArgumentException("please define at least one strategy,"
+ "setting the propertyEditorBeanName or propertyEditorClass");
}

if (propertyEditorClass != null) {
boolean isAssignable = PropertyEditorSupport.class.isAssignableFrom(
propertyEditorClass);
Validate.isTrue(isAssignable,
"The given Property editor class does not extends from "
+ "PropertyEditorSupport.class");
}
}

/** Attaches to the given binder the property editor.
* @param binder the binder to attach the property editor. Cannot be null.
*/
public void register(final ServletRequestDataBinder binder) {
Validate.notNull(binder, "The binder cannot be null");
PropertyEditorSupport editor = null;
try {

if (StringUtils.isBlank(propertyEditorBeanName)) {
editor = propertyEditorClass.newInstance();
} else {
editor = (PropertyEditorSupport) applicationContext.getBean(
propertyEditorBeanName);
Validate.notNull(editor, "Could not find the bean named:"
+ propertyEditorBeanName);
}

if (editor instanceof DataBinderHttpServletRequestAware) {
((DataBinderHttpServletRequestAware) editor)
.setHttpServletRequest(binder.getHttpServletRequest());
}

if (editor instanceof DataBinderHttpServletResponseAware) {
((DataBinderHttpServletResponseAware) editor)
.setHttpServletResponse(binder.getHttpServletResponse());
}

} catch (Exception e) {
throw new RuntimeException(e);
}

log.debug("creating binder for: [ "
+ "target-field: " + targetField + ", "
+ "target-class: " + targetClass.getName() + ", "
+ "editor-class: " + editor.getClass().getName()
+ " ]");

if (targetField == null) {
binder.registerCustomEditor(targetClass, editor);
} else {
binder.registerCustomEditor(targetClass, targetField, editor);
}
}

/** {@inheritDoc}. */
public void setApplicationContext(final ApplicationContext context) {
applicationContext = context;
}

/** Sets the target class.
* @param klass the target class to set.
*/
public void setTargetClass(final Class<?> klass) {
if (targetClass != null) {
throw new IllegalStateException("Cannot modify the target class");
}
targetClass = klass;
}

/** Sets the target field.
* @param field the target field to set.
*/
public void setTargetField(final String field) {
if (targetField != null) {
throw new IllegalStateException("Cannot modify the target field");
}
targetField = field;
}

/** Sets the property editor class.
* @param editorClass the property editor class to set.
*/
public void setPropertyEditorClass(
final Class<PropertyEditorSupport> editorClass) {
if (propertyEditorClass != null) {
throw new IllegalStateException(
"Cannot modify the property editor class");
}
propertyEditorClass = editorClass;
}

/** Sets the property editor bean name.
* @param editorBeanName the property editor bean name to set.
*/
public void setPropertyEditorBeanName(final String editorBeanName) {
if (propertyEditorBeanName != null) {
throw new IllegalStateException(
"Cannot modify the property editor bean name");
}
propertyEditorBeanName = editorBeanName;
}

/** {@inheritDoc}.*/
@Override
public String toString() {
return "Propery Editor binder for:" + targetClass.getName();
}

/** Interface to be implemented by any object that needs the
* HttpServletRequest.
*/
public static interface DataBinderHttpServletRequestAware {

/** Sets the HttpServlet Request.
* @param request the HTTP servlet request.
*/
void setHttpServletRequest(final HttpServletRequest request);

}

/** Interface to be implemented by any object that needs the
* HttpServletResponse.
*/
public static interface DataBinderHttpServletResponseAware {

/** Sets the HttpServlet Response.
* @param response the HTTP servlet response.
*/
void setHttpServletResponse(final HttpServletResponse response);

}
}
Loading