001: /*
002: * ====================================================================
003: * JAFFA - Java Application Framework For All
004: *
005: * Copyright (C) 2002 JAFFA Development Group
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: *
021: * Redistribution and use of this software and associated documentation ("Software"),
022: * with or without modification, are permitted provided that the following conditions are met:
023: * 1. Redistributions of source code must retain copyright statements and notices.
024: * Redistributions must also contain a copy of this document.
025: * 2. Redistributions in binary form must reproduce the above copyright notice,
026: * this list of conditions and the following disclaimer in the documentation
027: * and/or other materials provided with the distribution.
028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
029: * this Software without prior written permission. For written permission,
030: * please contact mail to: jaffagroup@yahoo.com.
031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
032: * appear in their names without prior written permission.
033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
034: *
035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
046: * SUCH DAMAGE.
047: * ====================================================================
048: */
049:
050: /*
051: * DomainDAO.java
052: *
053: * Created on February 12, 2004, 11:00 AM
054: */
055:
056: package org.jaffa.beans.moulding.data.domain;
057:
058: import java.util.HashMap;
059: import java.util.List;
060: import java.util.Map;
061: import org.apache.log4j.Logger;
062: import org.jaffa.beans.moulding.mapping.BeanMoulder;
063: import org.jaffa.exceptions.ApplicationExceptions;
064: import org.jaffa.exceptions.FrameworkException;
065:
066: /** This is the base class for all Domain Data Access Objects.
067: * <p>
068: * It provides a default implementation of the PropertyChange function from
069: * the Java Bean specification, which keeps track of which properties in
070: * the Bean have been modified since construction, or since the last <code>
071: * clearChanges()</code>
072: * <p>
073: * It therefore provides (for the bean moulding framework) a way to infer if
074: * a value has been passed, which can be used to see if a field value should
075: * be moulded from the source to target bean.
076: *
077: * @author PaulE
078: * @version 1.0
079: */
080: public abstract class DomainDAO {
081:
082: private static Logger log = Logger.getLogger(DomainDAO.class);
083:
084: private Map changes = new HashMap();
085:
086: /** Utility field used by bound properties. */
087: protected java.beans.PropertyChangeSupport propertyChangeSupport = new java.beans.PropertyChangeSupport(
088: this );
089:
090: /** Creates a new instance of DAO */
091: public DomainDAO() {
092: //log.debug("Create Change Listener");
093: addPropertyChangeListener(new java.beans.PropertyChangeListener() {
094: public void propertyChange(
095: java.beans.PropertyChangeEvent evt) {
096: //log.debug("Listener Invoked on "+evt.getPropertyName());
097: //if(!(evt.getOldValue()==null && evt.getNewValue()==null)) {
098: valueChanged(evt.getPropertyName(), evt.getOldValue());
099: log.debug("Field '" + evt.getPropertyName()
100: + "' updated from '" + evt.getOldValue()
101: + "' to '" + evt.getNewValue() + "'");
102: //}
103: /* else
104: log.debug("IGNORE Field '"+evt.getPropertyName()+"' updated from '"+evt.getOldValue()+"' to '"+evt.getNewValue()+"'");
105: */
106: }
107: });
108: }
109:
110: /** Adds a PropertyChangeListener to the listener list.
111: * @param l The listener to add.
112: */
113: public final void addPropertyChangeListener(
114: java.beans.PropertyChangeListener l) {
115: propertyChangeSupport.addPropertyChangeListener(l);
116: }
117:
118: /** Removes a PropertyChangeListener from the listener list.
119: * @param l The listener to remove.
120: *
121: */
122: public final void removePropertyChangeListener(
123: java.beans.PropertyChangeListener l) {
124: propertyChangeSupport.removePropertyChangeListener(l);
125: }
126:
127: /**
128: * Clear all the changes on this bean. Will cause all future calls to
129: * {@link #hasChanged(String)} to return false
130: */
131: public void clearChanges() {
132: changes.clear();
133: }
134:
135: /**
136: * Has the specified bean property been changed since the bean was
137: * created or last cleared
138: * @param property Name of bean property to check
139: * @return true if the property has been modified
140: */
141: public boolean hasChanged(String property) {
142: return changes.containsKey(property);
143: }
144:
145: /**
146: * Get the original value for this field, throw an error if this field has no
147: * changed, so you should consider first checking with the {@link #hasChanged(String)}
148: * method
149: * @param property Name of bean property to check
150: * @throws NoSuchFieldException Throw if the property has not been changed, or does not exist.
151: * @return The object representing the original values. Primitives are return as their
152: * Object counterparts.
153: */
154: public Object getOriginalValue(String property)
155: throws NoSuchFieldException {
156: if (changes.containsKey(property))
157: return changes.get(property);
158: else
159: throw new NoSuchFieldException(property);
160: }
161:
162: /**
163: * This is called prior to a domain DAO being used in a service. This is
164: * only called on the top level DAO of a DAO Graph, so this method should roll
165: * up lower level validations. The DAO is assumed to be valid if no exception
166: * is thrown.
167: *
168: * @throws ApplicationExceptions Contains an list of possible business logic
169: * exceptions that caused the validation to fail
170: * @throws FrameworkException Thrown if there is an environment/runtime problem
171: * that prevented the validation from being performed.
172: */
173: public abstract void validate() throws ApplicationExceptions,
174: FrameworkException;
175:
176: /**
177: * Converts the current contents of the bean to a multi-line
178: * nested output string, listing all the bean's properties.
179: * <p>
180: * Property names that are suffixed with an asterisk (*) indicate
181: * that the value <CODE>hasChanged()</CODE>.
182: * @return test string listing the beans contents
183: */
184: public String toString() {
185: return BeanMoulder.printBean(this );
186: }
187:
188: /**
189: * Converts the current contents of the bean to a multi-line
190: * nested output string, listing all the bean's properties.
191: * <p>
192: * Property names that are suffixed with an asterisk (*) indicate
193: * that the value <CODE>hasChanged()</CODE>.
194: * @return test string listing the beans contents
195: */
196: public String toString(List objectStack) {
197: return BeanMoulder.printBean(this , objectStack);
198: }
199:
200: private void valueChanged(String property, Object value) {
201: if (!changes.containsKey(property))
202: changes.put(property, value);
203: }
204:
205: }
|