001    /*
002     * Copyright 1999-2001,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    
017    package org.apache.commons.workflow.util;
018    
019    
020    import java.util.Map;
021    import org.apache.commons.workflow.Scope;
022    import org.apache.commons.workflow.ScopeEvent;
023    import org.apache.commons.workflow.ScopeListener;
024    
025    
026    /**
027     * <strong>ScopeSupport</strong> is a convenience class for managing the
028     * firing of <code>ScopeEvents</code> to registered
029     * <code>ScopeListeners</code>.
030     *
031     * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
032     * @author Craig R. McClanahan
033     */
034    
035    public class ScopeSupport {
036    
037    
038        // ----------------------------------------------------------- Constructors
039    
040    
041        /**
042         * Construct a new ScopeSupport object associated with the specified Scope.
043         *
044         * @param scope Scope for whom we will fire events
045         */
046        public ScopeSupport(Scope scope) {
047    
048            super();
049            this.scope = scope;
050    
051        }
052    
053    
054        // ----------------------------------------------------- Instance Variables
055    
056    
057        /**
058         * The set of registered <code>ScopeListener</code> event listeners.
059         */
060        protected ScopeListener listeners[] = new ScopeListener[0];
061    
062    
063        /**
064         * The <code>Scope</code> for whom we will fire events.
065         */
066        protected Scope scope = null;
067    
068    
069        // ------------------------------------------------- Event Listener Methods
070    
071    
072        /**
073         * Add a listener that is notified each time beans are added,
074         * replaced, or removed in this scope.
075         *
076         * @param listener The ScopeListener to be added
077         */
078        public void addScopeListener(ScopeListener listener) {
079    
080          synchronized (listeners) {
081              ScopeListener results[] =
082                new ScopeListener[listeners.length + 1];
083              System.arraycopy(listeners, 0, results, 0, listeners.length);
084              results[listeners.length] = listener;
085              listeners = results;
086          }
087    
088        }
089    
090    
091        /**
092         * Remove a listener that is notified each time beans are added,
093         * replaced, or removed in this scope.
094         *
095         * @param listener The ScopeListener to be removed
096         */
097        public void removeScopeListener(ScopeListener listener) {
098    
099            synchronized (listeners) {
100                int n = -1;
101                for (int i = 0; i < listeners.length; i++) {
102                    if (listeners[i] == listener) {
103                        n = i;
104                        break;
105                    }
106                }
107                if (n < 0)
108                    return;
109                ScopeListener results[] =
110                  new ScopeListener[listeners.length - 1];
111                int j = 0;
112                for (int i = 0; i < listeners.length; i++) {
113                    if (i != n)
114                        results[j++] = listeners[i];
115                }
116                listeners = results;
117            }
118    
119        }
120    
121    
122        // --------------------------------------------------- Event Firing Methods
123    
124    
125        /**
126         * Fire a <code>beanAdded()</code> event to all registered listeners.
127         *
128         * @param key Key of the bean that was added
129         * @param value Value of the bean that was added
130         */
131        public void fireBeanAdded(String key, Object value) {
132    
133            if (listeners.length == 0)
134                return;
135            ScopeEvent event = new ScopeEvent(scope, key, value);
136            ScopeListener interested[] = null;
137            synchronized (listeners) {
138                interested = (ScopeListener[]) listeners.clone();
139            }
140            for (int i = 0; i < interested.length; i++)
141                interested[i].beanAdded(event);
142    
143        }
144    
145    
146        /**
147         * Fire a <code>beanRemoved()</code> event to all registered listeners.
148         *
149         * @param key Key of the bean that was removed
150         * @param value Value of the bean that was removed
151         */
152        public void fireBeanRemoved(String key, Object value) {
153    
154            if (listeners.length == 0)
155                return;
156            ScopeEvent event = new ScopeEvent(scope, key, value);
157            ScopeListener interested[] = null;
158            synchronized (listeners) {
159                interested = (ScopeListener[]) listeners.clone();
160            }
161            for (int i = 0; i < interested.length; i++)
162                interested[i].beanRemoved(event);
163    
164        }
165    
166    
167        /**
168         * Fire a <code>beanReplaced()</code> event to all registered listeners.
169         *
170         * @param key Key of the bean that was replaced
171         * @param value Old value of the bean that was replaced
172         */
173        public void fireBeanReplaced(String key, Object value) {
174    
175            if (listeners.length == 0)
176                return;
177            ScopeEvent event = new ScopeEvent(scope, key, value);
178            ScopeListener interested[] = null;
179            synchronized (listeners) {
180                interested = (ScopeListener[]) listeners.clone();
181            }
182            for (int i = 0; i < interested.length; i++)
183                interested[i].beanReplaced(event);
184    
185        }
186    
187    
188        /**
189         * Fire a <code>scopeCleared()</code> event to all registered listeners.
190         */
191        public void fireScopeCleared() {
192    
193            if (listeners.length == 0)
194                return;
195            ScopeEvent event = new ScopeEvent(scope, null, null);
196            ScopeListener interested[] = null;
197            synchronized (listeners) {
198                interested = (ScopeListener[]) listeners.clone();
199            }
200            for (int i = 0; i < interested.length; i++)
201                interested[i].scopeCleared(event);
202    
203        }
204    
205    
206    }