19
19
package com .redhat .lightblue .crud .ldap ;
20
20
21
21
import java .util .ArrayList ;
22
+ import java .util .Collection ;
22
23
import java .util .HashMap ;
23
24
import java .util .HashSet ;
24
25
import java .util .List ;
32
33
import com .redhat .lightblue .common .ldap .DBResolver ;
33
34
import com .redhat .lightblue .common .ldap .LdapConstant ;
34
35
import com .redhat .lightblue .common .ldap .LdapDataStore ;
36
+ import com .redhat .lightblue .common .ldap .LdapFieldNameTranslator ;
35
37
import com .redhat .lightblue .common .ldap .LightblueUtil ;
36
38
import com .redhat .lightblue .crud .CRUDController ;
37
39
import com .redhat .lightblue .crud .CRUDDeleteResponse ;
42
44
import com .redhat .lightblue .crud .CRUDUpdateResponse ;
43
45
import com .redhat .lightblue .crud .CrudConstants ;
44
46
import com .redhat .lightblue .crud .DocCtx ;
47
+ import com .redhat .lightblue .crud .ldap .model .TrivialLdapFieldNameTranslator ;
45
48
import com .redhat .lightblue .crud .ldap .translator .FilterTranslator ;
46
49
import com .redhat .lightblue .crud .ldap .translator .ResultTranslator ;
47
50
import com .redhat .lightblue .crud .ldap .translator .SortTranslator ;
@@ -104,9 +107,10 @@ public CRUDInsertionResponse insert(CRUDOperationContext ctx,
104
107
105
108
EntityMetadata md = ctx .getEntityMetadata (ctx .getEntityName ());
106
109
LdapDataStore store = getLdapDataStore (md );
110
+ LdapFieldNameTranslator property = getLdapFieldNameTranslator (md );
107
111
108
112
FieldAccessRoleEvaluator roles = new FieldAccessRoleEvaluator (md , ctx .getCallerRoles ());
109
- EntryBuilder entryBuilder = new EntryBuilder (md );
113
+ EntryBuilder entryBuilder = new EntryBuilder (md , property );
110
114
111
115
//Create Entry instances for each document.
112
116
List <com .unboundid .ldap .sdk .Entry > entries = new ArrayList <com .unboundid .ldap .sdk .Entry >();
@@ -123,9 +127,10 @@ public CRUDInsertionResponse insert(CRUDOperationContext ctx,
123
127
124
128
JsonNode rootNode = document .getRoot ();
125
129
126
- JsonNode uniqueNode = rootNode .get (store .getUniqueField ());
130
+ String uniqueFieldName = property .translateAttributeName (store .getUniqueAttribute ());
131
+ JsonNode uniqueNode = rootNode .get (uniqueFieldName );
127
132
if (uniqueNode == null ){
128
- throw new IllegalArgumentException (store . getUniqueField () + " is a required field" );
133
+ throw new IllegalArgumentException (uniqueFieldName + " is a required field" );
129
134
}
130
135
131
136
String dn = createDN (store , uniqueNode .asText ());
@@ -203,15 +208,17 @@ public CRUDFindResponse find(CRUDOperationContext ctx,
203
208
204
209
LDAPConnection connection = getNewLdapConnection (store );
205
210
211
+ LdapFieldNameTranslator property = getLdapFieldNameTranslator (md );
212
+
206
213
try {
207
214
//TODO: Support scopes other than SUB
208
215
SearchRequest request = new SearchRequest (
209
216
store .getBaseDN (),
210
217
SearchScope .SUB ,
211
- new FilterTranslator ().translate (query ),
212
- collectRequiredFields ( md , projection , query , sort ).toArray (new String [0 ]));
218
+ new FilterTranslator (property ).translate (query ),
219
+ translateFieldNames ( property , gatherRequiredFields ( md , projection , query , sort ) ).toArray (new String [0 ]));
213
220
if (sort != null ){
214
- request .addControl (new ServerSideSortRequestControl (false , new SortTranslator ().translate (sort )));
221
+ request .addControl (new ServerSideSortRequestControl (false , new SortTranslator (property ).translate (sort )));
215
222
}
216
223
if ((from != null ) && (from > 0 )){
217
224
int endPos = to .intValue () - from .intValue ();
@@ -221,11 +228,11 @@ public CRUDFindResponse find(CRUDOperationContext ctx,
221
228
SearchResult result = connection .search (request );
222
229
223
230
response .setSize (result .getEntryCount ());
224
- ResultTranslator resultTranslator = new ResultTranslator (ctx .getFactory ().getNodeFactory ());
231
+ ResultTranslator resultTranslator = new ResultTranslator (ctx .getFactory ().getNodeFactory (), md , property );
225
232
List <DocCtx > translatedDocs = new ArrayList <DocCtx >();
226
233
for (SearchResultEntry entry : result .getSearchEntries ()){
227
234
try {
228
- translatedDocs .add (resultTranslator .translate (entry , md ));
235
+ translatedDocs .add (resultTranslator .translate (entry ));
229
236
}
230
237
catch (Exception e ){
231
238
DocCtx erroredDoc = new DocCtx (null );
@@ -274,13 +281,18 @@ public void beforeUpdateEntityInfo(Metadata m, EntityInfo ei, boolean newEntity)
274
281
*/
275
282
@ Override
276
283
public void beforeCreateNewSchema (Metadata m , EntityMetadata md ) {
284
+ LdapFieldNameTranslator property = getLdapFieldNameTranslator (md );
285
+
277
286
Fields fields = md .getEntitySchema ().getFields ();
278
- if (!fields .has (LdapConstant .FIELD_DN )){
279
- fields .addNew (new SimpleField (LdapConstant .FIELD_DN , StringType .TYPE ));
287
+ String dnFieldName = property .translateAttributeName (LdapConstant .ATTRIBUTE_DN );
288
+ if (!fields .has (dnFieldName )){
289
+ fields .addNew (new SimpleField (dnFieldName , StringType .TYPE ));
280
290
}
281
- if (!fields .has (LdapConstant .FIELD_OBJECT_CLASS )){
282
- fields .addNew (new ArrayField (LdapConstant .FIELD_OBJECT_CLASS , new SimpleArrayElement (StringType .TYPE )));
283
- fields .addNew (new SimpleField (LightblueUtil .createArrayCountFieldName (LdapConstant .FIELD_OBJECT_CLASS ), IntegerType .TYPE ));
291
+
292
+ String objectClassFieldName = property .translateAttributeName (LdapConstant .ATTRIBUTE_OBJECT_CLASS );
293
+ if (!fields .has (objectClassFieldName )){
294
+ fields .addNew (new ArrayField (objectClassFieldName , new SimpleArrayElement (StringType .TYPE )));
295
+ fields .addNew (new SimpleField (LightblueUtil .createArrayCountFieldName (objectClassFieldName ), IntegerType .TYPE ));
284
296
}
285
297
}
286
298
@@ -312,6 +324,26 @@ private LdapDataStore getLdapDataStore(EntityMetadata md){
312
324
return (LdapDataStore ) store ;
313
325
}
314
326
327
+ /**
328
+ * Shortcut method to get and return the {@link LdapFieldNameTranslator} on the passed
329
+ * in {@link EntityMetadata}.
330
+ * @param md - {@link EntityMetadata}.
331
+ * @return {@link LdapFieldNameTranslator}
332
+ * @throws IllegalArgumentException if an invalid object is found.
333
+ */
334
+ private LdapFieldNameTranslator getLdapFieldNameTranslator (EntityMetadata md ){
335
+ Object o = md .getEntityInfo ().getProperties ().get (LdapConstant .BACKEND );
336
+
337
+ if (o == null ){
338
+ return new TrivialLdapFieldNameTranslator ();
339
+ }
340
+
341
+ if (!(o instanceof LdapFieldNameTranslator )){
342
+ throw new IllegalArgumentException ("Object of type " + o .getClass () + " is not supported." );
343
+ }
344
+ return (LdapFieldNameTranslator ) o ;
345
+ }
346
+
315
347
/**
316
348
* Creates and returns a unique DN.
317
349
* @param store - {@link LdapDataStore} to use as the BaseDN and field that
@@ -320,7 +352,7 @@ private LdapDataStore getLdapDataStore(EntityMetadata md){
320
352
* @return a string representation of the DN.
321
353
*/
322
354
private String createDN (LdapDataStore store , String uniqueValue ){
323
- return store .getUniqueField () + "=" + uniqueValue + "," + store .getBaseDN ();
355
+ return store .getUniqueAttribute () + "=" + uniqueValue + "," + store .getBaseDN ();
324
356
}
325
357
326
358
/**
@@ -332,7 +364,7 @@ private String createDN(LdapDataStore store, String uniqueValue){
332
364
* @param sort - (optional) {@link Sort}.
333
365
* @return list of field names.
334
366
*/
335
- private Set <String > collectRequiredFields (EntityMetadata md ,
367
+ private Set <String > gatherRequiredFields (EntityMetadata md ,
336
368
Projection projection , QueryExpression query , Sort sort ){
337
369
Set <String > fields = new HashSet <String >();
338
370
@@ -360,6 +392,22 @@ private Set<String> collectRequiredFields(EntityMetadata md,
360
392
return fields ;
361
393
}
362
394
395
+ /**
396
+ * Translates a <code>Collection</code> of fieldNames into a <code>Set</code> of
397
+ * attributeNames
398
+ * @param property - {@link LdapFieldNameTranslator}.
399
+ * @param fieldNames - <code>Collection</code> of fieldNames to translated
400
+ * @return <code>Set</code> of translated attributeNames.
401
+ */
402
+ private Set <String > translateFieldNames (LdapFieldNameTranslator property , Collection <String > fieldNames ){
403
+ Set <String > attributes = new HashSet <String >();
404
+ for (String fieldName : fieldNames ){
405
+ attributes .add (property .translateFieldName (fieldName ));
406
+ }
407
+
408
+ return attributes ;
409
+ }
410
+
363
411
/**
364
412
* For Insert and Save (and possibly Update), this method will project the results back
365
413
* onto the documents.
@@ -374,7 +422,9 @@ private void projectChanges(Projection projection, CRUDOperationContext ctx, Map
374
422
375
423
EntityMetadata md = ctx .getEntityMetadata (ctx .getEntityName ());
376
424
JsonNodeFactory factory = ctx .getFactory ().getNodeFactory ();
377
- Set <String > requiredFields = collectRequiredFields (md , projection , null , null );
425
+ LdapFieldNameTranslator property = getLdapFieldNameTranslator (md );
426
+
427
+ Set <String > requiredAttributeNames = translateFieldNames (property , gatherRequiredFields (md , projection , null , null ));
378
428
Projector projector = Projector .getInstance (
379
429
Projection .add (
380
430
projection ,
@@ -384,15 +434,17 @@ private void projectChanges(Projection projection, CRUDOperationContext ctx, Map
384
434
),
385
435
md );
386
436
437
+ String dnFieldName = property .translateAttributeName (LdapConstant .ATTRIBUTE_DN );
438
+
387
439
for (Entry <DocCtx , String > insertedDn : documentToDnMap .entrySet ()){
388
440
DocCtx document = insertedDn .getKey ();
389
441
String dn = insertedDn .getValue ();
390
442
DocCtx projectionResponseJson = null ;
391
443
392
444
// If only dn is in the projection, then no need to query LDAP.
393
- if ((requiredFields .size () == 1 ) && requiredFields .contains (LdapConstant .FIELD_DN )){
445
+ if ((requiredAttributeNames .size () == 1 ) && requiredAttributeNames .contains (LdapConstant .ATTRIBUTE_DN )){
394
446
ObjectNode node = factory .objectNode ();
395
- node .set (LdapConstant . FIELD_DN , StringType .TYPE .toJson (factory , dn ));
447
+ node .set (dnFieldName , StringType .TYPE .toJson (factory , dn ));
396
448
projectionResponseJson = new DocCtx (new JsonDoc (node ));
397
449
}
398
450
//TODO: else fetch entity from LDAP and project results.
0 commit comments