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.ognl;
017:
018: import java.util.Iterator;
019: import java.util.Set;
020:
021: import org.iscreen.ConfigurationException;
022: import org.iscreen.impl.ConfiguredResource;
023: import org.iscreen.impl.DefaultValidationService;
024: import org.iscreen.impl.xml.XmlConfigConstraint;
025: import org.iscreen.impl.xml.XmlConfigDoc;
026: import org.iscreen.impl.xml.XmlConfigFailure;
027: import org.iscreen.impl.xml.XmlConfigLabel;
028: import org.iscreen.impl.xml.XmlConfigMapping;
029: import org.iscreen.impl.xml.XmlServiceFactory;
030:
031: /**
032: * This factory constructs a ValidationService based upon an XML
033: * configuration (via file or String, etc.). This ValidationFactory
034: * supports XML files that use OGNL.
035: *
036: * @author Shellman, Dan
037: */
038: public class OgnlXmlServiceFactory extends XmlServiceFactory {
039: /**
040: * Default constructor.
041: */
042: public OgnlXmlServiceFactory() {
043: } //end OgnlXmlServiceFactory()
044:
045: /**
046: * Registers an individual Validator configuration. This will create
047: * a configured Validator that can be referenced by other Validators or
048: * by adding a Validator to a Validation Set.
049: *
050: * @param globalDefaultResource The resource id, when all else fails.
051: * @param id The unique id of the Validator
052: * @param ref The unique id of the Validator this Validator references.
053: * This can be null and is optional.
054: * @param className The class name of the Validator (optional, but if
055: * there MUST be a valid ref).
056: * @param defaultResource The resource id if no id is defined locally.
057: * @param label The Label for the Validator. This is optional.
058: * @param doc The documentation for the Validator. This is optional.
059: * @param mappings The Set of mappings (can't be null, but can be empty).
060: * @param constraints The Set of constraints (can't be null, but can be empty).
061: * @param failures The Set of failures (can't be null, but can be empty).
062: */
063: public void registerValidator(String globalDefaultResource,
064: String id, String ref, String className,
065: String defaultResource, XmlConfigLabel label,
066: XmlConfigDoc doc, Set mappings, Set constraints,
067: Set failures) {
068: OgnlConfiguredValidator validator;
069:
070: if (id == null || id.trim().equals("")) {
071: throw new ConfigurationException(
072: "Invalid definition of a Validator. The id is missing. All validators must have a unique id.");
073: }
074:
075: if ((className == null || className.trim().equals(""))
076: && (ref == null || ref.trim().equals(""))) {
077: throw new ConfigurationException(
078: "Invalid definition of a Validator. Either the ref or the class name must be valid.");
079: }
080:
081: validator = getValidator(id);
082: validator.setId(id);
083: validator.setClassName(className);
084: if (ref != null && !ref.trim().equals("")) {
085: validator.setRef(getValidator(ref));
086: }
087:
088: configureValidator(validator, globalDefaultResource,
089: defaultResource, label, doc, mappings, constraints,
090: failures);
091: } //end registerValidator()
092:
093: /**
094: * Registers a Validation Set.
095: *
096: * @param id The validation set's unique id.
097: */
098: public void registerValidationSet(String id) {
099: DefaultValidationService service;
100:
101: if (id == null || id.trim().equals("")) {
102: throw new ConfigurationException(
103: "Invalid unique id for validation set. All validation sets must have a non-empty, unique id.");
104: }
105:
106: //Check to see if it exists
107: if (setMap.get(id) == null) {
108: service = new DefaultValidationService(id,
109: getDefaultLocale());
110: setMap.put(id, service);
111: }
112: } //end registerValidationSet()
113:
114: /**
115: * Adds a 'use-validator' to a Validation Set. The 'use-validator' must
116: * reference a Validator.
117: *
118: * @param setId The Validation Set id.
119: * @param globalDefaultResource The configuration file's default resource
120: * (can be null/empty).
121: * @param defaultResource The Validation Set's default resource (optional).
122: * @param validatorRef The reference to a Validator (required).
123: * @param failFastFlag Whether to stop validations if this validator fails.
124: * @param label The label for this validator.
125: * @param doc Documentation for this use of the validator.
126: * @param mappings The mappings for this validator.
127: * @param constraints The constraints for this validator.
128: * @param failures The failures for this validator.
129: */
130: public void addValidatorToSet(String setId,
131: String globalDefaultResource, String defaultResource,
132: String validatorRef, boolean failFastFlag,
133: String validatorName, XmlConfigLabel label,
134: XmlConfigDoc doc, Set mappings, Set constraints,
135: Set failures) {
136: OgnlConfiguredValidator validator;
137: DefaultValidationService service;
138:
139: if (validatorRef == null || validatorRef.trim().equals("")) {
140: throw new ConfigurationException(
141: "Invalid reference to a Validator. The 'ref' attribute must be set and must point to a Validator.");
142: }
143:
144: validator = new OgnlConfiguredValidator();
145: validator.setRef(getValidator(validatorRef));
146:
147: configureValidator(validator, globalDefaultResource,
148: defaultResource, label, doc, mappings, constraints,
149: failures);
150:
151: validator.setFailFast(failFastFlag);
152: validator.setName(validatorName);
153:
154: service = (DefaultValidationService) setMap.get(setId);
155: service.addValidatorWrapper(validator);
156: validator.setValidationService(service);
157: } //end addValidatorToSet()
158:
159: /**
160: * Adds a validation set reference call to a validation set.
161: *
162: * @param setId The id of the containing Validation Set.
163: * @param setRefId The id of the Validation Set being referenced.
164: * @param failFastFlag Whether to continue validations if the set
165: * reports a failure.
166: * @param ifExp Whether to execute the validations in the referenced set.
167: * @param iterateExp Whether to iterate over the objects being mapped
168: * and validate each one.
169: * @param mapExp The mapping expression.
170: */
171: public void addValidationSetToSet(String setId, String setRefId,
172: boolean failFastFlag, String name, String ifExp,
173: String iterateExp, String mapExp) {
174: DefaultValidationService service;
175: DefaultValidationService referencedService;
176: OgnlValidationServiceValidator serviceWrapper;
177:
178: //Grab the referenced service. If it doesn't exist, then create it.
179: referencedService = (DefaultValidationService) setMap
180: .get(setRefId);
181: if (referencedService == null) {
182: referencedService = new DefaultValidationService(setRefId,
183: getDefaultLocale());
184: setMap.put(setRefId, referencedService);
185: }
186:
187: //Configure the service "wrapper"
188: serviceWrapper = new OgnlValidationServiceValidator(
189: referencedService);
190:
191: serviceWrapper.setFailFast(failFastFlag);
192: serviceWrapper.setIfExpression(ifExp);
193: serviceWrapper.setIterateExpression(iterateExp);
194: serviceWrapper.setMapExpression(mapExp);
195: serviceWrapper.setName(name);
196:
197: //This will never be null, since the registerValidationSet() will have
198: //been called before this method.
199: service = (DefaultValidationService) setMap.get(setId);
200: service.addValidatorWrapper(serviceWrapper);
201: } //end addValidationSetToSet()
202:
203: /**
204: * Retrieves a OgnlConfiguredValidator with the given id. If one has not
205: * been previously registered, then create a blank one.
206: *
207: *
208: * @param id The Validator's id.
209: * @return Returns a Validator with the given id.
210: */
211: public OgnlConfiguredValidator getValidator(String id) {
212: OgnlConfiguredValidator validator;
213:
214: validator = (OgnlConfiguredValidator) validatorMap.get(id);
215: if (validator == null) {
216: validator = new OgnlConfiguredValidator();
217: validator.setId(id);
218: validatorMap.put(id, validator);
219: }
220:
221: return validator;
222: } //end getValidator()
223:
224: // ***
225: // Protected methods
226: // ***
227:
228: /**
229: * Handles the actual configuration of a Validator, whether via registration
230: * or by adding one to a Validation Set.
231: */
232: protected void configureValidator(
233: OgnlConfiguredValidator validator,
234: String globalDefaultResource, String defaultResource,
235: XmlConfigLabel label, XmlConfigDoc doc, Set mappings,
236: Set constraints, Set failures) {
237: Iterator it;
238:
239: //Configure the constraints.
240: it = constraints.iterator();
241: while (it.hasNext()) {
242: XmlConfigConstraint constraint;
243:
244: constraint = (XmlConfigConstraint) it.next();
245: if (constraint.getServiceId() == null
246: || constraint.getServiceId().trim().equals("")) {
247: validator.addStaticProperty(constraint.getProperty(),
248: constraint.getValue());
249: } else {
250: validator.addStaticProperty(constraint.getProperty(),
251: serviceMap.get(constraint.getServiceId()));
252: }
253: }
254:
255: //Configure the failure objects.
256: it = failures.iterator();
257: while (it.hasNext()) {
258: XmlConfigFailure failure;
259:
260: failure = (XmlConfigFailure) it.next();
261: if (failure.getMessage() == null) {
262: ConfiguredResource resource;
263:
264: resource = getResource(failure.getResource(),
265: defaultResource, globalDefaultResource);
266: validator.addStaticProperty(failure.getProperty(),
267: new OgnlResourceMessage(resource, failure
268: .getKey()));
269: } else {
270: validator.addStaticProperty(failure.getProperty(),
271: new OgnlMessage(failure.getMessage()));
272: }
273: }
274:
275: //Configure mappings
276: it = mappings.iterator();
277: while (it.hasNext()) {
278: XmlConfigMapping mapping;
279:
280: mapping = (XmlConfigMapping) it.next();
281: validator.addMapping(mapping.getFrom(), mapping.getTo());
282: }
283:
284: //TODO: this needs to be done better.
285: if (label != null) {
286: if (label.getValue() != null) {
287: validator.setLabel(label.getValue());
288: } else {
289: validator.setLabel(getResource(label.getResourceId(),
290: defaultResource, globalDefaultResource), label
291: .getResourceKey());
292: }
293: }
294:
295: if (doc != null) {
296: validator.setDoc(doc.getContent());
297: }
298: } //end configureValidator()
299: } //end OgnlXmlServiceFactory
|