001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.cocoon.transformation.helpers;
018:
019: import org.apache.avalon.framework.configuration.Configuration;
020: import org.apache.avalon.framework.configuration.ConfigurationException;
021: import org.apache.avalon.framework.configuration.SAXConfigurationHandler;
022: import org.apache.excalibur.source.Source;
023:
024: import org.apache.cocoon.Constants;
025: import org.apache.cocoon.acting.ConfigurationHelper;
026: import org.apache.cocoon.acting.ValidatorActionResult;
027: import org.apache.cocoon.components.source.SourceUtil;
028: import org.apache.cocoon.environment.ObjectModelHelper;
029: import org.apache.cocoon.environment.Request;
030: import org.apache.cocoon.environment.SourceResolver;
031:
032: import org.apache.avalon.framework.logger.Logger;
033:
034: import java.util.HashMap;
035: import java.util.Map;
036:
037: /**
038: * The <code>ValidatorActionResult</code> object helper
039: *
040: * @author <a href="mailto:haul@apache.org">Christian Haul</a>
041: * @version CVS $Id: FormValidatorHelper.java 433543 2006-08-22 06:22:54Z crossley $
042: */
043: public class FormValidatorHelper {
044:
045: private static Map configurations = new HashMap();
046:
047: /**
048: * these make it easier for the xsl
049: */
050:
051: String current_descriptor = null;
052: boolean current_reloadable = true;
053: Logger current_logger = null;
054: String current_constraint_set = null;
055: String current_parameter = null;
056: SourceResolver current_resolver = null;
057:
058: public FormValidatorHelper(String descriptor, boolean reloadable,
059: Logger logger, SourceResolver resolver) {
060: current_descriptor = descriptor;
061: current_reloadable = reloadable;
062: current_logger = logger;
063: current_resolver = resolver;
064: }
065:
066: public FormValidatorHelper(String descriptor, boolean reloadable,
067: Logger logger, SourceResolver resolver, String constraintset) {
068: current_descriptor = descriptor;
069: current_reloadable = reloadable;
070: current_logger = logger;
071: current_resolver = resolver;
072: current_constraint_set = constraintset;
073: }
074:
075: /**
076: * keep track of current parameter context
077: */
078: public void setParameter(String parameter) {
079: current_parameter = parameter;
080: }
081:
082: /**
083: * keep track of current constraint-set context
084: * (probably this is not needed?)
085: */
086: public void setConstraintSet(String constraintset) {
087: current_constraint_set = constraintset;
088: }
089:
090: /**
091: * Get the specified attribute
092: *
093: * @param objectModel The Map objectModel
094: * @param name The parameter name
095: */
096: public static Object getAttribute(Map objectModel, String name) {
097: Request request = ObjectModelHelper.getRequest(objectModel);
098: return request.getAttribute(name);
099: }
100:
101: /**
102: * Extracts the validation results from the request attribute
103: *
104: * @param objectModel The Map objectModel
105: * @return Map with ValidatorActionResults
106: * @see org.apache.cocoon.acting.ValidatorActionResult
107: */
108: public static Map getResults(Map objectModel) {
109: Request request = ObjectModelHelper.getRequest(objectModel);
110: return (Map) request
111: .getAttribute(Constants.XSP_FORMVALIDATOR_PATH);
112: }
113:
114: /**
115: * Extracts the validation results from the request attribute
116: * for a specific request parameter
117: *
118: * @param objectModel The Map objectModel
119: * @param name Request parameter's name
120: * @see org.apache.cocoon.acting.ValidatorActionResult
121: */
122: public static ValidatorActionResult getParamResult(Map objectModel,
123: String name) {
124: ValidatorActionResult result = ValidatorActionResult.NOTPRESENT;
125: Map param_result = getResults(objectModel);
126: if (param_result != null) {
127: result = (ValidatorActionResult) param_result.get(name);
128: }
129: return (result != null ? result
130: : ValidatorActionResult.NOTPRESENT);
131: }
132:
133: /**
134: * Extracts the validation results from the request attribute
135: * for the context's current request parameter
136: *
137: * @param objectModel The Map objectModel
138: * @see org.apache.cocoon.acting.ValidatorActionResult
139: */
140: public ValidatorActionResult getParamResult(Map objectModel) {
141: ValidatorActionResult result = ValidatorActionResult.NOTPRESENT;
142: Map param_result = getResults(objectModel);
143: if (param_result != null) {
144: result = (ValidatorActionResult) param_result
145: .get(current_parameter);
146: }
147: return (result != null ? result
148: : ValidatorActionResult.NOTPRESENT);
149: }
150:
151: /**
152: * Test whether the validation returned no error for this
153: * parameter.
154: *
155: * @param objectModel The Map objectModel
156: * @param name Request parameter's name
157: * @return true only if the parameter was validated and the validation
158: * did not return an error.
159: */
160: public static boolean isOK(Map objectModel, String name) {
161: return getParamResult(objectModel, name).equals(
162: ValidatorActionResult.OK);
163: }
164:
165: /**
166: * Test whether the validation returned no error for the
167: * context's current parameter.
168: *
169: * @param objectModel The Map objectModel
170: * @return true only if the parameter was validated and the validation
171: * did not return an error.
172: */
173: public boolean isOK(Map objectModel) {
174: return isOK(objectModel, current_parameter);
175: }
176:
177: /**
178: * Test whether the validation returned an error for this
179: * parameter.
180: *
181: * @param objectModel The Map objectModel
182: * @param name Request parameter's name
183: * @return true if the parameter was either not validated or the validation
184: * returned an error.
185: */
186: public static boolean isError(Map objectModel, String name) {
187: return getParamResult(objectModel, name).ge(
188: ValidatorActionResult.ERROR);
189: }
190:
191: /**
192: * Test whether the validation returned an error for the
193: * context's current parameter.
194: *
195: * @param objectModel The Map objectModel
196: * @return true if the parameter was either not validated or the validation
197: * returned an error.
198: */
199: public boolean isError(Map objectModel) {
200: return isError(objectModel, current_parameter);
201: }
202:
203: /**
204: * Test whether the validated parameter was null but wasn't allowed to.
205: *
206: * @param objectModel The Map objectModel
207: * @param name Request parameter's name
208: * @return true if the parameter was validated and the validation
209: * returned an error because the parameter was null but wasn't allowd to.
210: */
211: public static boolean isNull(Map objectModel, String name) {
212: return getParamResult(objectModel, name).equals(
213: ValidatorActionResult.ISNULL);
214: }
215:
216: /**
217: * Test whether the context's current parameter as validated was null but
218: * wasn't allowed to.
219: *
220: * @param objectModel The Map objectModel
221: * @return true if the parameter was validated and the validation
222: * returned an error because the parameter was null but wasn't allowd to.
223: */
224: public boolean isNull(Map objectModel) {
225: return isNull(objectModel, current_parameter);
226: }
227:
228: /**
229: * Test whether the validated parameter was too small.
230: *
231: * @param objectModel The Map objectModel
232: * @param name Request parameter's name
233: * @return true if the parameter was validated and the validation
234: * returned an error because either its value or its length was
235: * too small.
236: */
237: public static boolean isTooSmall(Map objectModel, String name) {
238: boolean ok = getParamResult(objectModel, name).equals(
239: ValidatorActionResult.TOOSMALL);
240:
241: if (!ok) {
242: ok = isNull(objectModel, name);
243: }
244:
245: return ok;
246: }
247:
248: /**
249: * Test whether the context's current parameter was too small.
250: *
251: * @param objectModel The Map objectModel
252: * @return true if the parameter was validated and the validation
253: * returned an error because either its value or its length was
254: * too small.
255: */
256: public boolean isTooSmall(Map objectModel) {
257: return isTooSmall(objectModel, current_parameter);
258: }
259:
260: /**
261: * Test whether the validated parameter was too large.
262: *
263: * @param objectModel The Map objectModel
264: * @param name Request parameter's name
265: * @return true if the parameter was validated and the validation
266: * returned an error because either its value or its length was
267: * too large.
268: */
269: public static boolean isTooLarge(Map objectModel, String name) {
270: return (getParamResult(objectModel, name) == ValidatorActionResult.TOOLARGE);
271: }
272:
273: /**
274: * Test whether the context's current parameter was too large.
275: *
276: * @param objectModel The Map objectModel
277: * @return true if the parameter was validated and the validation
278: * returned an error because either its value or its length was
279: * too large.
280: */
281: public boolean isTooLarge(Map objectModel) {
282: return isTooLarge(objectModel, current_parameter);
283: }
284:
285: /**
286: * Test whether the validated parameter wasn't matched by the requested
287: * regular expression.
288: *
289: * @param objectModel The Map objectModel
290: * @param name Request parameter's name
291: * @return true if the parameter was validated and the validation
292: * returned an error because its value wasn't matched by the requested
293: * regular expression.
294: */
295: public static boolean isNoMatch(Map objectModel, String name) {
296: return getParamResult(objectModel, name).equals(
297: ValidatorActionResult.NOMATCH);
298: }
299:
300: /**
301: * Test whether the context's current parameter wasn't matched by the requested
302: * regular expression.
303: *
304: * @param objectModel The Map objectModel
305: * @return true if the parameter was validated and the validation
306: * returned an error because its value wasn't matched by the requested
307: * regular expression.
308: */
309: public boolean isNoMatch(Map objectModel) {
310: return isNoMatch(objectModel, current_parameter);
311: }
312:
313: /**
314: * Test whether the validated parameter wasn't validated
315: *
316: * @param objectModel The Map objectModel
317: * @param name Request parameter's name
318: * @return true if the parameter was not validated.
319: */
320: public static boolean isNotPresent(Map objectModel, String name) {
321: return getParamResult(objectModel, name).equals(
322: ValidatorActionResult.NOTPRESENT);
323: }
324:
325: /**
326: * Test whether the context's current parameter wasn't validated
327: *
328: * @param objectModel The Map objectModel
329: * @return true if the parameter was not validated.
330: */
331: public boolean isNotPresent(Map objectModel) {
332: return isNotPresent(objectModel, current_parameter);
333: }
334:
335: /**
336: * Set up the complementary configuration file. Please note that
337: * multiple Actions can share the same configurations. By using
338: * this approach, we can limit the number of config files.
339: * Also note that the configuration file does not have to be a file.
340: *
341: * This is based on the similar named functions in
342: * org.apache.cocoon.acting.AbstractComplimentaryConfigurableAction
343: * with the addition of reloadable configuration files, reloadable
344: * flagg, manager, and logger parameter.
345: *
346: * @param descriptor URL of descriptor.xml file @see org.apache.cocoon.acting.AbstractComplimentaryConfigurableAction
347: * @param resolver
348: * @param reloadable set to <code>true</code> if changes of
349: * <code>descriptor</code> should trigger a reload. Note that this
350: * only works if <code>Source</code> is able to determine the
351: * modification time @see org.apache.cocoon.environment.Source
352: * @param logger used to send debug and error messages to
353: * @return up-to-date configuration, either (re)loaded or cached.
354: */
355:
356: protected static Configuration getConfiguration(String descriptor,
357: SourceResolver resolver, boolean reloadable, Logger logger)
358: throws ConfigurationException {
359:
360: if (descriptor == null) {
361: throw new ConfigurationException(
362: "The form descriptor is not set!");
363: }
364:
365: ConfigurationHelper conf = null;
366: synchronized (FormValidatorHelper.configurations) {
367: Source source = null;
368: try {
369: source = resolver.resolveURI(descriptor);
370: conf = (ConfigurationHelper) FormValidatorHelper.configurations
371: .get(source.getURI());
372: if (conf == null
373: || (reloadable && conf.lastModified != source
374: .getLastModified())) {
375: logger.debug("(Re)Loading " + descriptor);
376:
377: if (conf == null) {
378: conf = new ConfigurationHelper();
379: }
380:
381: SAXConfigurationHandler builder = new SAXConfigurationHandler();
382: SourceUtil.toSAX(source, builder);
383:
384: conf.lastModified = source.getLastModified();
385: conf.configuration = builder.getConfiguration();
386:
387: FormValidatorHelper.cacheConfiguration(source
388: .getURI(), conf);
389: } else {
390: logger.debug("Using cached configuration for "
391: + descriptor);
392: }
393: } catch (Exception e) {
394: logger
395: .error(
396: "Could not configure Database mapping environment",
397: e);
398: throw new ConfigurationException(
399: "Error trying to load configurations for resource: "
400: + source.getURI());
401: } finally {
402: resolver.release(source);
403: }
404: }
405:
406: return conf.configuration;
407: }
408:
409: /**
410: * Cache the configuration so that we can use it later.
411: */
412: private static void cacheConfiguration(String descriptor,
413: ConfigurationHelper conf) {
414: synchronized (FormValidatorHelper.configurations) {
415: FormValidatorHelper.configurations.put(descriptor, conf);
416: }
417: }
418:
419: /**
420: * Iterate over a set of configurations and return the one whose
421: * name matches the given one.
422: *
423: * @param conf set of configurations
424: * @param name name of configuration
425: * @param logger
426: * @return specified configuration or <code>null</code> if not found.
427: */
428: protected static Configuration getConfigurationByName(
429: Configuration[] conf, String name, Logger logger) {
430: int j = 0;
431: boolean found = false;
432: String setname = null;
433: for (j = 0; j < conf.length; j++) {
434: setname = conf[j].getAttribute("name", "");
435: if (name.trim().equals(setname.trim())) {
436: found = true;
437: break;
438: }
439: }
440: if (!found) {
441: logger
442: .debug("FormValidatorHelper.getConfigurationByName: configuration "
443: + name + " not found.");
444: return null;
445: }
446: return conf[j];
447: }
448:
449: /**
450: * Get an attribute for a parameter as specified in
451: * descriptor.xml.
452: *
453: * @param descriptor URL of descriptor.xml file @see org.apache.cocoon.acting.AbstractComplimentaryConfigurableAction
454: * @param resolver
455: * @param reloadable set to <code>true</code> if changes of
456: * <code>descriptor</code> should trigger a reload. Note that this
457: * only works if <code>Source</code> is able to determine the
458: * modification time @see org.apache.cocoon.environment.Source
459: * @param logger used to send debug and error messages to
460: * @param attribute attribute name
461: * @return attribute value or <code>null</code>
462: */
463: public static String getParameterAttributes(String descriptor,
464: SourceResolver resolver, boolean reloadable,
465: String constraintset, String parameter, String attribute,
466: Logger logger) {
467: try {
468: Configuration conf = getConfiguration(descriptor, resolver,
469: reloadable, logger);
470: Configuration[] desc = conf.getChildren("parameter");
471: Configuration[] csets = conf.getChildren("constraint-set");
472:
473: Configuration cset = getConfigurationByName(csets,
474: constraintset, logger);
475:
476: Configuration[] set = cset.getChildren("validate");
477: Configuration constraints = getConfigurationByName(set,
478: parameter, logger);
479: Configuration descr = getConfigurationByName(desc,
480: parameter, logger);
481: return constraints.getAttribute(attribute, descr
482: .getAttribute(attribute, ""));
483: } catch (Exception e) {
484: logger
485: .debug("FormValidatorHelper.getParameterAttributes Exception "
486: + e);
487: }
488:
489: return "";
490: }
491:
492: /**
493: * Get an attribute for the context's current parameter as specified in
494: * descriptor.xml.
495: *
496: * @param attribute attribute name
497: * @return attribute value or <code>null</code>
498: */
499: public String getParameterAttribute(String attribute) {
500: return FormValidatorHelper.getParameterAttributes(
501: current_descriptor, current_resolver,
502: current_reloadable, current_constraint_set,
503: current_parameter, attribute, current_logger);
504: }
505:
506: /**
507: * Get an attribute for a parameter as specified in
508: * descriptor.xml.
509: *
510: * @param attribute attribute name
511: * @return attribute value or <code>null</code>
512: */
513: public String getParameterAttribute(String parameter,
514: String attribute) {
515: return FormValidatorHelper.getParameterAttributes(
516: current_descriptor, current_resolver,
517: current_reloadable, current_constraint_set, parameter,
518: attribute, current_logger);
519: }
520: }
|