001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: MetaData.java 3717 2007-04-12 18:01:39Z gbevin $
007: */
008: package com.uwyn.rife.site;
009:
010: import com.uwyn.rife.tools.ExceptionUtils;
011: import java.util.Collection;
012: import java.util.List;
013: import java.util.Set;
014: import java.util.logging.Logger;
015:
016: /**
017: * This abstract base class can be conveniently used to added {@link
018: * Constrained} and {@link ValidatedConstrained} meta data to a POJO.
019: * <p>Besides implementing all the required interfaces for you, it also sets
020: * up the underlying data structures in a lazy fashion. This allows you to
021: * benefit from a rich API without the memory overhead when the meta data
022: * isn't used.
023: *
024: * @author Geert Bevin (gbevin[remove] at uwyn dot com)
025: * @see MetaDataMerged
026: * @see MetaDataBeanAware
027: * @version $Revision: 3717 $
028: * @since 1.4
029: */
030: public abstract class MetaData<B extends ConstrainedBean, P extends ConstrainedProperty>
031: implements ValidatedConstrained<P>, Constrained<B, P>,
032: MetaDataMerged, MetaDataBeanAware, Cloneable {
033: private Validated mMetaDataBean = this ;
034: private Validation<B, P> mValidation;
035:
036: /**
037: * This method is called at least once and maximum once when any meta-data
038: * introspection logic is executed.
039: * <p>You need to implement this method since it will be called after the
040: * underlying validation context has been initialized. Incidentally, by
041: * doing all your meta data setup here, you don't enforce a performance
042: * penalty at each object construction like when you do this in the
043: * default constructor.
044: *
045: * @since 1.4
046: */
047: public void activateMetaData() {
048: }
049:
050: public final void setMetaDataBean(Object bean) {
051: mMetaDataBean = (Validated) bean;
052:
053: if (mValidation != null) {
054: mValidation.provideValidatedBean(mMetaDataBean);
055: }
056: }
057:
058: private void ensureActivatedMetaData() {
059: if (null == mValidation) {
060: mValidation = new Validation<B, P>();
061: mValidation.provideValidatedBean(mMetaDataBean);
062: activateMetaData();
063: }
064: }
065:
066: public void provideValidatedBean(Validated bean) {
067: ensureActivatedMetaData();
068: mValidation.provideValidatedBean(bean);
069: }
070:
071: public final Validated retrieveValidatedBean() {
072: ensureActivatedMetaData();
073: return mValidation.retrieveValidatedBean();
074: }
075:
076: public void addConstraint(B constrainedBean) {
077: ensureActivatedMetaData();
078: mValidation.addConstraint(constrainedBean);
079: }
080:
081: public void addConstraint(P constrainedProperty) {
082: ensureActivatedMetaData();
083: mValidation.addConstraint(constrainedProperty);
084: }
085:
086: public B getConstrainedBean() {
087: ensureActivatedMetaData();
088: return mValidation.getConstrainedBean();
089: }
090:
091: public Collection<P> getConstrainedProperties() {
092: ensureActivatedMetaData();
093: return mValidation.getConstrainedProperties();
094: }
095:
096: public boolean hasPropertyConstraint(String name) {
097: ensureActivatedMetaData();
098: return mValidation.hasPropertyConstraint(name);
099: }
100:
101: public P getConstrainedProperty(String propertyName) {
102: ensureActivatedMetaData();
103: return mValidation.getConstrainedProperty(propertyName);
104: }
105:
106: public boolean validate() {
107: ensureActivatedMetaData();
108: return mValidation.validate();
109: }
110:
111: public boolean validate(ValidationContext context) {
112: ensureActivatedMetaData();
113: return mValidation.validate(context);
114: }
115:
116: public void resetValidation() {
117: ensureActivatedMetaData();
118: mValidation.resetValidation();
119: }
120:
121: public void addValidationError(ValidationError error) {
122: ensureActivatedMetaData();
123: mValidation.addValidationError(error);
124: }
125:
126: public Set<ValidationError> getValidationErrors() {
127: ensureActivatedMetaData();
128: return mValidation.getValidationErrors();
129: }
130:
131: public int countValidationErrors() {
132: ensureActivatedMetaData();
133: return mValidation.countValidationErrors();
134: }
135:
136: public void replaceValidationErrors(Set<ValidationError> errors) {
137: ensureActivatedMetaData();
138: mValidation.replaceValidationErrors(errors);
139: }
140:
141: public void limitSubjectErrors(String subject) {
142: ensureActivatedMetaData();
143: mValidation.limitSubjectErrors(subject);
144: }
145:
146: public void unlimitSubjectErrors(String subject) {
147: ensureActivatedMetaData();
148: mValidation.unlimitSubjectErrors(subject);
149: }
150:
151: public List<String> getValidatedSubjects() {
152: ensureActivatedMetaData();
153: return mValidation.getValidatedSubjects();
154: }
155:
156: public boolean isSubjectValid(String subject) {
157: ensureActivatedMetaData();
158: return mValidation.isSubjectValid(subject);
159: }
160:
161: public void makeErrorValid(String identifier, String subject) {
162: ensureActivatedMetaData();
163: mValidation.makeErrorValid(identifier, subject);
164: }
165:
166: public void makeSubjectValid(String subject) {
167: ensureActivatedMetaData();
168: mValidation.makeSubjectValid(subject);
169: }
170:
171: public ValidationGroup<P> addGroup(String name) {
172: ensureActivatedMetaData();
173: return mValidation.addGroup(name);
174: }
175:
176: public void focusGroup(String name) {
177: ensureActivatedMetaData();
178: mValidation.focusGroup(name);
179: }
180:
181: public void resetGroup(String name) {
182: ensureActivatedMetaData();
183: mValidation.resetGroup(name);
184: }
185:
186: public void addRule(ValidationRule rule) {
187: ensureActivatedMetaData();
188: mValidation.addRule(rule);
189: }
190:
191: public List<PropertyValidationRule> addConstrainedPropertyRules(
192: P constrainedProperty) {
193: ensureActivatedMetaData();
194: return mValidation
195: .addConstrainedPropertyRules(constrainedProperty);
196: }
197:
198: public List<PropertyValidationRule> generateConstrainedPropertyRules(
199: P constrainedProperty) {
200: ensureActivatedMetaData();
201: return mValidation
202: .generateConstrainedPropertyRules(constrainedProperty);
203: }
204:
205: public List<ValidationRule> getRules() {
206: ensureActivatedMetaData();
207: return mValidation.getRules();
208: }
209:
210: public Collection<ValidationGroup<P>> getGroups() {
211: ensureActivatedMetaData();
212: return mValidation.getGroups();
213: }
214:
215: public ValidationGroup<P> getGroup(String name) {
216: ensureActivatedMetaData();
217: return mValidation.getGroup(name);
218: }
219:
220: public boolean validateGroup(String name) {
221: ensureActivatedMetaData();
222: return mValidation.validateGroup(name);
223: }
224:
225: public boolean validateGroup(String name, ValidationContext context) {
226: ensureActivatedMetaData();
227: return mValidation.validateGroup(name, context);
228: }
229:
230: public Collection<String> getLoadingErrors(String propertyName) {
231: ensureActivatedMetaData();
232: return mValidation.getLoadingErrors(propertyName);
233: }
234:
235: public Object clone() throws CloneNotSupportedException {
236: MetaData new_metadata = null;
237: try {
238: new_metadata = (MetaData) super .clone();
239:
240: if (mValidation != null) {
241: new_metadata.mValidation = (Validation) mValidation
242: .clone();
243: }
244:
245: if (this == new_metadata.mMetaDataBean) {
246: if (mValidation != null) {
247: new_metadata.mValidation
248: .provideValidatedBean(new_metadata);
249: }
250: new_metadata.mMetaDataBean = new_metadata;
251: }
252: } catch (CloneNotSupportedException e) {
253: ///CLOVER:OFF
254: // this should never happen
255: Logger.getLogger("com.uwyn.rife.site").severe(
256: ExceptionUtils.getExceptionStackTrace(e));
257: ///CLOVER:ON
258: }
259:
260: return new_metadata;
261: }
262: }
|