001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2013-2016 ForgeRock AS.
015 */
016package org.forgerock.opendj.adapter.server3x;
017
018import static com.forgerock.opendj.ldap.CoreMessages.*;
019import static com.forgerock.opendj.util.StaticUtils.*;
020
021import static org.forgerock.opendj.ldap.LdapException.*;
022import static org.opends.server.extensions.ExtensionsConstants.*;
023import static org.opends.server.util.CollectionUtils.*;
024
025import java.io.IOException;
026import java.util.ArrayList;
027import java.util.Collection;
028import java.util.List;
029
030import org.forgerock.i18n.LocalizableMessageBuilder;
031import org.forgerock.opendj.io.ASN1;
032import org.forgerock.opendj.io.ASN1Reader;
033import org.forgerock.opendj.io.ASN1Writer;
034import org.forgerock.opendj.ldap.Attribute;
035import org.forgerock.opendj.ldap.ByteString;
036import org.forgerock.opendj.ldap.ByteStringBuilder;
037import org.forgerock.opendj.ldap.DN;
038import org.forgerock.opendj.ldap.LdapException;
039import org.forgerock.opendj.ldap.LinkedAttribute;
040import org.forgerock.opendj.ldap.LinkedHashMapEntry;
041import org.forgerock.opendj.ldap.ResultCode;
042import org.forgerock.opendj.ldap.SearchScope;
043import org.forgerock.opendj.ldap.controls.Control;
044import org.forgerock.opendj.ldap.controls.GenericControl;
045import org.forgerock.opendj.ldap.responses.PasswordModifyExtendedResult;
046import org.forgerock.opendj.ldap.responses.Responses;
047import org.forgerock.opendj.ldap.responses.Result;
048import org.forgerock.opendj.ldap.responses.SearchResultEntry;
049import org.forgerock.opendj.server.config.meta.BackendVLVIndexCfgDefn;
050import org.forgerock.util.Reject;
051import org.opends.server.core.BindOperation;
052import org.opends.server.core.CompareOperation;
053import org.opends.server.core.DirectoryServer;
054import org.opends.server.core.ExtendedOperation;
055import org.opends.server.protocols.ldap.LDAPAttribute;
056import org.opends.server.protocols.ldap.LDAPControl;
057import org.opends.server.protocols.ldap.LDAPFilter;
058import org.opends.server.protocols.ldap.LDAPModification;
059import org.opends.server.types.AttributeBuilder;
060import org.opends.server.types.DirectoryException;
061import org.opends.server.types.LDAPException;
062import org.opends.server.types.ObjectClass;
063import org.opends.server.types.Operation;
064import org.opends.server.types.SearchFilter;
065import org.opends.server.util.ServerConstants;
066
067/** Common utility methods. */
068public final class Converters {
069
070    /** Prevent instantiation. */
071    private Converters() {
072        throw new AssertionError();
073    }
074
075    /**
076     * Converts from OpenDJ LDAP SDK {@link org.forgerock.opendj.ldap.Entry} to OpenDJ
077     * server {@link org.opends.server.types.Entry}.
078     *
079     * @param sdkEntry
080     *          SDK entry to convert
081     * @return the converted entry
082     */
083    public static org.opends.server.types.Entry to(
084            final org.forgerock.opendj.ldap.Entry sdkEntry) {
085        if (sdkEntry != null) {
086            org.opends.server.types.Entry entry =
087                new org.opends.server.types.Entry(sdkEntry.getName(), null, null, null);
088            List<ByteString> duplicateValues = new ArrayList<>();
089            for (org.opends.server.types.Attribute attribute : toAttributes(sdkEntry.getAllAttributes())) {
090                if (attribute.getAttributeDescription().getAttributeType().isObjectClass()) {
091                    for (ByteString attrName : attribute) {
092                        try {
093                            final String ocName = attrName.toString();
094                            ObjectClass oc = DirectoryServer.getObjectClass(ocName);
095                            if (oc == null) {
096                                oc = DirectoryServer.getDefaultObjectClass(ocName);
097                            }
098                            entry.addObjectClass(oc);
099                        } catch (DirectoryException e) {
100                            throw new IllegalStateException(e.getMessage(), e);
101                        }
102                    }
103                } else {
104                    entry.addAttribute(attribute, duplicateValues);
105                }
106            }
107            return entry;
108        }
109        return null;
110    }
111
112    /**
113     * Converts from OpenDJ LDAP SDK {@link org.forgerock.opendj.ldap.responses.SearchResultEntry} to OpenDJ
114     * server {@link org.opends.server.types.SearchResultEntry}.
115     *
116     * @param value
117     *          value to convert
118     * @return the converted value
119     */
120    public static org.opends.server.types.SearchResultEntry to(
121            final org.forgerock.opendj.ldap.responses.SearchResultEntry value) {
122        if (value != null) {
123            org.opends.server.types.Entry entry =
124                new org.opends.server.types.Entry(value.getName(), null, null, null);
125            org.opends.server.types.SearchResultEntry searchResultEntry =
126                new org.opends.server.types.SearchResultEntry(entry, to(value.getControls()));
127            List<ByteString> duplicateValues = new ArrayList<>();
128            for (org.opends.server.types.Attribute attribute : toAttributes(value.getAllAttributes())) {
129                searchResultEntry.addAttribute(attribute, duplicateValues);
130            }
131            return searchResultEntry;
132        }
133        return null;
134    }
135
136    /**
137     * Converts from OpenDJ LDAP SDK {@link org.forgerock.opendj.ldap.Filter} to
138     * OpenDJ server {@link org.opends.server.types.RawFilter}.
139     *
140     * @param filter
141     *          value to convert
142     * @return the converted value
143     */
144    public static org.opends.server.types.RawFilter to(final org.forgerock.opendj.ldap.Filter filter) {
145        try {
146            return LDAPFilter.decode(filter.toString());
147        } catch (LDAPException e) {
148            throw new IllegalStateException(e);
149        }
150    }
151
152    /**
153     * Converts from OpenDJ LDAP SDK {@link org.forgerock.opendj.ldap.Filter} to
154     * OpenDJ server {@link org.opends.server.types.RawFilter}.
155     *
156     * @param filter
157     *          value to convert
158     * @return the converted value
159     */
160    public static SearchFilter toSearchFilter(final org.forgerock.opendj.ldap.Filter filter) {
161        try {
162            return SearchFilter.createFilterFromString(filter.toString());
163        } catch (DirectoryException e) {
164            throw new IllegalStateException(e.getMessage(), e);
165        }
166    }
167
168    /**
169     * Converts from OpenDJ LDAP SDK
170     * {@link org.forgerock.opendj.ldap.responses.SearchResultReference} to OpenDJ
171     * server {@link org.opends.server.types.SearchResultReference}.
172     *
173     * @param searchResultReference
174     *          value to convert
175     * @return the converted value
176     */
177    public static org.opends.server.types.SearchResultReference to(
178            final org.forgerock.opendj.ldap.responses.SearchResultReference searchResultReference) {
179        return new org.opends.server.types.SearchResultReference(
180                searchResultReference.getURIs(), to(searchResultReference.getControls()));
181    }
182
183    /**
184     * Converts from OpenDJ LDAP SDK {@link Control} to OpenDJ server
185     * {@link org.opends.server.protocols.ldap.LDAPControl}.
186     *
187     * @param control
188     *          value to convert
189     * @return the converted value
190     */
191    public static org.opends.server.protocols.ldap.LDAPControl to(final Control control) {
192        return new LDAPControl(control.getOID(), control.isCritical(), control.getValue());
193    }
194
195    /**
196     * Converts from a <code>List</code> of OpenDJ LDAP SDK
197     * {@link org.forgerock.opendj.ldap.controls.Control} to a <code>List</code>
198     * of OpenDJ server {@link org.opends.server.types.Control}.
199     *
200     * @param listOfControl
201     *          value to convert
202     * @return the converted value
203     */
204    public static List<org.opends.server.types.Control> to(
205            final List<org.forgerock.opendj.ldap.controls.Control> listOfControl) {
206        List<org.opends.server.types.Control> toListOfControl = new ArrayList<>(listOfControl.size());
207        for (org.forgerock.opendj.ldap.controls.Control c : listOfControl) {
208            toListOfControl.add(to(c));
209        }
210        return toListOfControl;
211    }
212
213    /**
214     * Converts from OpenDJ LDAP SDK {@link org.forgerock.opendj.ldap.Attribute}
215     * to OpenDJ server {@link org.opends.server.types.RawAttribute}.
216     *
217     * @param attribute
218     *          value to convert
219     * @return the converted value
220     */
221    public static org.opends.server.types.RawAttribute to(
222            final org.forgerock.opendj.ldap.Attribute attribute) {
223        ArrayList<ByteString> listAttributeValues = newArrayList(attribute.toArray());
224        return new LDAPAttribute(attribute.getAttributeDescriptionAsString(), listAttributeValues);
225    }
226
227    /**
228     * Converts from an <code>Iterable</code> of OpenDJ LDAP SDK
229     * {@link org.forgerock.opendj.ldap.Attribute} to a <code>List</code> of
230     * OpenDJ server {@link org.opends.server.types.RawAttribute}.
231     *
232     * @param listOfAttributes
233     *          value to convert
234     * @return the converted value
235     */
236    public static List<org.opends.server.types.RawAttribute> to(
237            final Iterable<org.forgerock.opendj.ldap.Attribute> listOfAttributes) {
238        List<org.opends.server.types.RawAttribute> toListOfAttributes =
239                new ArrayList<>(((Collection<?>) listOfAttributes).size());
240        for (org.forgerock.opendj.ldap.Attribute a : listOfAttributes) {
241            toListOfAttributes.add(to(a));
242        }
243        return toListOfAttributes;
244    }
245
246    /**
247     * Converts from OpenDJ LDAP SDK
248     * {@link org.forgerock.opendj.ldap.Modification} to OpenDJ server
249     * {@link org.opends.server.types.RawModification}.
250     *
251     * @param modification
252     *          value to convert
253     * @return the converted value
254     */
255    public static org.opends.server.types.RawModification to(
256            final org.forgerock.opendj.ldap.Modification modification) {
257        return new LDAPModification(modification.getModificationType(), to(modification
258                .getAttribute()));
259    }
260
261    /**
262     * Converts from a <code>List</code> of OpenDJ LDAP SDK
263     * {@link org.forgerock.opendj.ldap.Modification} to a <code>List</code> of
264     * OpenDJ server {@link org.opends.server.types.RawModification}.
265     *
266     * @param listOfModifications
267     *          value to convert
268     * @return the converted value
269     */
270    public static List<org.opends.server.types.RawModification> toRawModifications(
271            final List<org.forgerock.opendj.ldap.Modification> listOfModifications) {
272        List<org.opends.server.types.RawModification> toListOfModifications =
273                new ArrayList<>(listOfModifications.size());
274        for (org.forgerock.opendj.ldap.Modification m : listOfModifications) {
275            toListOfModifications.add(to(m));
276        }
277        return toListOfModifications;
278    }
279
280    /**
281     * Converts from OpenDJ LDAP SDK {@link org.forgerock.opendj.ldap.Attribute}
282     * to OpenDJ server {@link org.opends.server.types.Attribute}.
283     *
284     * @param attribute
285     *          value to convert
286     * @return the converted value
287     */
288    public static org.opends.server.types.Attribute toAttribute(
289            final org.forgerock.opendj.ldap.Attribute attribute) {
290        final AttributeBuilder attrBuilder =
291            new AttributeBuilder(attribute.getAttributeDescriptionAsString());
292        for (ByteString b : attribute.toArray()) {
293            attrBuilder.add(b);
294        }
295        return attrBuilder.toAttribute();
296    }
297
298    /**
299     * Converts from an <code>Iterable</code> of OpenDJ LDAP SDK
300     * {@link org.forgerock.opendj.ldap.Attribute} to a <code>List</code> of
301     * OpenDJ server {@link org.opends.server.types.RawAttribute}.
302     *
303     * @param listOfAttributes
304     *          value to convert
305     * @return the converted value
306     */
307    public static List<org.opends.server.types.Attribute> toAttributes(
308            final Iterable<org.forgerock.opendj.ldap.Attribute> listOfAttributes) {
309        List<org.opends.server.types.Attribute> toListOfAttributes =
310                new ArrayList<>(((Collection<?>) listOfAttributes).size());
311        for (org.forgerock.opendj.ldap.Attribute a : listOfAttributes) {
312            toListOfAttributes.add(toAttribute(a));
313        }
314        return toListOfAttributes;
315    }
316
317    /**
318     * Converts from OpenDJ LDAP SDK
319     * {@link org.forgerock.opendj.ldap.Modification} to OpenDJ server
320     * {@link org.opends.server.types.Modification}.
321     *
322     * @param modification
323     *          value to convert
324     * @return the converted value
325     */
326    public static org.opends.server.types.Modification toModification(
327            final org.forgerock.opendj.ldap.Modification modification) {
328        return new org.opends.server.types.Modification(modification.getModificationType(),
329            toAttribute(modification.getAttribute()));
330    }
331
332    /**
333     * Converts from a <code>List</code> of OpenDJ LDAP SDK
334     * {@link org.forgerock.opendj.ldap.Modification} to a <code>List</code> of
335     * OpenDJ server {@link org.opends.server.types.Modification}.
336     *
337     * @param listOfModifications
338     *          value to convert
339     * @return the converted value
340     */
341    public static List<org.opends.server.types.Modification> toModifications(
342            final List<org.forgerock.opendj.ldap.Modification> listOfModifications) {
343        List<org.opends.server.types.Modification> toListOfModifications = new ArrayList<>(listOfModifications.size());
344        for (org.forgerock.opendj.ldap.Modification m : listOfModifications) {
345            toListOfModifications.add(toModification(m));
346        }
347        return toListOfModifications;
348    }
349
350    /**
351     * Converts from OpenDJ server
352     * {@link org.opends.server.protocols.ldap.LDAPControl} to OpenDJ LDAP SDK
353     * {@link Control}.
354     *
355     * @param ldapControl
356     *          value to convert
357     * @return the converted value
358     */
359    public static Control from(final org.opends.server.protocols.ldap.LDAPControl ldapControl) {
360        return GenericControl.newControl(ldapControl.getOID(), ldapControl.isCritical(),
361                ldapControl.getValue());
362    }
363
364    /**
365     * Converts from OpenDJ server {@link org.opends.server.types.Control} to
366     * OpenDJ LDAP SDK {@link Control}.
367     *
368     * @param control
369     *          value to convert
370     * @return the converted value
371     */
372    public static Control from(final org.opends.server.types.Control control) {
373        String oid = null;
374        boolean isCritical = false;
375        ByteString value = null;
376        // The server control doesn't have a method for extracting directly the value so, we need to ASN1 it.
377        ByteStringBuilder builder = new ByteStringBuilder();
378        final ASN1Writer writer = ASN1.getWriter(builder);
379        try {
380            control.write(writer);
381        } catch (IOException e) {
382            // Nothing to do.
383        }
384
385        final ByteString sdkByteString = builder.toByteString();
386        final org.forgerock.opendj.io.ASN1Reader sdkReaderASN1 =
387                org.forgerock.opendj.io.ASN1.getReader(sdkByteString.toByteArray());
388
389        // Reads the ASN1 SDK byte string.
390        try {
391            sdkReaderASN1.readStartSequence();
392            oid = sdkReaderASN1.readOctetStringAsString();
393            if (sdkReaderASN1.hasNextElement()
394                    && sdkReaderASN1.peekType() == ASN1.UNIVERSAL_BOOLEAN_TYPE) {
395                isCritical = sdkReaderASN1.readBoolean();
396            }
397            if (sdkReaderASN1.hasNextElement()
398                    && sdkReaderASN1.peekType() == ASN1.UNIVERSAL_OCTET_STRING_TYPE) {
399                value = sdkReaderASN1.readOctetString();
400            }
401            sdkReaderASN1.readEndSequence();
402        } catch (IOException e) {
403            // Nothing to do.
404        }
405        // Creates the control
406        return GenericControl.newControl(oid, isCritical, value);
407    }
408
409    /**
410     * Converts from a <code>List</code> of OpenDJ server
411     * {@link org.opends.server.types.Control} to a <code>List</code> of OpenDJ
412     * LDAP SDK {@link org.forgerock.opendj.ldap.controls.Control}.
413     *
414     * @param listOfControl
415     *          value to convert
416     * @return the converted value
417     */
418    public static List<org.forgerock.opendj.ldap.controls.Control> from(
419            final List<org.opends.server.types.Control> listOfControl) {
420        List<org.forgerock.opendj.ldap.controls.Control> fromListofControl = new ArrayList<>(listOfControl.size());
421        for (org.opends.server.types.Control c : listOfControl) {
422            fromListofControl.add(from(c));
423        }
424        return fromListofControl;
425    }
426
427    /**
428     * Converts from OpenDJ server
429     * {@link org.opends.server.types.SearchResultReference} to OpenDJ LDAP SDK
430     * {@link org.forgerock.opendj.ldap.responses.SearchResultReference}.
431     *
432     * @param srvResultReference
433     *          value to convert
434     * @return the converted value
435     */
436    public static org.forgerock.opendj.ldap.responses.SearchResultReference from(
437            final org.opends.server.types.SearchResultReference srvResultReference) {
438        return Responses.newSearchResultReference(srvResultReference.getReferralURLString());
439    }
440
441    /**
442     * Converts from OpenDJ server {@link org.opends.server.types.Attribute} to
443     * OpenDJ LDAP SDK {@link org.forgerock.opendj.ldap.Attribute}.
444     *
445     * @param attribute
446     *          value to convert
447     * @return the converted value
448     */
449    public static org.forgerock.opendj.ldap.Attribute from(
450            final org.opends.server.types.Attribute attribute) {
451        Attribute sdkAttribute = new LinkedAttribute(attribute.getNameWithOptions());
452        for (ByteString value : attribute) {
453            sdkAttribute.add(value);
454        }
455        return sdkAttribute;
456    }
457
458    /**
459     * Converts from an <code>Iterable</code> of OpenDJ server
460     * {@link org.opends.server.types.Attribute} to a <code>List</code> of OpenDJ
461     * LDAP SDK {@link org.forgerock.opendj.ldap.Attribute}.
462     *
463     * @param listOfAttributes
464     *          value to convert
465     * @return the converted value
466     */
467    public static List<org.forgerock.opendj.ldap.Attribute> from(
468            final Iterable<org.opends.server.types.Attribute> listOfAttributes) {
469        List<org.forgerock.opendj.ldap.Attribute> fromListofAttributes =
470                new ArrayList<>(((Collection<?>) listOfAttributes).size());
471        for (org.opends.server.types.Attribute a : listOfAttributes) {
472            fromListofAttributes.add(from(a));
473        }
474        return fromListofAttributes;
475    }
476
477    /**
478     * Converts from OpenDJ server
479     * {@link org.opends.server.types.SearchResultEntry} to OpenDJ LDAP SDK
480     * {@link org.forgerock.opendj.ldap.responses.SearchResultEntry}.
481     *
482     * @param srvResultEntry
483     *          value to convert
484     * @return the converted value
485     */
486    public static org.forgerock.opendj.ldap.responses.SearchResultEntry from(
487            final org.opends.server.types.SearchResultEntry srvResultEntry) {
488
489        final SearchResultEntry searchResultEntry =
490                Responses.newSearchResultEntry(srvResultEntry.getName().toString());
491        for (org.opends.server.types.Attribute a : srvResultEntry.getAttributes()) {
492            searchResultEntry.addAttribute(from(a));
493        }
494        for (org.opends.server.types.Control c : srvResultEntry.getControls()) {
495            searchResultEntry.addControl(from(c));
496        }
497        return searchResultEntry;
498    }
499
500    /**
501     * Converts from OpenDJ server
502     * {@link org.opends.server.types.Entry} to OpenDJ LDAP SDK
503     * {@link org.forgerock.opendj.ldap.Entry}.
504     *
505     * @param srvResultEntry
506     *          value to convert
507     * @return the converted value
508     */
509    public static org.forgerock.opendj.ldap.Entry from(
510        final org.opends.server.types.Entry srvResultEntry) {
511
512        final org.forgerock.opendj.ldap.Entry entry = new LinkedHashMapEntry(srvResultEntry.getName().toString());
513        for (org.opends.server.types.Attribute a : srvResultEntry.getAttributes()) {
514            entry.addAttribute(from(a));
515        }
516        return entry;
517    }
518
519    /**
520     * Converts from OpenDJ server
521     * {@link org.opends.server.admin.std.meta.VirtualAttributeCfgDefn.Scope} to OpenDJ LDAP SDK
522     * {@link org.forgerock.opendj.ldap.SearchScope}.
523     *
524     * @param srvScope
525     *          The server scope value.
526     * @return The SDK scope value.
527     */
528    public static SearchScope from(org.opends.server.admin.std.meta.VirtualAttributeCfgDefn.Scope srvScope) {
529        if (srvScope != null) {
530            switch (srvScope) {
531            case BASE_OBJECT:
532                return SearchScope.BASE_OBJECT;
533            case SINGLE_LEVEL:
534                return SearchScope.SINGLE_LEVEL;
535            case SUBORDINATE_SUBTREE:
536                return SearchScope.SUBORDINATES;
537            case WHOLE_SUBTREE:
538                return SearchScope.WHOLE_SUBTREE;
539            default:
540                return null;
541            }
542        }
543        return null;
544    }
545
546    /**
547     * Populates the result object with the operation details and return the
548     * result object if it was successful. Otherwise, it throws an
549     * {@link LdapException}.
550     *
551     * @param <T>
552     *          the type of the result object
553     * @param operation
554     *          used to populate the result
555     * @param result
556     *          the result object to populate from the Operation
557     * @return the result if successful, an {@link LdapException} is thrown
558     *         otherwise
559     * @throws LdapException
560     *           when an error occurs
561     */
562    public static <T extends Result> T getResponseResult(final Operation operation, final T result)
563            throws LdapException {
564        if (operation.getReferralURLs() != null) {
565            for (String ref : operation.getReferralURLs()) {
566                result.addReferralURI(ref);
567            }
568        }
569        if (operation.getResponseControls() != null) {
570            for (org.opends.server.types.Control c : operation.getResponseControls()) {
571                result.addControl(from(c));
572            }
573        }
574        final LocalizableMessageBuilder errorMsg = operation.getErrorMessage();
575        final DN matchedDN = operation.getMatchedDN();
576        result.setDiagnosticMessage(errorMsg != null ? errorMsg.toString() : null);
577        result.setMatchedDN(matchedDN != null ? matchedDN.toString() : null);
578        if (result.isSuccess()) {
579            return result;
580        } else {
581            throw newLdapException(result);
582        }
583    }
584
585    /**
586     * Converts the OpenDJ server {@link Operation} object into an OpenDJ LDAP SDK
587     * {@link Result} object.
588     *
589     * @param operation
590     *          value to convert
591     * @return the converted value
592     * @throws LdapException
593     *           when an error occurs
594     */
595    public static Result getResponseResult(final Operation operation) throws LdapException {
596        return getResponseResult(operation, newSDKResult(operation));
597    }
598
599    private static Result newSDKResult(final Operation operation) throws LdapException {
600        ResultCode rc = operation.getResultCode();
601        if (operation instanceof BindOperation) {
602            return Responses.newBindResult(rc);
603        } else if (operation instanceof CompareOperation) {
604            return Responses.newCompareResult(rc);
605        } else if (operation instanceof ExtendedOperation) {
606            ExtendedOperation extendedOperation = (ExtendedOperation) operation;
607            switch (extendedOperation.getRequestOID()) {
608            case ServerConstants.OID_PASSWORD_MODIFY_REQUEST:
609                PasswordModifyExtendedResult result = Responses.newPasswordModifyExtendedResult(rc);
610                ByteString generatedPwd = getGeneratedPassword(extendedOperation);
611                if (generatedPwd != null) {
612                    result.setGeneratedPassword(generatedPwd.toByteArray());
613                }
614                return result;
615
616            default:
617                return Responses.newGenericExtendedResult(rc);
618            }
619        }
620        return Responses.newResult(rc);
621    }
622
623    private static ByteString getGeneratedPassword(ExtendedOperation op) throws LdapException {
624        // FIXME this code is duplicated with code in the SDK
625        // see PasswordModifyExtendedRequestImpl#ResultDecoder#decodeExtendedResult()
626        ByteString responseValue = op.getResponseValue();
627        if (responseValue != null) {
628            try {
629                ASN1Reader reader = ASN1.getReader(responseValue);
630                reader.readStartSequence();
631                return reader.readOctetString(TYPE_PASSWORD_MODIFY_GENERATED_PASSWORD);
632            } catch (IOException e) {
633                throw LdapException.newLdapException(ResultCode.PROTOCOL_ERROR,
634                        ERR_EXTOP_PASSMOD_CANNOT_DECODE_REQUEST.get(getExceptionMessage(e)), e);
635            }
636        }
637        return null;
638    }
639
640    /**
641     * Converts from <code>byte[]</code> to OpenDJ server {@link ByteString}.
642     *
643     * @param authenticationValue
644     *          value to convert
645     * @return the converted value
646     */
647    public static ByteString getCredentials(final byte[] authenticationValue) {
648        final ASN1Reader reader = ASN1.getReader(authenticationValue);
649        try {
650            reader.readOctetStringAsString(); // Reads SASL Mechanism - RFC 4511 4.2
651            if (reader.hasNextElement()) {
652                return reader.readOctetString().toByteString();
653            }
654        } catch (IOException e) {
655            // Nothing to do.
656        }
657        return ByteString.empty();
658    }
659
660    /**
661     * Converts from OpenDJ server
662     * {@link org.opends.server.admin.std.meta.BackendVLVIndexCfgDefn.Scope} to
663     * {@link org.forgerock.opendj.server.config.meta.BackendVLVIndexCfgDefn.Scope}.
664     *
665     * @param scope
666     *          The scope value.
667     * @return The converted scope value.
668     */
669    public static BackendVLVIndexCfgDefn.Scope from(
670        final org.opends.server.admin.std.meta.BackendVLVIndexCfgDefn.Scope scope) {
671      Reject.ifNull(scope, "Provided scope to convert is null");
672      switch (scope) {
673      case BASE_OBJECT:
674        return BackendVLVIndexCfgDefn.Scope.BASE_OBJECT;
675      case SINGLE_LEVEL:
676        return BackendVLVIndexCfgDefn.Scope.SINGLE_LEVEL;
677      case SUBORDINATE_SUBTREE:
678        return BackendVLVIndexCfgDefn.Scope.SUBORDINATE_SUBTREE;
679      case WHOLE_SUBTREE:
680        return BackendVLVIndexCfgDefn.Scope.WHOLE_SUBTREE;
681      default:
682        throw new IllegalArgumentException("Impossible to convert the unknown scope: " + scope);
683      }
684    }
685}