001: /*
002: * Copyright 2006-2007 Dan Shellman
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: package org.iscreen.impl;
017:
018: import java.util.Collection;
019: import java.util.List;
020: import java.util.Locale;
021: import org.iscreen.DocumentationIterator;
022:
023: /**
024: * This is a special ValidatorWrapper that forwards validation to
025: * a different Validation Set.
026: *
027: * @author Shellman, Dan
028: */
029: public abstract class ValidationServiceValidator implements
030: ValidatorWrapper {
031: protected DefaultValidationService wrappedService;
032: protected String ifExp;
033: protected String iterateExp;
034: protected String mapExp;
035: protected boolean failFastFlag;
036: protected String name;
037:
038: /**
039: * Default constructor.
040: */
041: public ValidationServiceValidator(DefaultValidationService service) {
042: wrappedService = service;
043: } //end ValidationServiceValidator()
044:
045: public boolean validate(InternalValidatorContext context,
046: ContextBean contextBean, Object obj) {
047: List validatorWrappers;
048: int failureCount;
049: Object mappedObj;
050: Object[] mappedArray;
051:
052: //First, check the 'if' expression to make sure we should even
053: //be executing these validators.
054: if (!shouldExecute(context, contextBean, obj)) {
055: return true;
056: }
057:
058: //Get the failure count pre-constraint
059: failureCount = context.getFailureCount();
060: validatorWrappers = wrappedService.getAllWrappers();
061:
062: //Map the object to what's being forwarded to the validators
063: mappedObj = mapObject(context, contextBean, obj);
064:
065: //Setup for iteration.
066: if (shouldIterate(context, contextBean, obj)) {
067: if (mappedObj instanceof Collection) {
068: mappedArray = ((Collection) mappedObj).toArray();
069: } else if (mappedObj != null
070: && mappedObj.getClass().isArray()) {
071: mappedArray = (Object[]) mappedObj;
072: } else {
073: mappedArray = new Object[1];
074: mappedArray[0] = mappedObj;
075: }
076: } else {
077: mappedArray = new Object[1];
078: mappedArray[0] = mappedObj;
079: }
080:
081: //Iterate through the mapped objects.
082: for (int iterate = 0; iterate < mappedArray.length; iterate++) {
083: Object objToValidate;
084: ContextBean newContextBean;
085: InternalValidatorContext newContext;
086:
087: objToValidate = mappedArray[iterate];
088: newContextBean = new ContextBean();
089: newContextBean.setBean(objToValidate);
090: newContextBean.setLabel(contextBean.getLabel());
091: newContextBean.setIndex(iterate);
092:
093: newContext = createNewContext(newContextBean, context
094: .getLocale(), context);
095:
096: //Iterate through the validators to perform the validations.
097: for (int i = 0; i < validatorWrappers.size(); i++) {
098: ValidatorWrapper wrapper;
099: boolean failFlag;
100:
101: wrapper = (ValidatorWrapper) validatorWrappers.get(i);
102: if (name != null && !name.trim().equals("")) {
103: //Use the use-validation-set 'name' attribute if it's valid
104: newContext.setValidator(this );
105: } else {
106: newContext.setValidator(wrapper);
107: }
108:
109: failFlag = wrapper.validate(newContext, newContextBean,
110: objToValidate);
111: if (!failFlag) {
112: break;
113: }
114: }
115:
116: //Add the new failures/warnings to the old context so that the old context
117: //contains all failures/warnings.
118: if (newContext.getCount() > 0) {
119: context.addRawFailures(newContext.getFailures());
120: context.addRawWarnings(newContext.getWarnings());
121: }
122: }
123:
124: if (failFastFlag && failureCount < context.getFailureCount()) {
125: return false;
126: }
127:
128: return true;
129: } //end validate()
130:
131: public void setIfExpression(String exp) {
132: ifExp = exp;
133: } //end setIfExpression()
134:
135: public String getIfExpression() {
136: return ifExp;
137: } //end getIfExpression()
138:
139: public void setIterateExpression(String exp) {
140: iterateExp = exp;
141: } //end setIterateExpression()
142:
143: public String getIterateExpression() {
144: return iterateExp;
145: } //end getIterateExpression()
146:
147: public void setMapExpression(String exp) {
148: mapExp = exp;
149: } //end setMapExpression()
150:
151: public String getMapExpression() {
152: return mapExp;
153: } //end getMapExpression()
154:
155: public void setFailFast(boolean flag) {
156: failFastFlag = flag;
157: } //end setFailFast()
158:
159: public boolean isFailFast() {
160: return failFastFlag;
161: } //end isFailFast()
162:
163: public void setName(String theName) {
164: name = theName;
165: } //end setName()
166:
167: public String getName() {
168: return name;
169: } //end getName()
170:
171: /**
172: * Called to retrieve the documentation for the validator.
173: *
174: * @return Returns the documentation for the validator.
175: */
176: public DocumentationIterator getDoc() {
177: return wrappedService.getDocumentation();
178: } //end getDoc()
179:
180: // ***
181: // Protected methods
182: // ***
183:
184: /**
185: * Determines whether we're iterating over the mapped object.
186: *
187: * @param context The ValidatorContext
188: * @param contextBean The ContextBean
189: * @param obj The object being validated.
190: *
191: * @return Returns true if we should iterate.
192: */
193: protected abstract boolean shouldIterate(
194: InternalValidatorContext context, ContextBean contextBean,
195: Object obj);
196:
197: /**
198: * Determines whether the inclusion/call to the validation set
199: * should occur.
200: *
201: * @param context The ValidatorContext
202: * @param contextBean The ContextBean
203: * @param obj The object being validated.
204: *
205: * @return Returns true if the validation set should be called/executed.
206: */
207: protected abstract boolean shouldExecute(
208: InternalValidatorContext context, ContextBean contextBean,
209: Object obj);
210:
211: /**
212: * Handle the mapping of the object being validated to the property
213: * that will be validated (may be the object, itself).
214: *
215: * @param context The ValidatorContext
216: * @param contextBean The ContextBean
217: * @param obj The object being validated.
218: *
219: * @return Returns the object that will be forwarded to the called
220: * validation set.
221: */
222: protected abstract Object mapObject(
223: InternalValidatorContext context, ContextBean contextBean,
224: Object obj);
225:
226: /**
227: * Constructs a new context for the validation set being called.
228: *
229: * @param newContextBean The new ContextBean created for the validation set.
230: * @param newLocale The new Locale for the validation set.
231: * @param oldContext The old ValidatorContext from the current validation set.
232: */
233: protected InternalValidatorContext createNewContext(
234: ContextBean newContextBean, Locale newLocale,
235: InternalValidatorContext oldContext) {
236: return new DefaultValidatorContext(newContextBean, newLocale);
237: } //end createNewContext()
238: } //end ValidationServiceValidator
|