001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.lenya.cms.observation;
019:
020: import java.util.HashMap;
021: import java.util.HashSet;
022: import java.util.Iterator;
023: import java.util.Map;
024: import java.util.Set;
025:
026: import org.apache.avalon.framework.logger.AbstractLogEnabled;
027: import org.apache.avalon.framework.thread.ThreadSafe;
028: import org.apache.lenya.cms.publication.Document;
029: import org.apache.lenya.cms.publication.DocumentIdentifier;
030: import org.apache.lenya.util.Assert;
031:
032: /**
033: * Observation manager. Works as an observation registry and sends the notifications.
034: */
035: public class ObservationManager extends AbstractLogEnabled implements
036: ObservationRegistry, ThreadSafe {
037:
038: private Map identifier2listeners = new HashMap();
039: private Set listeners = new HashSet();
040:
041: public synchronized void registerListener(
042: RepositoryListener listener, Document doc)
043: throws ObservationException {
044: Set listeners = getListeners(doc.getIdentifier());
045: if (listeners.contains(listener)) {
046: throw new ObservationException("The listener [" + listener
047: + "] is already registered for the document ["
048: + doc + "].");
049: }
050: listeners.add(listener);
051: }
052:
053: protected Set getListeners(DocumentIdentifier doc) {
054: Set listeners = (Set) this .identifier2listeners.get(doc);
055: if (listeners == null) {
056: listeners = new HashSet();
057: this .identifier2listeners.put(doc, listeners);
058: }
059: return listeners;
060: }
061:
062: public synchronized void registerListener(
063: RepositoryListener listener) throws ObservationException {
064: if (this .listeners.contains(listener)) {
065: throw new ObservationException("The listener [" + listener
066: + "] is already registered.");
067: }
068: this .listeners.add(listener);
069: }
070:
071: protected DocumentIdentifier getIdentifier(DocumentEvent event) {
072:
073: Assert.notNull("event", event);
074: DocumentIdentifier id = new DocumentIdentifier(event
075: .getPublicationId(), event.getArea(), event.getUuid(),
076: event.getLanguage());
077: return id;
078: }
079:
080: protected Set getAllListeners(DocumentIdentifier doc) {
081: Set allListeners = new HashSet();
082: synchronized (this ) {
083: allListeners.addAll(this .listeners);
084: allListeners.addAll(getListeners(doc));
085: }
086: return allListeners;
087: }
088:
089: protected void notify(Set listeners, RepositoryEvent event) {
090: for (Iterator i = listeners.iterator(); i.hasNext();) {
091: RepositoryListener listener = (RepositoryListener) i.next();
092: listener.eventFired(event);
093: }
094: }
095:
096: public void eventFired(RepositoryEvent event) {
097: Assert.notNull("event", event);
098: Set listeners;
099: if (event instanceof DocumentEvent) {
100: DocumentIdentifier id = getIdentifier((DocumentEvent) event);
101: listeners = getAllListeners(id);
102: } else {
103: listeners = this.listeners;
104: }
105: notify(listeners, event);
106: }
107:
108: }
|