1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.ldap.server.normalization;
18
19
20 import java.util.Map;
21
22 import javax.naming.Name;
23 import javax.naming.NamingEnumeration;
24 import javax.naming.NamingException;
25 import javax.naming.directory.Attributes;
26 import javax.naming.directory.ModificationItem;
27 import javax.naming.directory.SearchControls;
28
29 import org.apache.ldap.common.filter.ExprNode;
30 import org.apache.ldap.common.filter.LeafNode;
31 import org.apache.ldap.common.filter.BranchNode;
32 import org.apache.ldap.common.name.DnParser;
33 import org.apache.ldap.common.name.NameComponentNormalizer;
34 import org.apache.ldap.common.schema.AttributeType;
35 import org.apache.ldap.common.util.EmptyEnumeration;
36 import org.apache.ldap.server.DirectoryServiceConfiguration;
37 import org.apache.ldap.server.configuration.InterceptorConfiguration;
38 import org.apache.ldap.server.interceptor.BaseInterceptor;
39 import org.apache.ldap.server.interceptor.NextInterceptor;
40 import org.apache.ldap.server.partition.DirectoryPartitionNexus;
41 import org.apache.ldap.server.schema.AttributeTypeRegistry;
42 import org.slf4j.LoggerFactory;
43 import org.slf4j.Logger;
44
45
46 /***
47 * A name normalization service. This service makes sure all relative and distinuished
48 * names are normalized before calls are made against the respective interface methods
49 * on {@link DirectoryPartitionNexus}.
50 *
51 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
52 * @version $Rev: 328545 $
53 */
54 public class NormalizationService extends BaseInterceptor
55 {
56 /*** logger used by this class */
57 private static final Logger log = LoggerFactory.getLogger( NormalizationService.class );
58
59 /*** the parser used for normalizing distinguished names */
60 private DnParser parser;
61 /*** a filter node value normalizer and undefined node remover */
62 private ValueNormalizingVisitor visitor;
63 /*** the attributeType registry used for normalization and determining if some filter nodes are undefined */
64 private AttributeTypeRegistry registry;
65
66
67 public void init( DirectoryServiceConfiguration factoryCfg, InterceptorConfiguration cfg ) throws NamingException
68 {
69 registry = factoryCfg.getGlobalRegistries().getAttributeTypeRegistry();
70 NameComponentNormalizer ncn = new PerComponentNormalizer();
71 parser = new DnParser( ncn );
72 visitor = new ValueNormalizingVisitor( ncn );
73 }
74
75
76 public void destroy() {}
77
78
79
80
81
82
83
84 public void add( NextInterceptor nextInterceptor, String upName, Name normName, Attributes attrs ) throws NamingException
85 {
86 normName = parser.parse( normName.toString() );
87 nextInterceptor.add( upName, normName, attrs );
88 }
89
90
91 public void delete( NextInterceptor nextInterceptor, Name name ) throws NamingException
92 {
93 name = parser.parse( name.toString() );
94 nextInterceptor.delete( name );
95 }
96
97
98 public void modify( NextInterceptor nextInterceptor, Name name, int modOp, Attributes attrs ) throws NamingException
99 {
100 name = parser.parse( name.toString() );
101 nextInterceptor.modify( name, modOp, attrs );
102 }
103
104
105 public void modify( NextInterceptor nextInterceptor, Name name, ModificationItem[] items ) throws NamingException
106 {
107 name = parser.parse( name.toString() );
108 nextInterceptor.modify( name, items );
109 }
110
111
112 public void modifyRn( NextInterceptor nextInterceptor, Name name, String newRn, boolean deleteOldRn ) throws NamingException
113 {
114 name = parser.parse( name.toString() );
115 nextInterceptor.modifyRn( name, newRn, deleteOldRn );
116 }
117
118
119 public void move( NextInterceptor nextInterceptor, Name name, Name newParentName ) throws NamingException
120 {
121 name = parser.parse( name.toString() );
122 newParentName = parser.parse( newParentName.toString() );
123 nextInterceptor.move( name, newParentName );
124 }
125
126
127 public void move( NextInterceptor nextInterceptor, Name name, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException
128 {
129 name = parser.parse( name.toString() );
130 newParentName = parser.parse( newParentName.toString() );
131 nextInterceptor.move( name, newParentName, newRn, deleteOldRn );
132 }
133
134
135 public NamingEnumeration search( NextInterceptor nextInterceptor,
136 Name base, Map env, ExprNode filter,
137 SearchControls searchCtls ) throws NamingException
138 {
139 base = parser.parse( base.toString() );
140
141 if ( filter.isLeaf() )
142 {
143 LeafNode ln = ( LeafNode ) filter;
144 if ( ! registry.hasAttributeType( ln.getAttribute() ) )
145 {
146 StringBuffer buf = new StringBuffer();
147 buf.append( "undefined filter based on undefined attributeType '" );
148 buf.append( ln.getAttribute() );
149 buf.append( "' not evaluted at all. Returning empty enumeration." );
150 log.warn( buf.toString() );
151 return new EmptyEnumeration();
152 }
153 }
154
155 filter.accept( visitor );
156
157
158 if ( ! filter.isLeaf() )
159 {
160 BranchNode child = ( BranchNode ) filter;
161
162
163 if ( child.getChildren().size() == 0 )
164 {
165 log.warn( "Undefined branchnode filter without child nodes not evaluted at all. Returning empty enumeration." );
166 return new EmptyEnumeration();
167 }
168
169
170 if ( child.getChildren().size() == 1 && child.getOperator() != BranchNode.NOT )
171 {
172 filter = child.getChild();
173 }
174 }
175 return nextInterceptor.search( base, env, filter, searchCtls );
176 }
177
178
179 public boolean hasEntry( NextInterceptor nextInterceptor, Name name ) throws NamingException
180 {
181 name = parser.parse( name.toString() );
182 return nextInterceptor.hasEntry( name );
183 }
184
185
186 public boolean isSuffix( NextInterceptor nextInterceptor, Name name ) throws NamingException
187 {
188 name = parser.parse( name.toString() );
189 return nextInterceptor.isSuffix( name );
190 }
191
192
193 public NamingEnumeration list( NextInterceptor nextInterceptor, Name base ) throws NamingException
194 {
195 base = parser.parse( base.toString() );
196 return nextInterceptor.list( base );
197 }
198
199
200 public Attributes lookup( NextInterceptor nextInterceptor, Name name ) throws NamingException
201 {
202 name = parser.parse( name.toString() );
203 return nextInterceptor.lookup( name );
204 }
205
206
207 public Attributes lookup( NextInterceptor nextInterceptor, Name name, String[] attrIds ) throws NamingException
208 {
209 name = parser.parse( name.toString() );
210 return nextInterceptor.lookup( name, attrIds );
211 }
212
213
214
215
216
217
218
219 public Name getMatchedName( NextInterceptor nextInterceptor, Name name, boolean normalized ) throws NamingException
220 {
221 name = parser.parse( name.toString() );
222 return nextInterceptor.getMatchedName( name, normalized );
223 }
224
225
226 public Name getSuffix( NextInterceptor nextInterceptor, Name name, boolean normalized ) throws NamingException
227 {
228 name = parser.parse( name.toString() );
229 return nextInterceptor.getSuffix( name, normalized );
230 }
231
232
233 public boolean compare( NextInterceptor next, Name name, String oid, Object value ) throws NamingException
234 {
235 name = parser.parse( name.toString() );
236 return next.compare( name, oid, value );
237 }
238
239
240 /***
241 * A normalizer that normalizes each name component specifically according to
242 * the attribute type of the name component.
243 */
244 private class PerComponentNormalizer implements NameComponentNormalizer
245 {
246 public String normalizeByName( String name, String value ) throws NamingException
247 {
248 AttributeType type = registry.lookup( name );
249 return ( String ) type.getEquality().getNormalizer().normalize( value );
250 }
251
252
253 public String normalizeByOid( String oid, String value ) throws NamingException
254 {
255 AttributeType type = registry.lookup( oid );
256 return ( String ) type.getEquality().getNormalizer().normalize( value );
257 }
258
259
260 public boolean isDefined( String id )
261 {
262 return registry.hasAttributeType( id );
263 }
264 }
265 }