|
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: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.