001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.event;
017:
018: import org.geotools.event.GTDelta;
019: import org.geotools.event.GTDeltaVisitor;
020: import java.util.Collections;
021: import java.util.Iterator;
022: import java.util.List;
023:
024: /**
025: * Describes the extent of changes.
026: *
027: * <p>
028: * The "delta" acts as a series of bread crumbs allowing you the listener to
029: * figure out what changed where.
030: * </p>
031: *
032: * @since 2.2.M3
033: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/event/GTDeltaImpl.java $
034: */
035: public class GTDeltaImpl implements GTDelta {
036: private String name;
037: private int position;
038: private Kind kind;
039: private Object value;
040: private Object oldValue;
041: private List children;
042:
043: /**
044: * Does the right thing, aka magic.
045: *
046: * <p>
047: * This constructor is provided to make things easier, if your experience
048: * is not magic please skip this and try the next constructor.
049: * </p>
050: *
051: * <p>
052: * Magic:
053: *
054: * <ul>
055: * <li>
056: * NO_CHANGE: before == null after == null
057: * </li>
058: * <li>
059: * NO_CHANGE: before == after
060: * </li>
061: * <li>
062: * REMOVED: before == obj after == null
063: * </li>
064: * <li>
065: * ADDED: before == null after == obj
066: * </li>
067: * <li>
068: * CHANGED: before != after
069: * </li>
070: * </ul>
071: * </p>
072: *
073: * @param notification
074: * @param before
075: * @param after
076: */
077: public GTDeltaImpl(GTNote notification, Object before, Object after) {
078: this (notification, magic(before, after), before, after);
079: }
080:
081: /**
082: * Create a delta, with no children.
083: *
084: * @param notification
085: * @param kind
086: * @param value
087: * @param oldValue
088: */
089: public GTDeltaImpl(GTNote notification, Kind kind, Object value,
090: Object oldValue) {
091: this (notification, kind, value, oldValue,
092: Collections.EMPTY_LIST);
093:
094: //this(name, NO_INDEX, kind, value, oldValue, Collections.EMPTY_LIST);
095: }
096:
097: /**
098: * Create a delta with with a list element child delta.
099: *
100: * <p>
101: * This can be used to communicate a batch of changes, such as adding and
102: * removing sections from a list, or the results of a transformation.
103: * </p>
104: *
105: * <p></p>
106: *
107: * @param notification
108: * @param kind
109: * @param value
110: * @param oldValue
111: * @param delta
112: */
113: public GTDeltaImpl(GTNote notification, Kind kind, Object value,
114: Object oldValue, GTDelta delta) {
115: this (notification, kind, value, oldValue, Collections
116: .singletonList(delta));
117: }
118:
119: /**
120: * Create a delta, completely specifying all values.
121: *
122: * @param notification
123: * @param kind
124: * @param value
125: * @param oldValue
126: * @param children
127: */
128: public GTDeltaImpl(GTNote notification, Kind kind, Object value,
129: Object oldValue, List children) {
130: this .name = notification.getNotificationName();
131: this .position = notification.getNotificationPosition();
132: this .kind = kind;
133: this .value = value;
134: this .oldValue = oldValue;
135: this .children = children;
136: }
137:
138: private static Kind magic(Object before, Object after) {
139: if ((before == null) && (after == null)) {
140: return Kind.NO_CHANGE;
141: }
142:
143: if (before == after) {
144: return Kind.NO_CHANGE;
145: }
146:
147: if ((before != null) && (after == null)) {
148: return Kind.REMOVED;
149: }
150:
151: if ((before == null) && (after != null)) {
152: return Kind.ADDED;
153: }
154:
155: if (before != after) {
156: return Kind.CHANGED;
157: }
158:
159: return Kind.CHANGED;
160: }
161:
162: public String getName() {
163: return name;
164: }
165:
166: public int getPosition() {
167: return position;
168: }
169:
170: public Kind getKind() {
171: return kind;
172: }
173:
174: public Object getValue() {
175: return value;
176: }
177:
178: public Object getOldValue() {
179: return oldValue;
180: }
181:
182: public List getChildren() {
183: return children;
184: }
185:
186: public void accept(GTDeltaVisitor visitor) {
187: boolean visitChildren = visitor.visit(this );
188:
189: if (!visitChildren) {
190: return;
191: }
192:
193: for (Iterator i = children.iterator(); i.hasNext();) {
194: GTDelta delta = (GTDelta) i.next();
195: delta.accept(visitor);
196: }
197: }
198: }
|