001: /*
002: * Copyright 2002-2006 the original author or authors.
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:
017: package org.springframework.web.portlet.bind;
018:
019: import javax.portlet.PortletRequest;
020:
021: import org.springframework.beans.MutablePropertyValues;
022: import org.springframework.validation.BindException;
023: import org.springframework.web.bind.WebDataBinder;
024: import org.springframework.web.portlet.multipart.MultipartActionRequest;
025:
026: /**
027: * Special DataBinder to perform data binding from PortletRequest parameters
028: * to JavaBeans.
029: *
030: * <p>See the DataBinder/WebDataBinder superclasses for customization options,
031: * which include specifying allowed/required fields, and registering custom
032: * property editors.
033: *
034: * <p>Used by Spring Portlet MVC's BaseCommandController.
035: * Note that BaseCommandController and its subclasses allow for easy customization
036: * of the binder instances that they use through overriding <code>initBinder</code>.
037: *
038: * <p>Can also be used for manual data binding in custom web controllers:
039: * for example, in a plain Portlet Controller implementation. Simply instantiate
040: * a PortletRequestDataBinder for each binding process, and invoke <code>bind</code>
041: * with the current PortletRequest as argument:
042: *
043: * <pre>
044: * MyBean myBean = new MyBean();
045: * // apply binder to custom target object
046: * PortletRequestDataBinder binder = new PortletRequestDataBinder(myBean);
047: * // register custom editors, if desired
048: * binder.registerCustomEditor(...);
049: * // trigger actual binding of request parameters
050: * binder.bind(request);
051: * // optionally evaluate binding errors
052: * Errors errors = binder.getErrors();
053: * ...</pre>
054: *
055: * @author Juergen Hoeller
056: * @author John A. Lewis
057: * @since 2.0
058: * @see #bind(javax.portlet.PortletRequest)
059: * @see #registerCustomEditor
060: * @see #setAllowedFields
061: * @see #setRequiredFields
062: * @see #setFieldMarkerPrefix
063: * @see org.springframework.web.portlet.mvc.BaseCommandController#initBinder
064: */
065: public class PortletRequestDataBinder extends WebDataBinder {
066:
067: /**
068: * Create a new PortletRequestDataBinder instance, with default object name.
069: * @param target target object to bind onto
070: * @see #DEFAULT_OBJECT_NAME
071: */
072: public PortletRequestDataBinder(Object target) {
073: super (target);
074: }
075:
076: /**
077: * Create a new PortletRequestDataBinder instance.
078: * @param target target object to bind onto
079: * @param objectName objectName of the target object
080: */
081: public PortletRequestDataBinder(Object target, String objectName) {
082: super (target, objectName);
083: }
084:
085: /**
086: * Bind the parameters of the given request to this binder's target,
087: * also binding multipart files in case of a multipart request.
088: * <p>This call can create field errors, representing basic binding
089: * errors like a required field (code "required"), or type mismatch
090: * between value and bean property (code "typeMismatch").
091: * <p>Multipart files are bound via their parameter name, just like normal
092: * HTTP parameters: i.e. "uploadedFile" to an "uploadedFile" bean property,
093: * invoking a "setUploadedFile" setter method.
094: * <p>The type of the target property for a multipart file can be MultipartFile,
095: * byte[], or String. The latter two receive the contents of the uploaded file;
096: * all metadata like original file name, content type, etc are lost in those cases.
097: * @param request request with parameters to bind (can be multipart)
098: * @see org.springframework.web.portlet.multipart.MultipartActionRequest
099: * @see org.springframework.web.multipart.MultipartFile
100: * @see #bindMultipartFiles
101: * @see #bind(org.springframework.beans.PropertyValues)
102: */
103: public void bind(PortletRequest request) {
104: MutablePropertyValues mpvs = new PortletRequestParameterPropertyValues(
105: request);
106: if (request instanceof MultipartActionRequest) {
107: MultipartActionRequest multipartRequest = (MultipartActionRequest) request;
108: bindMultipartFiles(multipartRequest.getFileMap(), mpvs);
109: }
110: doBind(mpvs);
111: }
112:
113: /**
114: * Treats errors as fatal. Use this method only if
115: * it's an error if the input isn't valid.
116: * This might be appropriate if all input is from dropdowns, for example.
117: * @throws PortletRequestBindingException subclass of PortletException on any binding problem
118: */
119: public void closeNoCatch() throws PortletRequestBindingException {
120: if (getBindingResult().hasErrors()) {
121: throw new PortletRequestBindingException(
122: "Errors binding onto object '"
123: + getBindingResult().getObjectName() + "'",
124: new BindException(getBindingResult()));
125: }
126: }
127:
128: }
|