001/* 002 * (C) Copyright 2006-2013 Nuxeo SA (http://nuxeo.com/) and others. 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 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.ecm.core.event.impl; 023 024import java.util.ArrayList; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029 030import org.nuxeo.ecm.core.event.EventListener; 031import org.nuxeo.ecm.core.event.PostCommitEventListener; 032 033/** 034 * Utility class used to manage event listeners descriptors. 035 * 036 * @author Thierry Delprat 037 */ 038public class EventListenerList { 039 040 protected final List<EventListenerDescriptor> inlineListenersDescriptors = new ArrayList<EventListenerDescriptor>(); 041 042 protected final List<EventListenerDescriptor> syncPostCommitListenersDescriptors = new ArrayList<EventListenerDescriptor>(); 043 044 protected final List<EventListenerDescriptor> asyncPostCommitListenersDescriptors = new ArrayList<EventListenerDescriptor>(); 045 046 protected volatile List<EventListenerDescriptor> enabledInlineListenersDescriptors = null; 047 048 protected volatile List<EventListenerDescriptor> enabledSyncPostCommitListenersDescriptors = null; 049 050 protected volatile List<EventListenerDescriptor> enabledAsyncPostCommitListenersDescriptors = null; 051 052 protected final Map<String, EventListenerDescriptor> descriptors = new HashMap<String, EventListenerDescriptor>(); 053 054 protected synchronized void flushCache() { 055 enabledAsyncPostCommitListenersDescriptors = null; 056 enabledInlineListenersDescriptors = null; 057 enabledSyncPostCommitListenersDescriptors = null; 058 } 059 060 public void add(EventListenerDescriptor descriptor) { 061 062 flushCache(); 063 // merge if necessary 064 if (descriptors.containsKey(descriptor.getName())) { 065 descriptor = mergeDescriptor(descriptor); 066 } 067 068 // checkListener 069 descriptor.initListener(); 070 071 if (descriptor.isPostCommit) { 072 if (descriptor.getIsAsync()) { 073 asyncPostCommitListenersDescriptors.add(descriptor); 074 Collections.sort(asyncPostCommitListenersDescriptors, new EventListenerDescriptorComparator()); 075 } else { 076 syncPostCommitListenersDescriptors.add(descriptor); 077 Collections.sort(syncPostCommitListenersDescriptors, new EventListenerDescriptorComparator()); 078 } 079 080 } else { 081 inlineListenersDescriptors.add(descriptor); 082 Collections.sort(inlineListenersDescriptors, new EventListenerDescriptorComparator()); 083 } 084 085 descriptors.put(descriptor.getName(), descriptor); 086 } 087 088 protected EventListenerDescriptor mergeDescriptor(EventListenerDescriptor descriptor) { 089 EventListenerDescriptor existingDesc = getDescriptor(descriptor.getName()); 090 removeDescriptor(existingDesc); 091 existingDesc.merge(descriptor); 092 return existingDesc; 093 } 094 095 public void removeDescriptor(EventListenerDescriptor descriptor) { 096 flushCache(); 097 if (descriptors.containsKey(descriptor.getName())) { 098 if (descriptor.isPostCommit) { 099 if (descriptor.getIsAsync()) { 100 asyncPostCommitListenersDescriptors.remove(descriptor); 101 } else { 102 syncPostCommitListenersDescriptors.remove(descriptor); 103 } 104 } else { 105 inlineListenersDescriptors.remove(descriptor); 106 } 107 descriptors.remove(descriptor.getName()); 108 } 109 } 110 111 public EventListenerDescriptor getDescriptor(String listenerName) { 112 return descriptors.get(listenerName); 113 } 114 115 public List<EventListener> getInLineListeners() { 116 List<EventListener> listeners = new ArrayList<EventListener>(); 117 for (EventListenerDescriptor desc : getEnabledInlineListenersDescriptors()) { 118 listeners.add(desc.asEventListener()); 119 } 120 return listeners; 121 } 122 123 public List<PostCommitEventListener> getSyncPostCommitListeners() { 124 List<PostCommitEventListener> listeners = new ArrayList<PostCommitEventListener>(); 125 for (EventListenerDescriptor desc : getEnabledSyncPostCommitListenersDescriptors()) { 126 listeners.add(desc.asPostCommitListener()); 127 } 128 return listeners; 129 } 130 131 public List<PostCommitEventListener> getAsyncPostCommitListeners() { 132 List<PostCommitEventListener> listeners = new ArrayList<PostCommitEventListener>(); 133 for (EventListenerDescriptor desc : getEnabledAsyncPostCommitListenersDescriptors()) { 134 listeners.add(desc.asPostCommitListener()); 135 } 136 return listeners; 137 } 138 139 public List<EventListenerDescriptor> getInlineListenersDescriptors() { 140 return inlineListenersDescriptors; 141 } 142 143 public List<EventListenerDescriptor> getSyncPostCommitListenersDescriptors() { 144 return syncPostCommitListenersDescriptors; 145 } 146 147 public List<EventListenerDescriptor> getAsyncPostCommitListenersDescriptors() { 148 return asyncPostCommitListenersDescriptors; 149 } 150 151 public synchronized void recomputeEnabledListeners() { 152 enabledAsyncPostCommitListenersDescriptors = new ArrayList<EventListenerDescriptor>(); 153 for (EventListenerDescriptor desc : asyncPostCommitListenersDescriptors) { 154 if (desc.isEnabled) { 155 enabledAsyncPostCommitListenersDescriptors.add(desc); 156 } 157 } 158 enabledSyncPostCommitListenersDescriptors = new ArrayList<EventListenerDescriptor>(); 159 for (EventListenerDescriptor desc : syncPostCommitListenersDescriptors) { 160 if (desc.isEnabled) { 161 enabledSyncPostCommitListenersDescriptors.add(desc); 162 } 163 } 164 enabledInlineListenersDescriptors = new ArrayList<EventListenerDescriptor>(); 165 for (EventListenerDescriptor desc : inlineListenersDescriptors) { 166 if (desc.isEnabled) { 167 enabledInlineListenersDescriptors.add(desc); 168 } 169 } 170 } 171 172 public List<EventListenerDescriptor> getEnabledInlineListenersDescriptors() { 173 if (enabledInlineListenersDescriptors == null) { 174 recomputeEnabledListeners(); 175 } 176 return new ArrayList<EventListenerDescriptor>(enabledInlineListenersDescriptors); 177 } 178 179 public List<EventListenerDescriptor> getEnabledSyncPostCommitListenersDescriptors() { 180 if (enabledSyncPostCommitListenersDescriptors == null) { 181 recomputeEnabledListeners(); 182 } 183 return new ArrayList<EventListenerDescriptor>(enabledSyncPostCommitListenersDescriptors); 184 } 185 186 public List<EventListenerDescriptor> getEnabledAsyncPostCommitListenersDescriptors() { 187 if (enabledAsyncPostCommitListenersDescriptors == null) { 188 recomputeEnabledListeners(); 189 } 190 return new ArrayList<EventListenerDescriptor>(enabledAsyncPostCommitListenersDescriptors); 191 } 192 193 public List<String> getListenerNames() { 194 return new ArrayList<String>(descriptors.keySet()); 195 } 196 197 public boolean hasListener(String name) { 198 return descriptors.containsKey(name); 199 } 200 201}