|
Groovy example source code file (ObservableMap.java)
The Groovy ObservableMap.java source code
/*
* Copyright 2003-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package groovy.util;
import groovy.lang.Closure;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.*;
/**
* Map decorator that will trigger PropertyChangeEvents when a value changes.<br>
* An optional Closure may be specified and will work as a filter, if it returns
* true the property will trigger an event (if the value indeed changed),
* otherwise it won't. The Closure may receive 1 or 2 parameters, the single one
* being the value, the other one both the key and value, for example:
* <pre>
* // skip all properties whose value is a closure
* def map = new ObservableMap( {!(it instanceof Closure)} )
* <p/>
* // skip all properties whose name matches a regex
* def map = new ObservableMap( { name, value -> !(name =~ /[A-Z+]/) } )
* </pre>
* <p/>
* <p>The current implementation will trigger specialized events in the following scenarios,
* you need not register a different listener as those events extend from PropertyChangeEvent
* <ul>
* <li>ObservableMap.PropertyAddedEvent - a new property is added to the map
* <li>ObservableMap.PropertyRemovedEvent - a property is removed from the map
* <li>ObservableMap.PropertyUpdatedEvent - a property changes value (same as regular PropertyChangeEvent)
* <li>ObservableMap.PropertyClearedEvent - all properties have been removed from the map
* <li>ObservableMap.MultiPropertyEvent - triggered by calling map.putAll(), contains Added|Updated events
* </ul>
* <p/>
* <p>
* <strong>Bound properties
* <ul>
* <li>content - read-only.
* <li>size - read-only.
* </ul>
* </p>
*
* @author <a href="mailto:aalmiray@users.sourceforge.net">Andres Almiray
*/
public class ObservableMap implements Map {
private Map delegate;
private PropertyChangeSupport pcs;
private Closure test;
public static final String SIZE_PROPERTY = "size";
public static final String CONTENT_PROPERTY = "content";
public static final String CLEARED_PROPERTY = "cleared";
public ObservableMap() {
this(new LinkedHashMap(), null);
}
public ObservableMap(Closure test) {
this(new LinkedHashMap(), test);
}
public ObservableMap(Map delegate) {
this(delegate, null);
}
public ObservableMap(Map delegate, Closure test) {
this.delegate = delegate;
this.test = test;
pcs = new PropertyChangeSupport(this);
}
protected Map getMapDelegate() {
return delegate;
}
protected Closure getTest() {
return test;
}
public Map getContent() {
return Collections.unmodifiableMap(delegate);
}
protected void firePropertyClearedEvent(Map values) {
firePropertyEvent(new PropertyClearedEvent(this, values));
}
protected void firePropertyAddedEvent(Object key, Object value) {
firePropertyEvent(new PropertyAddedEvent(this, String.valueOf(key), value));
}
protected void firePropertyUpdatedEvent(Object key, Object oldValue, Object newValue) {
firePropertyEvent(new PropertyUpdatedEvent(this, String.valueOf(key), oldValue, newValue));
}
protected void fireMultiPropertyEvent(List<PropertyEvent> events) {
firePropertyEvent(new MultiPropertyEvent(this, (PropertyEvent[]) events.toArray(new PropertyEvent[events.size()])));
}
protected void fireMultiPropertyEvent(PropertyEvent[] events) {
firePropertyEvent(new MultiPropertyEvent(this, events));
}
protected void firePropertyRemovedEvent(Object key, Object value) {
firePropertyEvent(new PropertyRemovedEvent(this, String.valueOf(key), value));
}
protected void firePropertyEvent(PropertyEvent event) {
pcs.firePropertyChange(event);
}
protected void fireSizeChangedEvent(int oldValue, int newValue) {
pcs.firePropertyChange(new PropertyChangeEvent(this, SIZE_PROPERTY, oldValue, newValue));
}
// Map interface
public void clear() {
int oldSize = size();
Map values = new HashMap();
if (!delegate.isEmpty()) {
values.putAll(delegate);
}
delegate.clear();
firePropertyClearedEvent(values);
fireSizeChangedEvent(oldSize, size());
}
public boolean containsKey(Object key) {
return delegate.containsKey(key);
}
public boolean containsValue(Object value) {
return delegate.containsValue(value);
}
public Set entrySet() {
return delegate.entrySet();
}
public boolean equals(Object o) {
return delegate.equals(o);
}
public Object get(Object key) {
return delegate.get(key);
}
public int hashCode() {
return delegate.hashCode();
}
public boolean isEmpty() {
return delegate.isEmpty();
}
public Set keySet() {
return delegate.keySet();
}
public Object put(Object key, Object value) {
int oldSize = size();
Object oldValue = null;
boolean newKey = !delegate.containsKey(key);
if (test != null) {
oldValue = delegate.put(key, value);
Object result = null;
if (test.getMaximumNumberOfParameters() == 2) {
result = test.call(new Object[]{key, value});
} else {
result = test.call(value);
}
if (result != null && result instanceof Boolean && (Boolean) result) {
if (newKey) {
firePropertyAddedEvent(key, value);
fireSizeChangedEvent(oldSize, size());
} else if (oldValue != value) {
firePropertyUpdatedEvent(key, oldValue, value);
}
}
} else {
oldValue = delegate.put(key, value);
if (newKey) {
firePropertyAddedEvent(key, value);
fireSizeChangedEvent(oldSize, size());
} else if (oldValue != value) {
firePropertyUpdatedEvent(key, oldValue, value);
}
}
return oldValue;
}
public void putAll(Map map) {
int oldSize = size();
if (map != null) {
List<PropertyEvent> events = new ArrayList
Other Groovy examples (source code examples)Here is a short list of links related to this Groovy ObservableMap.java source code file: |
Other websites by Alvin Alexander:
Life/living in Alaska (OneMansAlaska.com)
How I Sold My Business (HowISoldMyBusiness.com)
Copyright 1998-2011 Alvin Alexander, devdaily.com
All Rights Reserved.