001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 package org.apache.directory.server.core.jndi; 021 022 023 import javax.naming.Binding; 024 import javax.naming.NamingException; 025 import javax.naming.directory.SearchControls; 026 import javax.naming.event.NamespaceChangeListener; 027 import javax.naming.event.NamingEvent; 028 import javax.naming.event.NamingExceptionEvent; 029 import javax.naming.event.NamingListener; 030 import javax.naming.event.ObjectChangeListener; 031 032 import org.apache.directory.server.core.entry.ServerEntryUtils; 033 import org.apache.directory.server.core.event.DirectoryListener; 034 import org.apache.directory.server.core.interceptor.context.AddOperationContext; 035 import org.apache.directory.server.core.interceptor.context.DeleteOperationContext; 036 import org.apache.directory.server.core.interceptor.context.ModifyOperationContext; 037 import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext; 038 import org.apache.directory.server.core.interceptor.context.MoveOperationContext; 039 import org.apache.directory.server.core.interceptor.context.OperationContext; 040 import org.apache.directory.server.core.interceptor.context.RenameOperationContext; 041 import org.apache.directory.server.i18n.I18n; 042 043 import org.slf4j.Logger; 044 import org.slf4j.LoggerFactory; 045 046 047 /** 048 * A DirectoryListener implementation which adapts call back to methods 049 * notifying of changes to the DIT into NamingEvents for use with the ApacheDS 050 * DirectoryService JNDI provider. 051 * 052 * TODO for the time being bindings in NamingEvents generated are not relative 053 * to the source context which they should be. 054 * 055 * TODO presume correctly manipulated entry values in opContext.getEntry() 056 * objects to function properly - at this point this is not handled in the 057 * Interceptors and needs to be added for this adapter to populate the event 058 * bindings. 059 * 060 * TODO - Should we factor in the attributes to be returned in bindings? 061 * Perhaps this should be privided as search controls along with the info 062 * we need to handle aliases, and referals? 063 * 064 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 065 * @version $Rev$, $Date$ 066 */ 067 public class EventListenerAdapter implements DirectoryListener 068 { 069 private static final Logger LOG = LoggerFactory.getLogger( EventListenerAdapter.class ); 070 private final NamingListener listener; 071 private final ServerLdapContext source; 072 073 /** 074 * TODO not utilized but should be to effect returns in bindings, alias 075 * and referral handling 076 */ 077 private final SearchControls controls; 078 079 080 public EventListenerAdapter( ServerLdapContext source, NamingListener listener ) 081 { 082 this( source, listener, new SearchControls() ); 083 } 084 085 086 public EventListenerAdapter( ServerLdapContext source, NamingListener listener, SearchControls controls ) 087 { 088 this.source = source; 089 this.controls = controls; 090 this.listener = listener; 091 } 092 093 094 private void deliverNamingExceptionEvent( Exception e, OperationContext opContext ) 095 { 096 LOG.error( I18n.err( I18n.ERR_118 ), e ); 097 NamingExceptionEvent evt = null; 098 099 if ( e instanceof NamingException ) 100 { 101 evt = new NamingExceptionEvent( source, ( NamingException ) e ); 102 } 103 else 104 { 105 NamingException ne = new NamingException( I18n.err( I18n.ERR_119 ) ); 106 ne.setRootCause( e ); 107 evt = new NamingExceptionEvent( source, ne ); 108 } 109 110 listener.namingExceptionThrown( evt ); 111 } 112 113 114 /* (non-Javadoc) 115 * @see org.apache.directory.server.core.event.DirectoryListener#entryAdded(org.apache.directory.server.core.interceptor.context.AddOperationContext) 116 */ 117 public void entryAdded( AddOperationContext opContext ) 118 { 119 try 120 { 121 Binding binding = new Binding( opContext.getDn().getName(), 122 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false ); 123 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_ADDED, 124 binding, null, opContext ); 125 126 if ( listener instanceof NamespaceChangeListener ) 127 { 128 ( ( NamespaceChangeListener ) listener ).objectAdded( evt ); 129 } 130 } 131 catch ( Exception e ) 132 { 133 deliverNamingExceptionEvent( e, opContext ); 134 } 135 } 136 137 138 /* (non-Javadoc) 139 * @see org.apache.directory.server.core.event.DirectoryListener#entryDeleted(org.apache.directory.server.core.interceptor.context.DeleteOperationContext) 140 */ 141 public void entryDeleted( DeleteOperationContext opContext ) 142 { 143 try 144 { 145 if ( listener instanceof NamespaceChangeListener ) 146 { 147 Binding binding = new Binding( opContext.getDn().getName(), 148 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false ); 149 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_REMOVED, null, 150 binding, opContext ); 151 ( ( NamespaceChangeListener ) listener ).objectAdded( evt ); 152 } 153 } 154 catch ( Exception e ) 155 { 156 deliverNamingExceptionEvent( e, opContext ); 157 } 158 } 159 160 161 /* (non-Javadoc) 162 * @see org.apache.directory.server.core.event.DirectoryListener#entryModified(org.apache.directory.server.core.interceptor.context.ModifyOperationContext) 163 */ 164 public void entryModified( ModifyOperationContext opContext ) 165 { 166 try 167 { 168 Binding newBinding = new Binding( opContext.getDn().getName(), 169 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false ); 170 Binding oldBinding = new Binding( opContext.getDn().getName(), 171 ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ), false ); 172 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_CHANGED, 173 newBinding, oldBinding, opContext ); 174 175 if ( listener instanceof ObjectChangeListener ) 176 { 177 ( ( ObjectChangeListener ) listener ).objectChanged( evt ); 178 } 179 } 180 catch ( Exception e ) 181 { 182 deliverNamingExceptionEvent( e, opContext ); 183 } 184 } 185 186 187 /* (non-Javadoc) 188 * @see org.apache.directory.server.core.event.DirectoryListener#entryMoved(org.apache.directory.server.core.interceptor.context.MoveOperationContext) 189 */ 190 public void entryMoved( MoveOperationContext opContext ) 191 { 192 try 193 { 194 if ( listener instanceof NamespaceChangeListener ) 195 { 196 Binding newBinding = new Binding( opContext.getDn().getName(), 197 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false ); 198 Binding oldBinding = new Binding( opContext.getDn().getName(), 199 ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ), false ); 200 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED, 201 newBinding, oldBinding, opContext ); 202 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt ); 203 } 204 } 205 catch ( Exception e ) 206 { 207 deliverNamingExceptionEvent( e, opContext ); 208 } 209 } 210 211 212 /* (non-Javadoc) 213 * @see org.apache.directory.server.core.event.DirectoryListener#entryMovedAndRenamed(org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext) 214 */ 215 public void entryMovedAndRenamed( MoveAndRenameOperationContext opContext ) 216 { 217 try 218 { 219 if ( listener instanceof NamespaceChangeListener ) 220 { 221 Binding newBinding = new Binding( opContext.getDn().getName(), 222 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false ); 223 Binding oldBinding = new Binding( opContext.getDn().getName(), 224 ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ), false ); 225 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED, 226 newBinding, oldBinding, opContext ); 227 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt ); 228 } 229 } 230 catch ( Exception e ) 231 { 232 deliverNamingExceptionEvent( e, opContext ); 233 } 234 } 235 236 237 /* (non-Javadoc) 238 * @see org.apache.directory.server.core.event.DirectoryListener#entryRenamed(org.apache.directory.server.core.interceptor.context.RenameOperationContext) 239 */ 240 public void entryRenamed( RenameOperationContext opContext ) 241 { 242 try 243 { 244 if ( listener instanceof NamespaceChangeListener ) 245 { 246 Binding newBinding = new Binding( opContext.getDn().getName(), 247 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false ); 248 Binding oldBinding = new Binding( opContext.getDn().getName(), 249 ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ), false ); 250 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED, 251 newBinding, oldBinding, null ); 252 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt ); 253 } 254 } 255 catch ( Exception e ) 256 { 257 deliverNamingExceptionEvent( e, opContext ); 258 } 259 } 260 }