001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.platform.audit.service; 021 022import java.util.ArrayList; 023import java.util.HashMap; 024import java.util.HashSet; 025import java.util.List; 026import java.util.Map; 027import java.util.Set; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.nuxeo.ecm.platform.audit.api.DocumentHistoryReader; 032import org.nuxeo.ecm.platform.audit.api.document.DocumentHistoryReaderImpl; 033import org.nuxeo.ecm.platform.audit.service.extension.AdapterDescriptor; 034import org.nuxeo.ecm.platform.audit.service.extension.AuditBackendDescriptor; 035import org.nuxeo.ecm.platform.audit.service.extension.EventDescriptor; 036import org.nuxeo.ecm.platform.audit.service.extension.ExtendedInfoDescriptor; 037import org.nuxeo.runtime.model.ComponentContext; 038import org.nuxeo.runtime.model.ComponentInstance; 039import org.nuxeo.runtime.model.ComponentName; 040import org.nuxeo.runtime.model.DefaultComponent; 041 042/** 043 * Event service configuration. 044 * 045 * @author <a href="mailto:ja@nuxeo.com">Julien Anguenot</a> 046 */ 047public class NXAuditEventsService extends DefaultComponent { 048 049 public static final ComponentName NAME = new ComponentName( 050 "org.nuxeo.ecm.platform.audit.service.NXAuditEventsService"); 051 052 private static final String EVENT_EXT_POINT = "event"; 053 054 private static final String EXTENDED_INFO_EXT_POINT = "extendedInfo"; 055 056 private static final String ADAPTER_POINT = "adapter"; 057 058 /** 059 * If passed as true on the event properties, event not logged 060 * 061 * @since 5.7 062 */ 063 public static final String DISABLE_AUDIT_LOGGER = "disableAuditLogger"; 064 065 private static final String BACKEND_EXT_POINT = "backend"; 066 067 protected static final Log log = LogFactory.getLog(NXAuditEventsService.class); 068 069 protected final Set<ExtendedInfoDescriptor> extendedInfoDescriptors = new HashSet<ExtendedInfoDescriptor>(); 070 071 protected final Map<String, List<ExtendedInfoDescriptor>> eventExtendedInfoDescriptors = new HashMap<String, List<ExtendedInfoDescriptor>>(); 072 073 // the adapters that will injected in the EL context for extended 074 // information 075 protected final Set<AdapterDescriptor> documentAdapters = new HashSet<AdapterDescriptor>(); 076 077 protected final Set<String> eventNames = new HashSet<String>(); 078 079 protected AuditBackend backend; 080 081 @Override 082 public void applicationStarted(ComponentContext context) { 083 if (backend != null) { 084 backend.onApplicationStarted(); 085 } 086 } 087 088 @Override 089 public void deactivate(ComponentContext context) { 090 backend.deactivate(); 091 super.deactivate(context); 092 } 093 094 protected void doRegisterAdapter(AdapterDescriptor desc) { 095 if (log.isDebugEnabled()) { 096 log.debug("Registered adapter : " + desc.getName()); 097 } 098 documentAdapters.add(desc); 099 } 100 101 protected void doRegisterBackend(AuditBackendDescriptor desc) { 102 if (backend != null) { 103 backend.deactivate(); 104 } 105 backend = desc.newInstance(); 106 backend.activate(this); 107 } 108 109 protected void doRegisterEvent(EventDescriptor desc) { 110 String eventName = desc.getName(); 111 boolean eventEnabled = desc.getEnabled(); 112 if (eventEnabled) { 113 eventNames.add(eventName); 114 if (log.isDebugEnabled()) { 115 log.debug("Registered event: " + eventName); 116 } 117 for (ExtendedInfoDescriptor extInfoDesc : desc.getExtendedInfoDescriptors()) { 118 if (extInfoDesc.getEnabled()) { 119 if (eventExtendedInfoDescriptors.containsKey(eventName)) { 120 eventExtendedInfoDescriptors.get(eventName).add(extInfoDesc); 121 } else { 122 List<ExtendedInfoDescriptor> toBeAdded = new ArrayList<ExtendedInfoDescriptor>(); 123 toBeAdded.add(extInfoDesc); 124 eventExtendedInfoDescriptors.put(eventName, toBeAdded); 125 } 126 } else { 127 if (eventExtendedInfoDescriptors.containsKey(eventName)) { 128 eventExtendedInfoDescriptors.get(eventName).remove(extInfoDesc); 129 } 130 } 131 } 132 } else if (eventNames.contains(eventName) && !eventEnabled) { 133 doUnregisterEvent(desc); 134 } 135 } 136 137 protected void doRegisterExtendedInfo(ExtendedInfoDescriptor desc) { 138 if (log.isDebugEnabled()) { 139 log.debug("Registered extended info mapping : " + desc.getKey()); 140 } 141 extendedInfoDescriptors.add(desc); 142 } 143 144 protected void doUnregisterAdapter(AdapterDescriptor desc) { 145 // FIXME: this doesn't look right 146 documentAdapters.remove(desc.getName()); 147 if (log.isDebugEnabled()) { 148 log.debug("Unregistered adapter: " + desc.getName()); 149 } 150 } 151 152 protected void doUnregisterEvent(EventDescriptor desc) { 153 eventNames.remove(desc.getName()); 154 eventExtendedInfoDescriptors.remove(desc.getName()); 155 if (log.isDebugEnabled()) { 156 log.debug("Unregistered event: " + desc.getName()); 157 } 158 } 159 160 protected void doUnregisterExtendedInfo(ExtendedInfoDescriptor desc) { 161 // FIXME: this doesn't look right 162 extendedInfoDescriptors.remove(desc.getKey()); 163 if (log.isDebugEnabled()) { 164 log.debug("Unregistered extended info: " + desc.getKey()); 165 } 166 } 167 168 @Override 169 public <T> T getAdapter(Class<T> adapter) { 170 if (adapter.getCanonicalName().equals(DocumentHistoryReader.class.getCanonicalName())) { 171 return adapter.cast(new DocumentHistoryReaderImpl()); 172 } else { 173 if (backend != null) { 174 return adapter.cast(backend); 175 } else { 176 log.error("Can not provide service " + adapter.getCanonicalName() + " since backend is undefined"); 177 return null; 178 } 179 } 180 } 181 182 public Set<String> getAuditableEventNames() { 183 return eventNames; 184 } 185 186 public AuditBackend getBackend() { 187 return backend; 188 } 189 190 public Set<AdapterDescriptor> getDocumentAdapters() { 191 return documentAdapters; 192 } 193 194 /** 195 * @since 7.4 196 */ 197 public Map<String, List<ExtendedInfoDescriptor>> getEventExtendedInfoDescriptors() { 198 return eventExtendedInfoDescriptors; 199 } 200 201 public Set<ExtendedInfoDescriptor> getExtendedInfoDescriptors() { 202 return extendedInfoDescriptors; 203 } 204 205 @Override 206 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 207 if (extensionPoint.equals(EVENT_EXT_POINT)) { 208 doRegisterEvent((EventDescriptor) contribution); 209 } else if (extensionPoint.equals(EXTENDED_INFO_EXT_POINT)) { 210 doRegisterExtendedInfo((ExtendedInfoDescriptor) contribution); 211 } else if (extensionPoint.equals(ADAPTER_POINT)) { 212 doRegisterAdapter((AdapterDescriptor) contribution); 213 } else if (extensionPoint.equals(BACKEND_EXT_POINT)) { 214 doRegisterBackend((AuditBackendDescriptor) contribution); 215 } 216 } 217 218 @Override 219 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 220 if (extensionPoint.equals(EVENT_EXT_POINT)) { 221 doUnregisterEvent((EventDescriptor) contribution); 222 } else if (extensionPoint.equals(EXTENDED_INFO_EXT_POINT)) { 223 doUnregisterExtendedInfo((ExtendedInfoDescriptor) contribution); 224 } else if (extensionPoint.equals(ADAPTER_POINT)) { 225 doUnregisterAdapter((AdapterDescriptor) contribution); 226 } 227 } 228 229}