001: /* $Id: AbstractBeanData.java 812 2007-01-15 20:48:12Z hengels $ */
002: package org.conform;
003:
004: import java.util.*;
005: import java.beans.PropertyChangeSupport;
006: import java.beans.PropertyChangeListener;
007:
008: /**
009: * @version $Revision: 812 $
010: */
011: public abstract class AbstractBeanData extends AbstractData implements
012: BeanData {
013: BeanMeta beanMeta;
014: Map<PropertyMeta, PropertyData> propertyDatas = new HashMap<PropertyMeta, PropertyData>();
015:
016: PropertyChangeSupport changeSupport = new PropertyChangeSupport(
017: this );
018: ValidationListener forwarder = new ValidationListener() {
019: public void addIssues(ValidationEvent event) {
020: fireAddIssue(event);
021: }
022:
023: public void removeIssues(ValidationEvent event) {
024: fireRemoveIssue(event);
025: }
026:
027: public void clearIssues(Meta meta) {
028: }
029: };
030:
031: protected AbstractBeanData(BeanMeta beanMeta) {
032: this .beanMeta = beanMeta;
033:
034: for (PropertyMeta propertyMeta : this .beanMeta.getProperties()) {
035: PropertyData propertyData = doGetPropertyData(propertyMeta);
036:
037: propertyDatas.put(propertyMeta, propertyData);
038: propertyData.addValidationListener(forwarder);
039: propertyData.setIssuePublishingActive(true);
040:
041: PropertyChangeListener listener = (PropertyChangeListener) propertyMeta
042: .getAttribute(PropertyMeta.ATTRIBUTE_CHANGE_LISTENER);
043: if (listener != null)
044: addPropertyChangeListener(propertyMeta.getName(),
045: listener);
046: }
047: }
048:
049: public PropertyData getPropertyData(PropertyMeta propertyMeta) {
050: return propertyDatas.get(propertyMeta);
051: }
052:
053: protected abstract PropertyData doGetPropertyData(
054: PropertyMeta propertyMeta);
055:
056: public BeanMeta getBeanMeta() {
057: return beanMeta;
058: }
059:
060: public Meta getMeta() {
061: return beanMeta;
062: }
063:
064: public Object getValue() {
065: return doGetValue();
066: }
067:
068: protected abstract Object doGetValue();
069:
070: public void setValue(Object bean) {
071: Object oldBean = doGetValue();
072: if (oldBean != null) {
073: for (PropertyData propertyData : propertyDatas.values()) {
074: if (propertyData.getPropertyMeta().isApplicable())
075: changeSupport.firePropertyChange(propertyData
076: .getPropertyMeta().getName(), propertyData
077: .getValue(), null);
078: }
079: }
080:
081: doSetValue(validate(bean));
082:
083: if (bean != null) {
084: for (PropertyData propertyData : propertyDatas.values()) {
085: PropertyMeta propertyMeta = propertyData
086: .getPropertyMeta();
087: if (propertyMeta.isApplicable()
088: && propertyMeta.isReadable()
089: && propertyMeta.isWritable())
090: propertyData.revalidate();
091:
092: propertyData.unsetInvalidValue();
093:
094: if (propertyMeta.isApplicable()
095: && propertyMeta.isReadable())
096: changeSupport.firePropertyChange(propertyMeta
097: .getName(), null, propertyData.getValue());
098: }
099: }
100: }
101:
102: protected abstract void doSetValue(Object bean);
103:
104: public void revalidate() {
105: try {
106: Object value = doGetValue();
107: validate(value);
108: } catch (ValidationException e) {
109: }
110: }
111:
112: public void revalidateAll() {
113: bufferedIssues.clear();
114: if (isIssuePublishingActive()) {
115: setIssuePublishingActive(false);
116: setIssuePublishingActive(true);
117: }
118: revalidate();
119: for (PropertyData propertyData : propertyDatas.values()) {
120: PropertyMeta propertyMeta = propertyData.getPropertyMeta();
121: if (propertyMeta.isApplicable()
122: && propertyMeta.isReadable()
123: && propertyMeta.isWritable())
124: propertyData.revalidate();
125: }
126: }
127:
128: public Object validate(Object value) throws ValidationException {
129: if (value == null)
130: return null;
131:
132: ValidationEvent addEvent = new ValidationEvent(this );
133: ValidationEvent removeEvent = new ValidationEvent(this );
134: List<ValidationException.Message> messages = new LinkedList<ValidationException.Message>();
135:
136: Collection validators = beanMeta.getValidators();
137: if (validators != null) {
138: Iterator iter = validators.iterator();
139: while (iter.hasNext()) {
140: BeanValidator validator = (BeanValidator) iter.next();
141: try {
142: if (arePropertiesValid(validator
143: .getAffectedPropertyNames()))
144: value = validator.validate(value);
145:
146: removeEvent.addIssue(new Issue(System
147: .identityHashCode(validator),
148: properties(validator
149: .getAffectedPropertyNames())));
150: } catch (ValidationException e) {
151: messages.addAll(e.getMessages());
152: for (ValidationException.Message message : e
153: .getMessages()) {
154: addEvent.addIssue(new Issue(System
155: .identityHashCode(validator),
156: properties(validator
157: .getAffectedPropertyNames()),
158: message.getCode(), message
159: .getArguments()));
160: }
161: }
162: }
163: }
164:
165: // fireRemoveIssue sends the issue to be removed
166: if (removeEvent.getIssues().size() != 0) {
167: fireRemoveIssue(removeEvent);
168: }
169:
170: // fireAddIssue sends an update of the issue
171: if (addEvent.getIssues().size() != 0) {
172: fireAddIssue(addEvent);
173: throw new ValidationException(messages);
174: }
175:
176: return value;
177: }
178:
179: private boolean arePropertiesValid(String[] propertyNames) {
180: for (String name : propertyNames) {
181: PropertyMeta propertyMeta = beanMeta.getProperty(name);
182: PropertyData propertyData = propertyDatas.get(propertyMeta);
183: if (propertyData.isInvalid())
184: return false;
185: }
186: return true;
187: }
188:
189: private PropertyMeta[] properties(String[] affectedPropertyNames) {
190: List<PropertyMeta> list = new ArrayList<PropertyMeta>(
191: affectedPropertyNames.length);
192: for (String name : affectedPropertyNames) {
193: list.add(beanMeta.getProperty(name));
194: }
195: return list
196: .toArray(new PropertyMeta[affectedPropertyNames.length]);
197: }
198:
199: public void addPropertyChangeListener(
200: PropertyChangeListener listener) {
201: changeSupport.addPropertyChangeListener(listener);
202: }
203:
204: public void removePropertyChangeListener(
205: PropertyChangeListener listener) {
206: changeSupport.removePropertyChangeListener(listener);
207: }
208:
209: public PropertyChangeListener[] getPropertyChangeListeners() {
210: return changeSupport.getPropertyChangeListeners();
211: }
212:
213: public void addPropertyChangeListener(String propertyName,
214: PropertyChangeListener listener) {
215: changeSupport.addPropertyChangeListener(propertyName, listener);
216: }
217:
218: public void removePropertyChangeListener(String propertyName,
219: PropertyChangeListener listener) {
220: changeSupport.removePropertyChangeListener(propertyName,
221: listener);
222: }
223:
224: public PropertyChangeListener[] getPropertyChangeListeners(
225: String propertyName) {
226: return changeSupport.getPropertyChangeListeners(propertyName);
227: }
228:
229: protected void firePropertyChange(String propertyName,
230: Object oldValue, Object newValue) {
231: changeSupport.firePropertyChange(propertyName, oldValue,
232: newValue);
233: }
234:
235: public void initialize() {
236: for (PropertyData propertyData : propertyDatas.values()) {
237: if (propertyData.getPropertyMeta().isApplicable()) {
238: propertyData.initialize();
239: }
240: }
241: }
242:
243: public void update() {
244: for (PropertyData propertyData : propertyDatas.values()) {
245: if (propertyData.getPropertyMeta().isApplicable()) {
246: propertyData.update();
247: }
248: }
249: }
250:
251: public void flush() {
252: for (PropertyData propertyData : propertyDatas.values()) {
253: if (propertyData.getPropertyMeta().isApplicable()) {
254: propertyData.flush();
255: }
256: }
257: }
258:
259: public void clear() {
260: for (PropertyData propertyData : propertyDatas.values()) {
261: if (propertyData.getPropertyMeta().isApplicable()) {
262: propertyData.clear();
263: }
264: }
265: }
266:
267: public String toString() {
268: return getMeta().getName();
269: }
270: }
|