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.api.entry.ClonedServerEntry;
33  import org.apache.directory.server.core.api.entry.ServerEntryUtils;
34  import org.apache.directory.server.core.api.event.DirectoryListener;
35  import org.apache.directory.server.core.api.interceptor.context.AddOperationContext;
36  import org.apache.directory.server.core.api.interceptor.context.DeleteOperationContext;
37  import org.apache.directory.server.core.api.interceptor.context.ModifyOperationContext;
38  import org.apache.directory.server.core.api.interceptor.context.MoveAndRenameOperationContext;
39  import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
40  import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
41  import org.apache.directory.server.i18n.I18n;
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   */
65  public class EventListenerAdapter implements DirectoryListener
66  {
67      private static final Logger LOG = LoggerFactory.getLogger( EventListenerAdapter.class );
68      private final NamingListener listener;
69      private final ServerLdapContext source;
70  
71  
72      public EventListenerAdapter( ServerLdapContext source, NamingListener listener )
73      {
74          this( source, listener, new SearchControls() );
75      }
76  
77  
78      public EventListenerAdapter( ServerLdapContext source, NamingListener listener, SearchControls controls )
79      {
80          this.source = source;
81          this.listener = listener;
82      }
83      
84      
85      @Override
86      public boolean isSynchronous()
87      {
88          return false; // always asynchronous
89      }
90  
91  
92      private void deliverNamingExceptionEvent( Exception e )
93      {
94          LOG.error( I18n.err( I18n.ERR_118 ), e );
95          NamingExceptionEvent evt = null;
96  
97          if ( e instanceof NamingException )
98          {
99              evt = new NamingExceptionEvent( source, ( NamingException ) e );
100         }
101         else
102         {
103             NamingException ne = new NamingException( I18n.err( I18n.ERR_119 ) );
104             ne.setRootCause( e );
105             evt = new NamingExceptionEvent( source, ne );
106         }
107 
108         listener.namingExceptionThrown( evt );
109     }
110 
111 
112     /* (non-Javadoc)
113      * @see org.apache.directory.server.core.event.DirectoryListener#entryAdded(org.apache.directory.server.core.interceptor.context.AddOperationContext)
114      */
115     public void entryAdded( AddOperationContext addContext )
116     {
117         try
118         {
119             Binding binding = new Binding( addContext.getDn().getName(),
120                 ServerEntryUtils.toBasicAttributes( addContext.getEntry() ), false );
121             NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_ADDED,
122                 binding, null, addContext );
123 
124             if ( listener instanceof NamespaceChangeListener )
125             {
126                 ( ( NamespaceChangeListener ) listener ).objectAdded( evt );
127             }
128         }
129         catch ( Exception e )
130         {
131             deliverNamingExceptionEvent( e );
132         }
133     }
134 
135 
136     /* (non-Javadoc)
137      * @see org.apache.directory.server.core.event.DirectoryListener#entryDeleted(org.apache.directory.server.core.interceptor.context.DeleteOperationContext)
138      */
139     public void entryDeleted( DeleteOperationContext deleteContext )
140     {
141         try
142         {
143             if ( listener instanceof NamespaceChangeListener )
144             {
145                 Binding binding = new Binding( deleteContext.getDn().getName(),
146                     ServerEntryUtils.toBasicAttributes( deleteContext.getEntry() ), false );
147                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_REMOVED, null,
148                     binding, deleteContext );
149                 ( ( NamespaceChangeListener ) listener ).objectAdded( evt );
150             }
151         }
152         catch ( Exception e )
153         {
154             deliverNamingExceptionEvent( e );
155         }
156     }
157 
158 
159     /* (non-Javadoc)
160      * @see org.apache.directory.server.core.event.DirectoryListener#entryModified(org.apache.directory.server.core.interceptor.context.ModifyOperationContext)
161      */
162     public void entryModified( ModifyOperationContext modifyContext )
163     {
164         try
165         {
166             Binding newBinding = new Binding( modifyContext.getDn().getName(),
167                 ServerEntryUtils.toBasicAttributes( modifyContext.getEntry() ), false );
168             Binding oldBinding = new Binding( modifyContext.getDn().getName(),
169                 ServerEntryUtils.toBasicAttributes( ( ( ClonedServerEntry ) modifyContext.getEntry() )
170                     .getOriginalEntry() ), false );
171             NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_CHANGED,
172                 newBinding, oldBinding, modifyContext );
173 
174             if ( listener instanceof ObjectChangeListener )
175             {
176                 ( ( ObjectChangeListener ) listener ).objectChanged( evt );
177             }
178         }
179         catch ( Exception e )
180         {
181             deliverNamingExceptionEvent( e );
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 moveContext )
190     {
191         try
192         {
193             if ( listener instanceof NamespaceChangeListener )
194             {
195                 Binding newBinding = new Binding( moveContext.getDn().getName(),
196                     ServerEntryUtils.toBasicAttributes( moveContext.getEntry() ), false );
197                 Binding oldBinding = new Binding( moveContext.getDn().getName(),
198                     ServerEntryUtils.toBasicAttributes( ( ( ClonedServerEntry ) moveContext.getEntry() )
199                         .getOriginalEntry() ), false );
200                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED,
201                     newBinding, oldBinding, moveContext );
202                 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt );
203             }
204         }
205         catch ( Exception e )
206         {
207             deliverNamingExceptionEvent( e );
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 moveAndRenameContext )
216     {
217         try
218         {
219             if ( listener instanceof NamespaceChangeListener )
220             {
221                 Binding newBinding = new Binding( moveAndRenameContext.getDn().getName(),
222                     ServerEntryUtils.toBasicAttributes( moveAndRenameContext.getEntry() ), false );
223                 Binding oldBinding = new Binding( moveAndRenameContext.getDn().getName(),
224                     ServerEntryUtils.toBasicAttributes( ( ( ClonedServerEntry ) moveAndRenameContext.getEntry() )
225                         .getOriginalEntry() ), false );
226                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED,
227                     newBinding, oldBinding, moveAndRenameContext );
228                 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt );
229             }
230         }
231         catch ( Exception e )
232         {
233             deliverNamingExceptionEvent( e );
234         }
235     }
236 
237 
238     /* (non-Javadoc)
239      * @see org.apache.directory.server.core.event.DirectoryListener#entryRenamed(org.apache.directory.server.core.interceptor.context.RenameOperationContext)
240      */
241     public void entryRenamed( RenameOperationContext renameContext )
242     {
243         try
244         {
245             if ( listener instanceof NamespaceChangeListener )
246             {
247                 Binding newBinding = new Binding( renameContext.getDn().getName(),
248                     ServerEntryUtils.toBasicAttributes( renameContext.getEntry() ), false );
249                 Binding oldBinding = new Binding( renameContext.getDn().getName(),
250                     ServerEntryUtils.toBasicAttributes( ( ( ClonedServerEntry ) renameContext.getEntry() )
251                         .getOriginalEntry() ), false );
252                 NamingEvent evt = new NamingEvent( source, NamingEvent.OBJECT_RENAMED,
253                     newBinding, oldBinding, null );
254                 ( ( NamespaceChangeListener ) listener ).objectRenamed( evt );
255             }
256         }
257         catch ( Exception e )
258         {
259             deliverNamingExceptionEvent( e );
260         }
261     }
262 }