001: /*
002: * Copyright (C) 2004 NNL Technology AB
003: * Visit www.infonode.net for information about InfoNode(R)
004: * products and how to contact NNL Technology AB.
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program 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
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
019: * MA 02111-1307, USA.
020: */
021:
022: // $Id: ConstChangeNotifyVectorMap.java,v 1.11 2005/12/04 13:46:04 jesper Exp $
023: package net.infonode.util.collection.notifymap;
024:
025: import net.infonode.util.ValueChange;
026: import net.infonode.util.collection.map.ConstVectorMap;
027: import net.infonode.util.collection.map.MapAdapter;
028: import net.infonode.util.collection.map.base.ConstMap;
029: import net.infonode.util.collection.map.base.ConstMapIterator;
030: import net.infonode.util.signal.Signal;
031: import net.infonode.util.signal.SignalListener;
032:
033: import java.util.ArrayList;
034:
035: public class ConstChangeNotifyVectorMap extends
036: AbstractConstChangeNotifyMap {
037: private ConstVectorMap vectorMap = new ConstVectorMap();
038: private ArrayList mapListeners;
039:
040: protected void firstListenerAdded() {
041: mapListeners = new ArrayList(vectorMap.getMapCount() + 2);
042:
043: for (int i = 0; i < vectorMap.getMapCount(); i++) {
044: addMapListener(i);
045: }
046: }
047:
048: protected void lastListenerRemoved() {
049: for (int i = vectorMap.getMapCount() - 1; i >= 0; i--) {
050: removeMapListener(i);
051: }
052:
053: mapListeners = null;
054: }
055:
056: private Object getValue(Object key, int fromIndex, int toIndex) {
057: for (int i = fromIndex; i < toIndex; i++) {
058: Object value = getMap(i).get(key);
059:
060: if (value != null)
061: return value;
062: }
063:
064: return null;
065: }
066:
067: public int getMapIndex(ConstMap map) {
068: return vectorMap.getMapIndex(map);
069: }
070:
071: public void addMap(ConstChangeNotifyMap map) {
072: addMap(vectorMap.getMapCount(), map);
073: }
074:
075: public void addMap(int index, ConstChangeNotifyMap map) {
076: vectorMap.addMap(index, map);
077:
078: if (getChangeSignalInternal().hasListeners()) {
079: addMapListener(index);
080: MapAdapter changes = new MapAdapter();
081:
082: for (ConstMapIterator iterator = map.constIterator(); iterator
083: .atEntry(); iterator.next()) {
084: Object value = getValue(iterator.getKey(), 0, index);
085:
086: if (value == null) {
087: Object mapValue = iterator.getValue();
088: changes.put(iterator.getKey(), new ValueChange(
089: getValue(iterator.getKey(), index + 1,
090: getMapCount()), mapValue));
091: }
092: }
093:
094: fireEntriesChanged(changes);
095: }
096: }
097:
098: private void addMapListener(int index) {
099: if (mapListeners == null)
100: mapListeners = new ArrayList(index + 2);
101:
102: final ConstChangeNotifyMap map = getMap(index);
103:
104: SignalListener mapListener = new SignalListener() {
105: public void signalEmitted(Signal signal, Object object) {
106: ConstMap changes = (ConstMap) object;
107: MapAdapter changes2 = new MapAdapter();
108: int index = getMapIndex(map);
109:
110: for (ConstMapIterator iterator = changes
111: .constIterator(); iterator.atEntry(); iterator
112: .next()) {
113: Object value = getValue(iterator.getKey(), 0, index);
114:
115: if (value == null) {
116: ValueChange vc = (ValueChange) iterator
117: .getValue();
118: changes2
119: .put(
120: iterator.getKey(),
121: vc.getOldValue() == null ? new ValueChange(
122: getValue(iterator
123: .getKey(),
124: index + 1,
125: getMapCount()),
126: vc.getNewValue())
127: : vc.getNewValue() == null ? new ValueChange(
128: vc
129: .getOldValue(),
130: getValue(
131: iterator
132: .getKey(),
133: index + 1,
134: getMapCount()))
135: : vc);
136: }
137: }
138:
139: fireEntriesChanged(changes2);
140: }
141: };
142:
143: mapListeners.add(index, mapListener);
144: map.getChangeSignal().add(mapListener);
145: }
146:
147: private void removeMapListener(int index) {
148: ConstChangeNotifyMap map = getMap(index);
149: map.getChangeSignal().remove(
150: (SignalListener) mapListeners.get(index));
151: mapListeners.remove(index);
152: }
153:
154: public int getMapCount() {
155: return vectorMap.getMapCount();
156: }
157:
158: public void removeMap(int index) {
159: if (getChangeSignalInternal().hasListeners())
160: removeMapListener(index);
161:
162: ConstMap map = vectorMap.removeMap(index);
163:
164: if (getChangeSignalInternal().hasListeners()) {
165: MapAdapter changes = new MapAdapter();
166:
167: for (ConstMapIterator iterator = map.constIterator(); iterator
168: .atEntry(); iterator.next()) {
169: Object value = getValue(iterator.getKey(), 0, index);
170:
171: if (value == null) {
172: Object mapValue = iterator.getValue();
173: changes.put(iterator.getKey(), new ValueChange(
174: mapValue, getValue(iterator.getKey(),
175: index, getMapCount())));
176: }
177: }
178:
179: fireEntriesChanged(changes);
180: }
181: }
182:
183: public Object get(Object key) {
184: return vectorMap.get(key);
185: }
186:
187: public boolean containsKey(Object key) {
188: return vectorMap.containsKey(key);
189: }
190:
191: public boolean containsValue(Object value) {
192: return vectorMap.containsValue(value);
193: }
194:
195: public boolean isEmpty() {
196: return vectorMap.isEmpty();
197: }
198:
199: public ConstChangeNotifyMap getMap(int index) {
200: return (ConstChangeNotifyMap) vectorMap.getMap(index);
201: }
202:
203: public ConstMapIterator constIterator() {
204: return vectorMap.constIterator();
205: }
206: }
|