001: /*
002: * Copyright (c) 2003-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.validation.util;
032:
033: import java.beans.PropertyChangeListener;
034: import java.beans.PropertyChangeSupport;
035:
036: import com.jgoodies.validation.Severity;
037: import com.jgoodies.validation.ValidationResult;
038: import com.jgoodies.validation.ValidationResultModel;
039:
040: /**
041: * An abstract class that minimizes the effort required to implement
042: * the {@link ValidationResultModel} interface. It provides a property
043: * change support
044: * behavior to add and remove methods
045: * to convert boolean, double, float, int, and long to their
046: * corresponding Object values.<p>
047: *
048: * Subclasses must implement <code>getResult()</code> and
049: * <code>setResult(ValidationResult)</code> to get and set
050: * the observable validation result. #getResult always returns a
051: * non-null result, #setResult accepts only non-null results.
052: *
053: * @author Karsten Lentzsch
054: * @version $Revision: 1.6 $
055: *
056: * @see com.jgoodies.validation.util.DefaultValidationResultModel
057: *
058: * @since 1.0.1
059: */
060: public abstract class AbstractValidationResultModel implements
061: ValidationResultModel {
062:
063: /**
064: * If any <code>PropertyChangeListeners</code> have been registered,
065: * the <code>changeSupport</code> field describes them.
066: *
067: * @serial
068: * @see #addPropertyChangeListener(PropertyChangeListener)
069: * @see #addPropertyChangeListener(String, PropertyChangeListener)
070: * @see #removePropertyChangeListener(PropertyChangeListener)
071: * @see #removePropertyChangeListener(String, PropertyChangeListener)
072: * @see #firePropertyChange(String, boolean, boolean)
073: * @see #firePropertyChange(String, Object, Object)
074: */
075: private PropertyChangeSupport changeSupport;
076:
077: // Accessors **************************************************************
078:
079: /**
080: * Looks up and returns the severity of the validation result,
081: * one of error, warning, or <code>null</code>.
082: *
083: * @return the severity of the validation result
084: */
085: public final Severity getSeverity() {
086: return getResult().getSeverity();
087: }
088:
089: /**
090: * Checks and answers whether the validation result has errors.
091: *
092: * @return true if the validation result has errors, false otherwise
093: */
094: public final boolean hasErrors() {
095: return getResult().hasErrors();
096: }
097:
098: /**
099: * Checks and answers whether the validation result has messages.
100: *
101: * @return true if the validation result has messages, false otherwise
102: */
103: public final boolean hasMessages() {
104: return getResult().hasMessages();
105: }
106:
107: // Convenience Behavior ***************************************************
108:
109: /**
110: * Notifies all registered listeners about changes of the result itself
111: * and the properties for severity, errors and messages. Useful to fire
112: * all changes in a #setResult implementation.
113: *
114: * @param oldResult the old validation result
115: * @param newResult the new validation result
116: *
117: * @throws NullPointerException if the old or new result is <code>null</code>
118: *
119: * @see #setResult(ValidationResult)
120: * @see ValidationResultModelContainer#setResult(ValidationResult)
121: */
122: protected final void firePropertyChanges(
123: ValidationResult oldResult, ValidationResult newResult) {
124: Severity oldSeverity = oldResult.getSeverity();
125: boolean oldErrors = oldResult.hasErrors();
126: boolean oldMessages = oldResult.hasMessages();
127: Severity newSeverity = newResult.getSeverity();
128: boolean newErrors = newResult.hasErrors();
129: boolean newMessages = newResult.hasMessages();
130: firePropertyChange(PROPERTYNAME_RESULT, oldResult, newResult);
131: firePropertyChange(PROPERTYNAME_ERRORS, oldErrors, newErrors);
132: firePropertyChange(PROPERTYNAME_MESSAGES, oldMessages,
133: newMessages);
134: firePropertyChange(PROPERTYNAME_SEVERITY, oldSeverity,
135: newSeverity);
136: }
137:
138: // Managing Property Change Listeners *************************************
139:
140: /**
141: * Adds a PropertyChangeListener to the listener list. The listener is
142: * registered for all bound properties of this class.<p>
143: *
144: * If listener is null, no exception is thrown and no action is
145: * performed.
146: *
147: * @param listener the PropertyChangeListener to be added
148: *
149: * @see #removePropertyChangeListener(PropertyChangeListener)
150: * @see #getPropertyChangeListeners()
151: * @see #addPropertyChangeListener(String, PropertyChangeListener)
152: */
153: public final synchronized void addPropertyChangeListener(
154: PropertyChangeListener listener) {
155: if (listener == null) {
156: return;
157: }
158: if (changeSupport == null) {
159: changeSupport = new PropertyChangeSupport(this );
160: }
161: changeSupport.addPropertyChangeListener(listener);
162: }
163:
164: /**
165: * Removes a PropertyChangeListener from the listener list. This method
166: * should be used to remove PropertyChangeListeners that were registered
167: * for all bound properties of this class.<p>
168: *
169: * If listener is null, no exception is thrown and no action is performed.
170: *
171: * @param listener the PropertyChangeListener to be removed
172: *
173: * @see #addPropertyChangeListener(PropertyChangeListener)
174: * @see #getPropertyChangeListeners()
175: * @see #removePropertyChangeListener(String, PropertyChangeListener)
176: */
177: public final synchronized void removePropertyChangeListener(
178: PropertyChangeListener listener) {
179: if (listener == null || changeSupport == null) {
180: return;
181: }
182: changeSupport.removePropertyChangeListener(listener);
183: }
184:
185: /**
186: * Adds a PropertyChangeListener to the listener list for a specific
187: * property. The specified property may be user-defined.<p>
188: *
189: * Note that if this Model is inheriting a bound property, then no event
190: * will be fired in response to a change in the inherited property.<p>
191: *
192: * If listener is null, no exception is thrown and no action is performed.
193: *
194: * @param propertyName one of the property names listed above
195: * @param listener the PropertyChangeListener to be added
196: *
197: * @see #removePropertyChangeListener(String, PropertyChangeListener)
198: * @see #getPropertyChangeListeners(String)
199: * @see #addPropertyChangeListener(String, PropertyChangeListener)
200: */
201: public final synchronized void addPropertyChangeListener(
202: String propertyName, PropertyChangeListener listener) {
203: if (listener == null) {
204: return;
205: }
206: if (changeSupport == null) {
207: changeSupport = new java.beans.PropertyChangeSupport(this );
208: }
209: changeSupport.addPropertyChangeListener(propertyName, listener);
210: }
211:
212: /**
213: * Removes a PropertyChangeListener from the listener list for a specific
214: * property. This method should be used to remove PropertyChangeListeners
215: * that were registered for a specific bound property.<p>
216: *
217: * If listener is null, no exception is thrown and no action is performed.
218: *
219: * @param propertyName a valid property name
220: * @param listener the PropertyChangeListener to be removed
221: *
222: * @see #addPropertyChangeListener(String, PropertyChangeListener)
223: * @see #getPropertyChangeListeners(String)
224: * @see #removePropertyChangeListener(PropertyChangeListener)
225: */
226: public final synchronized void removePropertyChangeListener(
227: String propertyName, PropertyChangeListener listener) {
228: if (listener == null || changeSupport == null) {
229: return;
230: }
231: changeSupport.removePropertyChangeListener(propertyName,
232: listener);
233: }
234:
235: /**
236: * Returns an array of all the property change listeners
237: * registered on this component.
238: *
239: * @return all of this component's <code>PropertyChangeListener</code>s
240: * or an empty array if no property change
241: * listeners are currently registered
242: *
243: * @see #addPropertyChangeListener(PropertyChangeListener)
244: * @see #removePropertyChangeListener(PropertyChangeListener)
245: * @see #getPropertyChangeListeners(String)
246: * @see PropertyChangeSupport#getPropertyChangeListeners()
247: */
248: public final synchronized PropertyChangeListener[] getPropertyChangeListeners() {
249: if (changeSupport == null) {
250: return new PropertyChangeListener[0];
251: }
252: return changeSupport.getPropertyChangeListeners();
253: }
254:
255: /**
256: * Returns an array of all the listeners which have been associated
257: * with the named property.
258: *
259: * @param propertyName the name of the property to lookup listeners
260: * @return all of the <code>PropertyChangeListeners</code> associated with
261: * the named property or an empty array if no listeners have
262: * been added
263: *
264: * @see #addPropertyChangeListener(String, PropertyChangeListener)
265: * @see #removePropertyChangeListener(String, PropertyChangeListener)
266: * @see #getPropertyChangeListeners()
267: */
268: public final synchronized PropertyChangeListener[] getPropertyChangeListeners(
269: String propertyName) {
270: if (changeSupport == null) {
271: return new PropertyChangeListener[0];
272: }
273: return changeSupport.getPropertyChangeListeners(propertyName);
274: }
275:
276: // Firing Changes for Bound Properties *************************************
277:
278: /**
279: * Support for reporting bound property changes for Object properties.
280: * This method can be called when a bound property has changed and it will
281: * send the appropriate PropertyChangeEvent to any registered
282: * PropertyChangeListeners.
283: *
284: * @param propertyName the property whose value has changed
285: * @param oldValue the property's previous value
286: * @param newValue the property's new value
287: */
288: protected final void firePropertyChange(String propertyName,
289: Object oldValue, Object newValue) {
290: PropertyChangeSupport aChangeSupport = this .changeSupport;
291: if (aChangeSupport == null) {
292: return;
293: }
294: aChangeSupport.firePropertyChange(propertyName, oldValue,
295: newValue);
296: }
297:
298: /**
299: * Support for reporting bound property changes for boolean properties.
300: * This method can be called when a bound property has changed and it will
301: * send the appropriate PropertyChangeEvent to any registered
302: * PropertyChangeListeners.
303: *
304: * @param propertyName the property whose value has changed
305: * @param oldValue the property's previous value
306: * @param newValue the property's new value
307: */
308: protected final void firePropertyChange(String propertyName,
309: boolean oldValue, boolean newValue) {
310: PropertyChangeSupport aChangeSupport = this.changeSupport;
311: if (aChangeSupport == null) {
312: return;
313: }
314: aChangeSupport.firePropertyChange(propertyName, oldValue,
315: newValue);
316: }
317:
318: }
|