001: /*
002: * (C) Copyright 2004 Nabh Information Systems, Inc.
003: *
004: * All copyright notices regarding Nabh's products MUST remain
005: * intact in the scripts and in the outputted HTML.
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021: package com.nabhinc.portlet.mvcportlet.core;
022:
023: import java.io.IOException;
024: import java.util.ArrayList;
025: import java.util.Collections;
026: import java.util.HashMap;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.Map;
030: import java.util.Vector;
031:
032: import javax.portlet.ActionRequest;
033: import javax.portlet.ActionResponse;
034: import javax.portlet.PortletContext;
035: import javax.portlet.PortletException;
036: import javax.portlet.PortletRequest;
037: import javax.portlet.PortletSession;
038:
039: /**
040: * Represents a form for obtaining user input.
041: *
042: * @author Padmanabh Dabke
043: * (c) 2004 Nabh Information Systems, Inc. All Rights Reserved.
044: */
045: public class Form {
046: private int fScope = Constants.SCOPE_UNSPECIFIED;
047: private ControllerPortletConfig fConfig = null;
048: private String fName = null;
049: private List fFieldList = new ArrayList();
050: private HashMap fFieldMap = new HashMap();
051: private String fJavascript = null;
052:
053: public Form(ControllerPortletConfig config) {
054: fConfig = config;
055: }
056:
057: public String getScope() {
058: switch (fScope) {
059: case Constants.SCOPE_APPLICATION_SESSION:
060: return Constants.APPLICATION_SESSION_SCOPE;
061: case Constants.SCOPE_PORTLET_SESSION:
062: return Constants.PORTLET_SESSION_SCOPE;
063: case Constants.SCOPE_PORTLET_CONTEXT:
064: return Constants.PORTLET_CONTEXT_SCOPE;
065: case Constants.SCOPE_UNSPECIFIED:
066: return Constants.UNSPECIFIED_SCOPE;
067: default:
068: return Constants.REQUEST_SCOPE;
069: }
070: }
071:
072: public int getScopeAsInt() {
073: return fScope;
074: }
075:
076: public void setScope(String scope) {
077: if (scope.equals(Constants.APPLICATION_SESSION_SCOPE)) {
078: fScope = Constants.SCOPE_APPLICATION_SESSION;
079: } else if (scope.equals(Constants.PORTLET_SESSION_SCOPE)) {
080: fScope = Constants.SCOPE_PORTLET_SESSION;
081: } else if (scope.equals(Constants.REQUEST_SCOPE)) {
082: fScope = Constants.SCOPE_REQUEST;
083: } else if (scope.equals(Constants.PORTLET_CONTEXT_SCOPE)) {
084: fScope = Constants.SCOPE_PORTLET_CONTEXT;
085: } else {
086: throw new IllegalArgumentException(
087: "Scope must be one of: request, portlet_session, application_session, portlet_context.");
088:
089: }
090: }
091:
092: /**
093: * Sets form name
094: * @param name Form name
095: */
096: public void setName(String name) {
097: fName = name;
098: }
099:
100: /**
101: * Get form name
102: * @return Form name
103: */
104: public String getName() {
105: return fName;
106: }
107:
108: /**
109: * Adds a form field
110: * @param field Field to be added
111: */
112: @SuppressWarnings("unchecked")
113: public void addField(FormField field) {
114: fFieldList.add(field);
115: fFieldMap.put(field.getName(), field);
116: }
117:
118: /**
119: * Returns a field with the specified name, null if
120: * it does not exist.
121: * @param name Field name
122: * @return Field with the specified name if exists
123: */
124: public FormField getField(String name) {
125: return (FormField) fFieldMap.get(name);
126: }
127:
128: /**
129: * Returns a list of fields in this form
130: * @return Field list
131: */
132: @SuppressWarnings("unchecked")
133: public List getFieldList() {
134: return Collections.unmodifiableList(fFieldList);
135: }
136:
137: /**
138: * Returns a mapping of field name -> field object.
139: * @return Field map
140: */
141: @SuppressWarnings("unchecked")
142: public Map getFieldMap() {
143: return Collections.unmodifiableMap(fFieldMap);
144: }
145:
146: /**
147: * Returns the field at the indicated location.
148: * @param position Field index
149: * @return Field at the specified location
150: */
151: public FormField getField(int position) {
152: return (FormField) fFieldList.get(position);
153: }
154:
155: /**
156: * Returns javascript computed by computeJavascript method.
157: * @return Javascript for client validation
158: */
159: public String getJavascript() {
160: return fJavascript;
161: }
162:
163: /**
164: * This method is called by ControllerPortlet after it adds
165: * all fields to this form. The javascript is computed by aggregating
166: * Javascript functions associated with all validator classes
167: * associated with this form (via form fields).
168: *
169: */
170: @SuppressWarnings("unchecked")
171: public void computeJavascript() {
172: HashMap validatorClassMap = new HashMap();
173: // getFieldList may be overridden by subclasses that create dynamic fields.
174: List fieldList = getFieldList();
175:
176: for (int i = 0; i < fieldList.size(); i++) {
177: FormField field = (FormField) fieldList.get(i);
178: FormFieldValidator[] vals = field.getValidators();
179: if (vals != null) {
180: for (int j = 0; j < vals.length; j++) {
181: validatorClassMap.put(vals[j].getClass().getName(),
182: "");
183: }
184: }
185: }
186: Iterator iter = validatorClassMap.keySet().iterator();
187: StringBuffer sb = new StringBuffer();
188: sb.append("\n\n");
189: while (iter.hasNext()) {
190: String className = (String) iter.next();
191: JavascriptValidationInfo jInfo = fConfig
192: .getJavascriptValidationInfo(className);
193: if (jInfo != null) {
194: sb.append(jInfo.getJavascript() + "\n");
195: }
196: }
197: fJavascript = sb.toString();
198: }
199:
200: /**
201: * Calls validate method on each form field. If at least one field
202: * returns an error it returns false, otherwise it returns true. In
203: * case of errors it sets the error parameter to
204: * "mvcportlet.form_error_message". In addition, it sets portlet mode
205: * scoped error attribute to the FormErrors object that contains
206: * description of all field errors.
207: * @param request
208: * @param response
209: * @param config
210: * @param portlet
211: * @return
212: * @throws PortletException
213: * @throws IOException
214: */
215: @SuppressWarnings("unchecked")
216: public boolean validate(ActionRequest request,
217: ActionResponse response, RequestConfig config,
218: ControllerPortlet portlet) throws PortletException,
219: IOException {
220:
221: boolean success = true;
222: Vector errors = new Vector(5);
223: // getFieldList may be overridden by subclasses that create dynamic fields.
224: List fieldList = getFieldList(request);
225: String portletMode = request.getPortletMode().toString()
226: .toLowerCase();
227: for (int i = 0; i < fieldList.size(); i++) {
228: FormField f = (FormField) fieldList.get(i);
229: String error = f.validate(request, config);
230: if (error != null) {
231: success = false;
232: errors.addElement(new FormError(f.getName(), error));
233: }
234: }
235:
236: if (success) {
237: request.getPortletSession().removeAttribute(
238: Constants.FORM_ERRORS_ATTRIB + portletMode);
239: // response.setRenderParameter(Constants.SUCCESS_MESSAGE_PARAM, "mvcportlet.form." + getName() + ".success_message");
240: } else {
241: FormErrors formErrors = new FormErrors(fName, errors);
242: response.setRenderParameter(Constants.ERROR_MESSAGE_PARAM
243: + portletMode, "mvcportlet.form_error_message");
244: request.getPortletSession().setAttribute(
245: Constants.FORM_ERRORS_ATTRIB + portletMode,
246: formErrors);
247: }
248: return success;
249: }
250:
251: /**
252: * Removes the error attribute since this action is cancelled. Also removes session/portlet context attributes
253: * depending on the form scope.
254: * @param request
255: * @param response
256: */
257: public void cancel(ActionRequest request, ActionResponse response) {
258: String portletMode = request.getPortletMode().toString()
259: .toLowerCase();
260: // getFieldList may be overridden by subclasses that create dynamic fields.
261: List fieldList = getFieldList(request);
262: request.getPortletSession().removeAttribute(
263: Constants.FORM_ERRORS_ATTRIB + portletMode);
264: if (this .fScope == Constants.SCOPE_APPLICATION_SESSION
265: || this .fScope == Constants.SCOPE_PORTLET_SESSION) {
266: int sessionScope = this .fScope == Constants.SCOPE_APPLICATION_SESSION ? PortletSession.APPLICATION_SCOPE
267: : PortletSession.PORTLET_SCOPE;
268: PortletSession pSession = request.getPortletSession();
269: for (int i = 0; i < fieldList.size(); i++) {
270: FormField f = (FormField) fieldList.get(i);
271: pSession.removeAttribute(f.getName(), sessionScope);
272: }
273: } else if (this .fScope == Constants.SCOPE_PORTLET_CONTEXT) {
274: PortletContext pContext = request.getPortletSession()
275: .getPortletContext();
276: for (int i = 0; i < fieldList.size(); i++) {
277: FormField f = (FormField) fieldList.get(i);
278: pContext.removeAttribute(f.getName());
279: }
280:
281: }
282: }
283:
284: protected List getFieldList(PortletRequest request) {
285: return getFieldList();
286: }
287:
288: public List getDynamicFieldList(PortletRequest request) {
289: return null;
290: }
291:
292: }
|