View Javadoc

1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.server.core.jndi;
21  
22  
23  import javax.naming.Binding;
24  import javax.naming.NamingException;
25  import javax.naming.directory.SearchControls;
26  import javax.naming.event.NamespaceChangeListener;
27  import javax.naming.event.NamingEvent;
28  import javax.naming.event.NamingExceptionEvent;
29  import javax.naming.event.NamingListener;
30  import javax.naming.event.ObjectChangeListener;
31  
32  import org.apache.directory.server.core.entry.ServerEntryUtils;
33  import org.apache.directory.server.core.event.DirectoryListener;
34  import org.apache.directory.server.core.interceptor.context.AddOperationContext;
35  import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
36  import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
37  import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
38  import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
39  import org.apache.directory.server.core.interceptor.context.OperationContext;
40  import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
41  
42  import org.slf4j.Logger;
43  import org.slf4j.LoggerFactory;
44  
45  
46  /**
47   * A DirectoryListener implementation which adapts call back to methods 
48   * notifying of changes to the DIT into NamingEvents for use with the ApacheDS
49   * DirectoryService JNDI provider.
50   * 
51   * TODO for the time being bindings in NamingEvents generated are not relative 
52   * to the source context which they should be.
53   * 
54   * TODO presume correctly manipulated entry values in opContext.getEntry() 
55   * objects to function properly - at this point this is not handled in the
56   * Interceptors and needs to be added for this adapter to populate the event
57   * bindings.
58   * 
59   * TODO - Should we factor in the attributes to be returned in bindings? 
60   * Perhaps this should be privided as search controls along with the info
61   * we need to handle aliases, and referals?
62   *
63   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
64   * @version $Rev$, $Date$
65   */
66  public class EventListenerAdapter implements DirectoryListener
67  {
68      private static final Logger LOG = LoggerFactory.getLogger( EventListenerAdapter.class );
69      private final NamingListener listener;
70      private final ServerLdapContext source;
71      
72      /** 
73       * TODO not utilized but should be to effect returns in bindings, alias 
74       * and referral handling
75       */
76      private final SearchControls controls;
77  
78      
79      public EventListenerAdapter( ServerLdapContext source, NamingListener listener )
80      {
81          this( source, listener, new SearchControls() );
82      }
83      
84      
85      public EventListenerAdapter( ServerLdapContext source, NamingListener listener, SearchControls controls )
86      {
87          this.source = source;
88          this.controls = controls;
89          this.listener = listener;
90      }
91      
92      
93      private void deliverNamingExceptionEvent( Exception e, OperationContext opContext )
94      {
95          LOG.error( "Error encountered while delivering notifications.", e );
96          NamingExceptionEvent evt = null;
97          
98          if ( e instanceof NamingException )
99          {
100             evt = new NamingExceptionEvent( source, ( NamingException ) e );
101         }
102         else
103         {
104             NamingException ne = new NamingException( "Encountered exception during event handling." );
105             ne.setRootCause( e );
106             evt = new NamingExceptionEvent( source, ne );
107         }
108         
109         listener.namingExceptionThrown( evt );
110     }
111     
112 
113     /* (non-Javadoc)
114      * @see org.apache.directory.server.core.event.DirectoryListener#entryAdded(org.apache.directory.server.core.interceptor.context.AddOperationContext)
115      */
116     public void entryAdded( AddOperationContext opContext )
117     {
118         try
119         {
120             Binding binding = new Binding( opContext.getDn().getUpName(), 
121                 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false );
122             NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_ADDED, 
123                 binding, null, opContext );
124 
125             if ( listener instanceof NamespaceChangeListener )
126             {
127                 ( ( NamespaceChangeListener ) listener ).objectAdded( evt );
128             }
129         }
130         catch ( Exception e )
131         {
132             deliverNamingExceptionEvent( e, opContext );
133         }
134     }
135 
136 
137     /* (non-Javadoc)
138      * @see org.apache.directory.server.core.event.DirectoryListener#entryDeleted(org.apache.directory.server.core.interceptor.context.DeleteOperationContext)
139      */
140     public void entryDeleted( DeleteOperationContext opContext )
141     {
142         try
143         {
144             if ( listener instanceof NamespaceChangeListener )
145             {
146                 Binding binding = new Binding( opContext.getDn().getUpName(), 
147                     ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false );
148                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_REMOVED, null, 
149                     binding, opContext );
150                 ( ( NamespaceChangeListener ) listener ).objectAdded( evt );
151             }
152         }
153         catch ( Exception e )
154         {
155             deliverNamingExceptionEvent( e, opContext );
156         }
157     }
158 
159 
160     /* (non-Javadoc)
161      * @see org.apache.directory.server.core.event.DirectoryListener#entryModified(org.apache.directory.server.core.interceptor.context.ModifyOperationContext)
162      */
163     public void entryModified( ModifyOperationContext opContext )
164     {
165         try
166         {
167             Binding newBinding = new Binding( opContext.getDn().getUpName(), 
168                 ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false );
169             Binding oldBinding = new Binding( opContext.getDn().getUpName(), 
170                 ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ),  false );
171             NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_CHANGED, 
172                 newBinding, oldBinding, opContext );
173 
174             if ( listener instanceof ObjectChangeListener )
175             {
176                 ( ( ObjectChangeListener ) listener ).objectChanged( evt );
177             }
178         }
179         catch ( Exception e )
180         {
181             deliverNamingExceptionEvent( e, opContext );
182         }
183     }
184 
185 
186     /* (non-Javadoc)
187      * @see org.apache.directory.server.core.event.DirectoryListener#entryMoved(org.apache.directory.server.core.interceptor.context.MoveOperationContext)
188      */
189     public void entryMoved( MoveOperationContext opContext )
190     {
191         try
192         {
193             if ( listener instanceof NamespaceChangeListener )
194             {
195                 Binding newBinding = new Binding( opContext.getDn().getUpName(), 
196                     ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false );
197                 Binding oldBinding = new Binding( opContext.getDn().getUpName(), 
198                     ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ), false );
199                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED, 
200                     newBinding, oldBinding, opContext );
201                 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt );
202             }
203         }
204         catch ( Exception e )
205         {
206             deliverNamingExceptionEvent( e, opContext );
207         }
208     }
209 
210 
211     /* (non-Javadoc)
212      * @see org.apache.directory.server.core.event.DirectoryListener#entryMovedAndRenamed(org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext)
213      */
214     public void entryMovedAndRenamed( MoveAndRenameOperationContext opContext )
215     {
216         try
217         {
218             if ( listener instanceof NamespaceChangeListener )
219             {
220                 Binding newBinding = new Binding( opContext.getDn().getUpName(), 
221                     ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false );
222                 Binding oldBinding = new Binding( opContext.getDn().getUpName(), 
223                     ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ), false );
224                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED, 
225                     newBinding, oldBinding, opContext );
226                 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt );
227             }
228         }
229         catch ( Exception e )
230         {
231             deliverNamingExceptionEvent( e, opContext );
232         }
233     }
234 
235 
236     /* (non-Javadoc)
237      * @see org.apache.directory.server.core.event.DirectoryListener#entryRenamed(org.apache.directory.server.core.interceptor.context.RenameOperationContext)
238      */
239     public void entryRenamed( RenameOperationContext opContext )
240     {
241         try
242         {
243             if ( listener instanceof NamespaceChangeListener )
244             {
245                 Binding newBinding = new Binding( opContext.getDn().getUpName(), 
246                     ServerEntryUtils.toBasicAttributes( opContext.getEntry() ), false );
247                 Binding oldBinding = new Binding( opContext.getDn().getUpName(), 
248                     ServerEntryUtils.toBasicAttributes( opContext.getEntry().getOriginalEntry() ), false );
249                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED, 
250                     newBinding, oldBinding, null );
251                 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt );
252             }
253         }
254         catch ( Exception e )
255         {
256             deliverNamingExceptionEvent( e, opContext );
257         }
258     }
259 }