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.normalization;
21  
22  
23  import org.apache.directory.server.core.DirectoryService;
24  import org.apache.directory.server.core.cursor.EmptyCursor;
25  import org.apache.directory.server.core.entry.ClonedServerEntry;
26  import org.apache.directory.server.core.entry.ServerEntry;
27  import org.apache.directory.server.core.filtering.EntryFilteringCursor;
28  import org.apache.directory.server.core.filtering.BaseEntryFilteringCursor;
29  import org.apache.directory.server.core.interceptor.BaseInterceptor;
30  import org.apache.directory.server.core.interceptor.NextInterceptor;
31  import org.apache.directory.server.core.interceptor.context.AddContextPartitionOperationContext;
32  import org.apache.directory.server.core.interceptor.context.AddOperationContext;
33  import org.apache.directory.server.core.interceptor.context.BindOperationContext;
34  import org.apache.directory.server.core.interceptor.context.CompareOperationContext;
35  import org.apache.directory.server.core.interceptor.context.DeleteOperationContext;
36  import org.apache.directory.server.core.interceptor.context.EntryOperationContext;
37  import org.apache.directory.server.core.interceptor.context.GetMatchedNameOperationContext;
38  import org.apache.directory.server.core.interceptor.context.GetSuffixOperationContext;
39  import org.apache.directory.server.core.interceptor.context.ListOperationContext;
40  import org.apache.directory.server.core.interceptor.context.LookupOperationContext;
41  import org.apache.directory.server.core.interceptor.context.ModifyOperationContext;
42  import org.apache.directory.server.core.interceptor.context.MoveAndRenameOperationContext;
43  import org.apache.directory.server.core.interceptor.context.MoveOperationContext;
44  import org.apache.directory.server.core.interceptor.context.RemoveContextPartitionOperationContext;
45  import org.apache.directory.server.core.interceptor.context.RenameOperationContext;
46  import org.apache.directory.server.core.interceptor.context.SearchOperationContext;
47  import org.apache.directory.server.core.partition.PartitionNexus;
48  import org.apache.directory.server.schema.ConcreteNameComponentNormalizer;
49  import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
50  import org.apache.directory.server.schema.registries.OidRegistry;
51  import org.apache.directory.shared.ldap.filter.ExprNode;
52  import org.apache.directory.shared.ldap.name.LdapDN;
53  import org.apache.directory.shared.ldap.name.NameComponentNormalizer;
54  import org.apache.directory.shared.ldap.schema.OidNormalizer;
55  import org.slf4j.Logger;
56  import org.slf4j.LoggerFactory;
57  
58  import java.util.Map;
59  
60  
61  /**
62   * A name normalization service.  This service makes sure all relative and distinuished
63   * names are normalized before calls are made against the respective interface methods
64   * on {@link PartitionNexus}.
65   *
66   * @org.apache.xbean.XBean
67   *
68   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
69   * @version $Rev: 674469 $
70   */
71  public class NormalizationInterceptor extends BaseInterceptor
72  {
73      /** logger used by this class */
74      private static final Logger LOG = LoggerFactory.getLogger( NormalizationInterceptor.class );
75  
76      /** a filter node value normalizer and undefined node remover */
77      private NormalizingVisitor normVisitor;
78  
79      /** The association between attributeTypes and their normalizers */
80      private Map<String, OidNormalizer> attrNormalizers; 
81      
82      /** The globa attributeType registry */
83      private AttributeTypeRegistry attributeRegistry;
84  
85      /**
86       * Initialize the registries, normalizers. 
87       */
88      public void init( DirectoryService directoryService ) throws Exception
89      {
90          OidRegistry oidRegistry = directoryService.getRegistries().getOidRegistry();
91          attributeRegistry = directoryService.getRegistries().getAttributeTypeRegistry();
92          NameComponentNormalizer ncn = new ConcreteNameComponentNormalizer( attributeRegistry, oidRegistry );
93          normVisitor = new NormalizingVisitor( ncn, directoryService.getRegistries() );
94          //expVisitor = new ExpandingVisitor( attributeRegistry );
95          attrNormalizers = attributeRegistry.getNormalizerMapping();
96      }
97  
98      /**
99       * The destroy method does nothing
100      */
101     public void destroy()
102     {
103     }
104 
105     // ------------------------------------------------------------------------
106     // Normalize all Name based arguments for ContextPartition interface operations
107     // ------------------------------------------------------------------------
108 
109     public void add( NextInterceptor nextInterceptor, AddOperationContext opContext ) throws Exception
110     {
111         opContext.getDn().normalize( attrNormalizers );
112         opContext.getEntry().getDn().normalize( attrNormalizers );
113         nextInterceptor.add( opContext );
114     }
115 
116 
117     public void delete( NextInterceptor nextInterceptor, DeleteOperationContext opContext ) throws Exception
118     {
119         opContext.getDn().normalize( attrNormalizers );
120         nextInterceptor.delete( opContext );
121     }
122 
123 
124     public void modify( NextInterceptor nextInterceptor, ModifyOperationContext opContext ) throws Exception
125     {
126         opContext.getDn().normalize( attrNormalizers );
127         nextInterceptor.modify( opContext );
128     }
129 
130 
131     public void rename( NextInterceptor nextInterceptor, RenameOperationContext opContext ) throws Exception
132     {
133         LdapDN rdn = new LdapDN();
134         rdn.add( opContext.getNewRdn() );
135         rdn.normalize( attrNormalizers );
136         opContext.setNewRdn( rdn.getRdn() );
137 
138         opContext.getDn().normalize( attrNormalizers );
139         nextInterceptor.rename( opContext );
140     }
141 
142 
143     public void move( NextInterceptor nextInterceptor, MoveOperationContext opContext ) throws Exception
144     {
145         opContext.getDn().normalize( attrNormalizers );
146         opContext.getParent().normalize( attrNormalizers);
147         nextInterceptor.move( opContext );
148     }
149 
150 
151     public void moveAndRename( NextInterceptor nextInterceptor, MoveAndRenameOperationContext opContext )
152         throws Exception
153     {
154         LdapDN rdn = new LdapDN();
155         rdn.add( opContext.getNewRdn() );
156         rdn.normalize( attrNormalizers );
157         opContext.setNewRdn( rdn.getRdn() );
158 
159         opContext.getDn().normalize( attrNormalizers );
160         opContext.getParent().normalize( attrNormalizers );
161         nextInterceptor.moveAndRename( opContext );
162     }
163 
164 
165     public EntryFilteringCursor search( NextInterceptor nextInterceptor, SearchOperationContext opContext ) throws Exception
166     {
167         opContext.getDn().normalize( attrNormalizers );
168 
169         ExprNode filter = opContext.getFilter();
170         ExprNode result = ( ExprNode ) filter.accept( normVisitor );
171 
172         if ( result == null )
173         {
174             LOG.warn( "undefined filter based on undefined attributeType not evaluted at all.  Returning empty enumeration." );
175             return new BaseEntryFilteringCursor( new EmptyCursor<ServerEntry>(), opContext );
176         }
177         else
178         {
179             opContext.setFilter( result );
180             
181             // TODO Normalize the returned Attributes, storing the UP attributes to format the returned values.
182             return nextInterceptor.search( opContext );
183         }
184     }
185 
186 
187     public boolean hasEntry( NextInterceptor nextInterceptor, EntryOperationContext opContext ) throws Exception
188     {
189         opContext.getDn().normalize( attrNormalizers );
190         return nextInterceptor.hasEntry( opContext );
191     }
192 
193 
194     public EntryFilteringCursor list( NextInterceptor nextInterceptor, ListOperationContext opContext ) throws Exception
195     {
196         opContext.getDn().normalize( attrNormalizers );
197         return nextInterceptor.list( opContext );
198     }
199 
200     
201     private String[] normalizeAttrsId( String[] attrIds ) throws Exception
202     {
203         if ( attrIds == null )
204         {
205             return attrIds;
206         }
207         
208         String[] normalizedAttrIds = new String[attrIds.length];
209         int pos = 0;
210         
211         for ( String id:attrIds )
212         {
213             String oid = attributeRegistry.lookup( id ).getOid();
214             normalizedAttrIds[pos++] = oid;
215         }
216         
217         return normalizedAttrIds;
218     }
219 
220     
221     public ClonedServerEntry lookup( NextInterceptor nextInterceptor, LookupOperationContext opContext ) throws Exception
222     {
223         opContext.getDn().normalize( attrNormalizers );
224         
225         if ( opContext.getAttrsId() != null )
226         {
227             // We have to normalize the requested IDs
228             opContext.setAttrsId( normalizeAttrsId( opContext.getAttrsIdArray() ) );
229         }
230         
231         return nextInterceptor.lookup( opContext );
232     }
233 
234 
235     // ------------------------------------------------------------------------
236     // Normalize all Name based arguments for other interface operations
237     // ------------------------------------------------------------------------
238 
239     
240     public LdapDN getMatchedName ( NextInterceptor nextInterceptor, GetMatchedNameOperationContext opContext ) throws Exception
241     {
242         opContext.getDn().normalize( attrNormalizers );
243         return nextInterceptor.getMatchedName( opContext );
244     }
245 
246 
247     public LdapDN getSuffix ( NextInterceptor nextInterceptor, GetSuffixOperationContext opContext ) throws Exception
248     {
249         opContext.getDn().normalize( attrNormalizers );
250         return nextInterceptor.getSuffix( opContext );
251     }
252 
253 
254     public boolean compare( NextInterceptor next, CompareOperationContext opContext ) throws Exception
255     {
256         opContext.getDn().normalize( attrNormalizers );
257         return next.compare( opContext );
258     }
259     
260     
261     public void bind( NextInterceptor next, BindOperationContext opContext )  throws Exception
262     {
263         opContext.getDn().normalize( attrNormalizers );
264         next.bind( opContext );
265     }
266 
267 
268     public void addContextPartition( NextInterceptor next, AddContextPartitionOperationContext opContext ) throws Exception
269     {
270         opContext.getDn().normalize( attrNormalizers );
271         next.addContextPartition( opContext );
272     }
273 
274 
275     public void removeContextPartition( NextInterceptor next, RemoveContextPartitionOperationContext opContext ) throws Exception
276     {
277         opContext.getDn().normalize( attrNormalizers );
278         next.removeContextPartition( opContext );
279     }
280 }