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 }