001: /**
002: * Copyright 2006 Webmedia Group Ltd.
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: **/package org.araneaframework.uilib.form.control;
016:
017: import org.araneaframework.http.HttpInputData;
018: import org.araneaframework.uilib.event.OnChangeEventListener;
019: import org.araneaframework.uilib.event.StandardControlEventListenerAdapter;
020: import org.araneaframework.uilib.support.UiLibMessages;
021: import org.araneaframework.uilib.util.MessageUtil;
022:
023: /**
024: * This class is a generalization of controls that have a single <code>String[]</code> request
025: * parameter.
026: *
027: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
028: *
029: */
030: public abstract class StringArrayRequestControl extends BaseControl {
031:
032: protected StandardControlEventListenerAdapter eventHelper = new StandardControlEventListenerAdapter();
033:
034: //*********************************************************************
035: //* PUBLIC METHODS
036: //*********************************************************************
037:
038: /**
039: * @param onChangeEventListener {@link OnChangeEventListener} which is called when the control value is changing.
040: * @see StandardControlEventListenerAdapter#addOnChangeEventListener(OnChangeEventListener)
041: */
042: public void addOnChangeEventListener(
043: OnChangeEventListener onChangeEventListener) {
044: eventHelper.addOnChangeEventListener(onChangeEventListener);
045: }
046:
047: public void clearOnChangeEventListeners() {
048: eventHelper.clearOnChangeEventListeners();
049: }
050:
051: public void setRawValue(Object value) {
052: super .setRawValue(value);
053: innerData = getRawValue() != null ? toResponseParameters(getRawValue())
054: : null;
055: }
056:
057: //*********************************************************************
058: //* INTERNAL METHODS
059: //*********************************************************************
060: protected void init() throws Exception {
061: super .init();
062:
063: setGlobalEventListener(eventHelper);
064: }
065:
066: /**
067: * This implementation of method {@link #readFromRequest(HttpInputData)}uses the
068: * methods {@link #preprocessRequestParameters(String[])}and
069: * {@link #fromRequestParameters(String[])}to read the control from request.
070: */
071: protected void readFromRequest(HttpInputData request) {
072: String parameterValues[] = request
073: .getParameterValues(getScope().toString());
074: innerData = preprocessRequestParameters(parameterValues);
075: isReadFromRequest = innerData != null;
076: }
077:
078: /**
079: * Breaks the procedure into two parts: conversion and validation. The conversion is done using
080: * method {@link #fromRequestParameters(String[])}and validation using method
081: * {@link #validate()}.
082: */
083: public void convert() {
084: if (innerData != null)
085: value = fromRequestParameters((String[]) innerData);
086: else
087: value = null;
088: }
089:
090: /**
091: * Checks that the mandatory is satisfied, and if the value is not <code>null</code> calls the
092: * {@link #validateNotNull()}method.
093: */
094: public void validate() {
095: if (isMandatory() && !isRead()) {
096: boolean hasValue = (innerData != null
097: && ((String[]) innerData).length > 0 && ((String[]) innerData)[0]
098: .trim().length() != 0);
099: if (!isDisabled() || (isDisabled() && !hasValue))
100: addError(MessageUtil.localizeAndFormat(
101: UiLibMessages.MANDATORY_FIELD,
102: MessageUtil.localize(getLabel(),
103: getEnvironment()), getEnvironment()));
104: }
105:
106: if (getRawValue() != null) {
107: validateNotNull();
108: }
109: }
110:
111: /**
112: * Returns {@link ViewModel}.
113: *
114: * @return {@link ViewModel}.
115: */
116: public Object getViewModel() {
117: return new ViewModel();
118: }
119:
120: //*********************************************************************
121: //* OVERRIDABLE METHODS
122: //*********************************************************************
123:
124: /**
125: * Empty method for overriding. Should contain custom validating logic. This method is called
126: * only if the control value is not null.
127: */
128: protected void validateNotNull() {
129: //Empty method for overriding
130: }
131:
132: //*********************************************************************
133: //* ABSTRACT METHODS
134: //*********************************************************************
135:
136: /**
137: * This method should preprocess the <code>parameterValues</code> and return the processed
138: * variant. It may be used to <i>normalize </i> the request making the further parsing of it
139: * easier.
140: *
141: * @param parameterValues <code>String[]</code>- the values from request.
142: * @return the preprocessed values from request.
143: */
144: protected abstract String[] preprocessRequestParameters(
145: String[] parameterValues);
146:
147: /**
148: * This method should parse the request parameters (preprocessed with
149: * {@link #preprocessRequestParameters(String[])}) an produce the control value.
150: *
151: * @param parameterValues the request parameters.
152: * @return control value.
153: */
154: protected abstract Object fromRequestParameters(
155: String[] parameterValues);
156:
157: /**
158: * This method should return the <code>String[]</code> representation of the control value.
159: *
160: * @param controlValue the control value.
161: * @return the <code>String[]</code> representation of the control value.
162: */
163: protected abstract String[] toResponseParameters(Object controlValue);
164:
165: //*********************************************************************
166: //* VIEW MODEL
167: //*********************************************************************
168:
169: /**
170: * Represents a view model of a control with a single array request parameter.
171: *
172: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
173: *
174: */
175: public class ViewModel extends BaseControl.ViewModel {
176:
177: private String[] values;
178: private boolean hasOnChangeEventListeners;
179:
180: /**
181: * Takes an outer class snapshot.
182: */
183: public ViewModel() {
184: this .values = (String[]) innerData;
185: this .hasOnChangeEventListeners = eventHelper
186: .hasOnChangeEventListeners();
187: }
188:
189: /**
190: * Returns control values.
191: * @return control values.
192: */
193: public String[] getValues() {
194: return values;
195: }
196:
197: /**
198: * Returns the first of control values.
199: * @return the first of control values.
200: */
201: public String getSimpleValue() {
202: return values != null ? values[0] : null;
203: }
204:
205: /**
206: * Returns whether there are registered <code>onChange</code> events.
207: * @return whether there are registered <code>onChange</code> events.
208: */
209: public boolean isOnChangeEventRegistered() {
210: return hasOnChangeEventListeners;
211: }
212:
213: }
214: }
|