001 /* 002 * Copyright 2003-2004 The Apache Software Foundation 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.apache.commons.events.observable; 017 018 import org.apache.commons.collections.Buffer; 019 020 /** 021 * Decorates a <code>Buffer</code> implementation to observe modifications. 022 * <p> 023 * Each modifying method call made on this <code>Buffer</code> is forwarded to a 024 * {@link ModificationHandler}. 025 * The handler manages the event, notifying listeners and optionally vetoing changes. 026 * The default handler is 027 * {@link org.apache.commons.events.observable.standard.StandardModificationHandler StandardModificationHandler}. 028 * See this class for details of configuration available. 029 * 030 * @since Commons Events 1.0 031 * @version $Revision: 155443 $ $Date: 2005-02-26 13:19:51 +0000 (Sat, 26 Feb 2005) $ 032 * 033 * @author Stephen Colebourne 034 */ 035 public class ObservableBuffer extends ObservableCollection implements Buffer { 036 037 // Factories 038 //----------------------------------------------------------------------- 039 /** 040 * Factory method to create an observable buffer. 041 * <p> 042 * A {@link org.apache.commons.events.observable.standard.StandardModificationHandler} will be created. 043 * This can be accessed by {@link #getHandler()} to add listeners. 044 * 045 * @param buffer the buffer to decorate, must not be null 046 * @return the observed Buffer 047 * @throws IllegalArgumentException if the buffer is null 048 */ 049 public static ObservableBuffer decorate(final Buffer buffer) { 050 return new ObservableBuffer(buffer, null); 051 } 052 053 /** 054 * Factory method to create an observable buffer using a listener or a handler. 055 * <p> 056 * A lot of functionality is available through this method. 057 * If you don't need the extra functionality, simply implement the 058 * {@link org.apache.commons.events.observable.standard.StandardModificationListener} 059 * interface and pass it in as the second parameter. 060 * <p> 061 * Internally, an <code>ObservableBuffer</code> relies on a {@link ModificationHandler}. 062 * The handler receives all the events and processes them, typically by 063 * calling listeners. Different handler implementations can be plugged in 064 * to provide a flexible event system. 065 * <p> 066 * The handler implementation is determined by the listener parameter via 067 * the registered factories. The listener may be a manually configured 068 * <code>ModificationHandler</code> instance. 069 * <p> 070 * The listener is defined as an Object for maximum flexibility. 071 * It does not have to be a listener in the classic JavaBean sense. 072 * It is entirely up to the factory and handler as to how the parameter 073 * is interpretted. An IllegalArgumentException is thrown if no suitable 074 * handler can be found for this listener. 075 * <p> 076 * A <code>null</code> listener will create a 077 * {@link org.apache.commons.events.observable.standard.StandardModificationHandler}. 078 * 079 * @param buffer the buffer to decorate, must not be null 080 * @param listener buffer listener, may be null 081 * @return the observed buffer 082 * @throws IllegalArgumentException if the buffer is null 083 * @throws IllegalArgumentException if there is no valid handler for the listener 084 */ 085 public static ObservableBuffer decorate( 086 final Buffer buffer, 087 final Object listener) { 088 089 if (buffer == null) { 090 throw new IllegalArgumentException("Buffer must not be null"); 091 } 092 return new ObservableBuffer(buffer, listener); 093 } 094 095 // Constructors 096 //----------------------------------------------------------------------- 097 /** 098 * Constructor that wraps (not copies). 099 * <p> 100 * The handler implementation is determined by the listener parameter via 101 * the registered factories. The listener may be a manually configured 102 * <code>ModificationHandler</code> instance. 103 * 104 * @param buffer the buffer to decorate, must not be null 105 * @param listener the listener, may be null 106 * @throws IllegalArgumentException if the buffer is null 107 */ 108 protected ObservableBuffer( 109 final Buffer buffer, 110 final Object listener) { 111 super(buffer, listener); 112 } 113 114 /** 115 * Typecast the collection to a Buffer. 116 * 117 * @return the wrapped collection as a Buffer 118 */ 119 private Buffer getBuffer() { 120 return (Buffer) getCollection(); 121 } 122 123 // Buffer API 124 //----------------------------------------------------------------------- 125 public Object get() { 126 return getBuffer().get(); 127 } 128 129 //----------------------------------------------------------------------- 130 public Object remove() { 131 Object result = null; 132 if (handler.preRemoveNext()) { 133 result = getBuffer().remove(); 134 handler.postRemoveNext(result); 135 } 136 return result; 137 } 138 139 }