Minor code cleanup and improvements:
* remove lots of duplicate and unused code
* moved LDAPMessageHandler into io package since it is required by LDAPReader
* added LDAP utility class for creating LDAPReader / LDAPWriter as well as static methods for common encoding/decoding (previously in LDAPUtils)
* minor Javadoc improvements simplifications
* minor simplifications to NameForm builder
* added makeldif shell scripts and updated site
* fixed rest2ldap build which was broken due to recent changes to json-resource.
8 files deleted
5 files added
42 files modified
| | |
| | | * The ASN.1 element decoding state that indicates that the next byte read |
| | | * should be additional bytes of a multi-byte length. |
| | | */ |
| | | static final int ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES = 2; |
| | | public static final int ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES = 2; |
| | | |
| | | /** |
| | | * The ASN.1 element decoding state that indicates that the next byte read |
| | | * should be the first byte for the element length. |
| | | */ |
| | | static final int ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE = 1; |
| | | public static final int ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE = 1; |
| | | |
| | | /** |
| | | * The ASN.1 element decoding state that indicates that the next byte read |
| | | * should be the BER type for a new element. |
| | | */ |
| | | static final int ELEMENT_READ_STATE_NEED_TYPE = 0; |
| | | public static final int ELEMENT_READ_STATE_NEED_TYPE = 0; |
| | | |
| | | /** |
| | | * The ASN.1 element decoding state that indicates that the next byte read |
| | | * should be applied to the value of the element. |
| | | */ |
| | | static final int ELEMENT_READ_STATE_NEED_VALUE_BYTES = 3; |
| | | public static final int ELEMENT_READ_STATE_NEED_VALUE_BYTES = 3; |
| | | |
| | | /** |
| | | * The byte array that will be used for ASN.1 elements with no value. |
| | | */ |
| | | static final byte[] NO_VALUE = new byte[0]; |
| | | |
| | | /** |
| | | * The bitmask that can be ANDed with the BER type to zero out all bits |
| | | * except those used in the class. |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.io; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.requests.AbandonRequest; |
| | | import org.forgerock.opendj.ldap.requests.AddRequest; |
| | | import org.forgerock.opendj.ldap.requests.CompareRequest; |
| | | import org.forgerock.opendj.ldap.requests.DeleteRequest; |
| | | import org.forgerock.opendj.ldap.requests.ExtendedRequest; |
| | | import org.forgerock.opendj.ldap.requests.GenericBindRequest; |
| | | import org.forgerock.opendj.ldap.requests.ModifyDNRequest; |
| | | import org.forgerock.opendj.ldap.requests.ModifyRequest; |
| | | import org.forgerock.opendj.ldap.requests.Request; |
| | | import org.forgerock.opendj.ldap.requests.SearchRequest; |
| | | import org.forgerock.opendj.ldap.requests.UnbindRequest; |
| | | import org.forgerock.opendj.ldap.responses.BindResult; |
| | | import org.forgerock.opendj.ldap.responses.CompareResult; |
| | | import org.forgerock.opendj.ldap.responses.ExtendedResult; |
| | | import org.forgerock.opendj.ldap.responses.IntermediateResponse; |
| | | import org.forgerock.opendj.ldap.responses.Response; |
| | | import org.forgerock.opendj.ldap.responses.Result; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultReference; |
| | | |
| | | /** |
| | | * This class provides a skeletal implementation of the |
| | | * {@link LDAPMessageHandler} interface, in order to minimize the effort |
| | | * required to implement this interface. By default each method throws a fatal |
| | | * {@link DecodeException}. |
| | | */ |
| | | public abstract class AbstractLDAPMessageHandler implements LDAPMessageHandler { |
| | | /** |
| | | * Default constructor. |
| | | */ |
| | | protected AbstractLDAPMessageHandler() { |
| | | // No implementation required. |
| | | } |
| | | |
| | | @Override |
| | | public void abandonRequest(final int messageID, final AbandonRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void addRequest(final int messageID, final AddRequest request) throws DecodeException, |
| | | IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void addResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public void bindRequest(final int messageID, final int version, final GenericBindRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void bindResult(final int messageID, final BindResult result) throws DecodeException, |
| | | IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public void compareRequest(final int messageID, final CompareRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void compareResult(final int messageID, final CompareResult result) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteRequest(final int messageID, final DeleteRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void deleteResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public <R extends ExtendedResult> void extendedRequest(final int messageID, |
| | | final ExtendedRequest<R> request) throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void extendedResult(final int messageID, final ExtendedResult result) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public void intermediateResponse(final int messageID, final IntermediateResponse response) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedResponseException(messageID, response); |
| | | } |
| | | |
| | | @Override |
| | | public void modifyDNRequest(final int messageID, final ModifyDNRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void modifyDNResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public void modifyRequest(final int messageID, final ModifyRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void modifyResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public void searchRequest(final int messageID, final SearchRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void searchResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | |
| | | @Override |
| | | public void searchResultEntry(final int messageID, final SearchResultEntry entry) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedResponseException(messageID, entry); |
| | | } |
| | | |
| | | @Override |
| | | public void searchResultReference(final int messageID, final SearchResultReference reference) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedResponseException(messageID, reference); |
| | | } |
| | | |
| | | @Override |
| | | public void unbindRequest(final int messageID, final UnbindRequest request) |
| | | throws DecodeException, IOException { |
| | | throw newUnexpectedRequestException(messageID, request); |
| | | } |
| | | |
| | | @Override |
| | | public void unrecognizedMessage(final int messageID, final byte messageTag, |
| | | final ByteString messageBytes) throws DecodeException, IOException { |
| | | throw newUnsupportedMessageException(messageID, messageTag, messageBytes); |
| | | } |
| | | |
| | | /** |
| | | * Returns a decoding exception suitable for use when an unsupported LDAP |
| | | * message is received. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param messageTag |
| | | * The LDAP message type. |
| | | * @param messageBytes |
| | | * The LDAP message content. |
| | | * @return A decoding exception suitable for use when an unsupported LDAP |
| | | * message is received. |
| | | */ |
| | | protected DecodeException newUnsupportedMessageException(final int messageID, |
| | | final byte messageTag, final ByteString messageBytes) { |
| | | return DecodeException.fatalError(LocalizableMessage.raw( |
| | | "Unsupported LDAP message: id=%d, tag=%d, content=%s", messageID, messageTag, |
| | | messageBytes)); |
| | | } |
| | | |
| | | /** |
| | | * Returns a decoding exception suitable for use when an unexpected LDAP |
| | | * request is received. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The LDAP request. |
| | | * @return A decoding exception suitable for use when an unexpected LDAP |
| | | * request is received. |
| | | */ |
| | | protected DecodeException newUnexpectedRequestException(final int messageID, |
| | | final Request request) { |
| | | return DecodeException.fatalError(LocalizableMessage.raw( |
| | | "Unexpected LDAP request: id=%d, message=%s", messageID, request)); |
| | | } |
| | | |
| | | /** |
| | | * Returns a decoding exception suitable for use when an unexpected LDAP |
| | | * response is received. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param response |
| | | * The LDAP response. |
| | | * @return A decoding exception suitable for use when an unexpected LDAP |
| | | * response is received. |
| | | */ |
| | | protected DecodeException newUnexpectedResponseException(final int messageID, |
| | | final Response response) { |
| | | return DecodeException.fatalError(LocalizableMessage.raw( |
| | | "Unexpected LDAP response: id=%d, message=%s", messageID, response)); |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.io; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.Collections; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.i18n.LocalizedIllegalArgumentException; |
| | | import org.forgerock.opendj.ldap.Attribute; |
| | | import org.forgerock.opendj.ldap.AttributeDescription; |
| | | import org.forgerock.opendj.ldap.ByteSequence; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.Filter; |
| | | import org.forgerock.opendj.ldap.FilterVisitor; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | |
| | | /** |
| | | * This class contains various static utility methods encoding and decoding LDAP |
| | | * protocol elements. |
| | | * |
| | | * @see LDAPReader |
| | | * @see LDAPWriter |
| | | */ |
| | | public final class LDAP { |
| | | // @Checkstyle:ignore AvoidNestedBlocks |
| | | |
| | | /** |
| | | * The OID for the Kerberos V GSSAPI mechanism. |
| | | */ |
| | | public static final String OID_GSSAPI_KERBEROS_V = "1.2.840.113554.1.2.2"; |
| | | |
| | | /** |
| | | * The OID for the LDAP notice of disconnection extended operation. |
| | | */ |
| | | public static final String OID_NOTICE_OF_DISCONNECTION = "1.3.6.1.4.1.1466.20036"; |
| | | |
| | | /** |
| | | * The protocol op type for abandon requests. |
| | | */ |
| | | public static final byte OP_TYPE_ABANDON_REQUEST = 0x50; |
| | | |
| | | /** |
| | | * The protocol op type for add requests. |
| | | */ |
| | | public static final byte OP_TYPE_ADD_REQUEST = 0x68; |
| | | |
| | | /** |
| | | * The protocol op type for add responses. |
| | | */ |
| | | public static final byte OP_TYPE_ADD_RESPONSE = 0x69; |
| | | |
| | | /** |
| | | * The protocol op type for bind requests. |
| | | */ |
| | | public static final byte OP_TYPE_BIND_REQUEST = 0x60; |
| | | |
| | | /** |
| | | * The protocol op type for bind responses. |
| | | */ |
| | | public static final byte OP_TYPE_BIND_RESPONSE = 0x61; |
| | | |
| | | /** |
| | | * The protocol op type for compare requests. |
| | | */ |
| | | public static final byte OP_TYPE_COMPARE_REQUEST = 0x6E; |
| | | |
| | | /** |
| | | * The protocol op type for compare responses. |
| | | */ |
| | | public static final byte OP_TYPE_COMPARE_RESPONSE = 0x6F; |
| | | |
| | | /** |
| | | * The protocol op type for delete requests. |
| | | */ |
| | | public static final byte OP_TYPE_DELETE_REQUEST = 0x4A; |
| | | |
| | | /** |
| | | * The protocol op type for delete responses. |
| | | */ |
| | | public static final byte OP_TYPE_DELETE_RESPONSE = 0x6B; |
| | | |
| | | /** |
| | | * The protocol op type for extended requests. |
| | | */ |
| | | public static final byte OP_TYPE_EXTENDED_REQUEST = 0x77; |
| | | |
| | | /** |
| | | * The protocol op type for extended responses. |
| | | */ |
| | | public static final byte OP_TYPE_EXTENDED_RESPONSE = 0x78; |
| | | |
| | | /** |
| | | * The protocol op type for intermediate responses. |
| | | */ |
| | | public static final byte OP_TYPE_INTERMEDIATE_RESPONSE = 0x79; |
| | | |
| | | /** |
| | | * The protocol op type for modify DN requests. |
| | | */ |
| | | public static final byte OP_TYPE_MODIFY_DN_REQUEST = 0x6C; |
| | | |
| | | /** |
| | | * The protocol op type for modify DN responses. |
| | | */ |
| | | public static final byte OP_TYPE_MODIFY_DN_RESPONSE = 0x6D; |
| | | |
| | | /** |
| | | * The protocol op type for modify requests. |
| | | */ |
| | | public static final byte OP_TYPE_MODIFY_REQUEST = 0x66; |
| | | |
| | | /** |
| | | * The protocol op type for modify responses. |
| | | */ |
| | | public static final byte OP_TYPE_MODIFY_RESPONSE = 0x67; |
| | | /** |
| | | * The protocol op type for search requests. |
| | | */ |
| | | public static final byte OP_TYPE_SEARCH_REQUEST = 0x63; |
| | | /** |
| | | * The protocol op type for search result done elements. |
| | | */ |
| | | public static final byte OP_TYPE_SEARCH_RESULT_DONE = 0x65; |
| | | /** |
| | | * The protocol op type for search result entries. |
| | | */ |
| | | public static final byte OP_TYPE_SEARCH_RESULT_ENTRY = 0x64; |
| | | /** |
| | | * The protocol op type for search result references. |
| | | */ |
| | | public static final byte OP_TYPE_SEARCH_RESULT_REFERENCE = 0x73; |
| | | /** |
| | | * The protocol op type for unbind requests. |
| | | */ |
| | | public static final byte OP_TYPE_UNBIND_REQUEST = 0x42; |
| | | /** |
| | | * The BER type to use for the AuthenticationChoice element in a bind |
| | | * request when SASL authentication is to be used. |
| | | */ |
| | | public static final byte TYPE_AUTHENTICATION_SASL = (byte) 0xA3; |
| | | /** |
| | | * The BER type to use for the AuthenticationChoice element in a bind |
| | | * request when simple authentication is to be used. |
| | | */ |
| | | public static final byte TYPE_AUTHENTICATION_SIMPLE = (byte) 0x80; |
| | | /** |
| | | * The BER type to use for encoding the sequence of controls in an LDAP |
| | | * message. |
| | | */ |
| | | public static final byte TYPE_CONTROL_SEQUENCE = (byte) 0xA0; |
| | | /** |
| | | * The BER type to use for the OID of an extended request. |
| | | */ |
| | | public static final byte TYPE_EXTENDED_REQUEST_OID = (byte) 0x80; |
| | | /** |
| | | * The BER type to use for the value of an extended request. |
| | | */ |
| | | public static final byte TYPE_EXTENDED_REQUEST_VALUE = (byte) 0x81; |
| | | /** |
| | | * The BER type to use for the OID of an extended response. |
| | | */ |
| | | public static final byte TYPE_EXTENDED_RESPONSE_OID = (byte) 0x8A; |
| | | /** |
| | | * The BER type to use for the value of an extended response. |
| | | */ |
| | | public static final byte TYPE_EXTENDED_RESPONSE_VALUE = (byte) 0x8B; |
| | | /** |
| | | * The BER type to use for AND filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_AND = (byte) 0xA0; |
| | | /** |
| | | * The BER type to use for approximate filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_APPROXIMATE = (byte) 0xA8; |
| | | /** |
| | | * The BER type to use for equality filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_EQUALITY = (byte) 0xA3; |
| | | /** |
| | | * The BER type to use for extensible matching filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_EXTENSIBLE_MATCH = (byte) 0xA9; |
| | | /** |
| | | * The BER type to use for greater than or equal to filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_GREATER_OR_EQUAL = (byte) 0xA5; |
| | | /** |
| | | * The BER type to use for less than or equal to filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_LESS_OR_EQUAL = (byte) 0xA6; |
| | | /** |
| | | * The BER type to use for NOT filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_NOT = (byte) 0xA2; |
| | | /** |
| | | * The BER type to use for OR filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_OR = (byte) 0xA1; |
| | | /** |
| | | * The BER type to use for presence filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_PRESENCE = (byte) 0x87; |
| | | /** |
| | | * The BER type to use for substring filter components. |
| | | */ |
| | | public static final byte TYPE_FILTER_SUBSTRING = (byte) 0xA4; |
| | | /** |
| | | * The BER type to use for the OID of an intermediate response message. |
| | | */ |
| | | public static final byte TYPE_INTERMEDIATE_RESPONSE_OID = (byte) 0x80; |
| | | /** |
| | | * The BER type to use for the value of an intermediate response message. |
| | | */ |
| | | public static final byte TYPE_INTERMEDIATE_RESPONSE_VALUE = (byte) 0x81; |
| | | /** |
| | | * The BER type to use for the DN attributes flag in a matching rule |
| | | * assertion. |
| | | */ |
| | | public static final byte TYPE_MATCHING_RULE_DN_ATTRIBUTES = (byte) 0x84; |
| | | /** |
| | | * The BER type to use for the matching rule OID in a matching rule |
| | | * assertion. |
| | | */ |
| | | public static final byte TYPE_MATCHING_RULE_ID = (byte) 0x81; |
| | | /** |
| | | * The BER type to use for the attribute type in a matching rule assertion. |
| | | */ |
| | | public static final byte TYPE_MATCHING_RULE_TYPE = (byte) 0x82; |
| | | /** |
| | | * The BER type to use for the assertion value in a matching rule assertion. |
| | | */ |
| | | public static final byte TYPE_MATCHING_RULE_VALUE = (byte) 0x83; |
| | | /** |
| | | * The BER type to use for the newSuperior component of a modify DN request. |
| | | */ |
| | | public static final byte TYPE_MODIFY_DN_NEW_SUPERIOR = (byte) 0x80; |
| | | /** |
| | | * The BER type to use for encoding the sequence of referral URLs in an |
| | | * LDAPResult element. |
| | | */ |
| | | public static final byte TYPE_REFERRAL_SEQUENCE = (byte) 0xA3; |
| | | /** |
| | | * The BER type to use for the server SASL credentials in a bind response. |
| | | */ |
| | | public static final byte TYPE_SERVER_SASL_CREDENTIALS = (byte) 0x87; |
| | | /** |
| | | * The BER type to use for the subAny component(s) of a substring filter. |
| | | */ |
| | | public static final byte TYPE_SUBANY = (byte) 0x81; |
| | | /** |
| | | * The BER type to use for the subFinal components of a substring filter. |
| | | */ |
| | | public static final byte TYPE_SUBFINAL = (byte) 0x82; |
| | | /** |
| | | * The BER type to use for the subInitial component of a substring filter. |
| | | */ |
| | | public static final byte TYPE_SUBINITIAL = (byte) 0x80; |
| | | private static final FilterVisitor<IOException, ASN1Writer> ASN1_ENCODER = |
| | | new FilterVisitor<IOException, ASN1Writer>() { |
| | | |
| | | @Override |
| | | public IOException visitAndFilter(final ASN1Writer writer, |
| | | final List<Filter> subFilters) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_AND); |
| | | for (final Filter subFilter : subFilters) { |
| | | final IOException e = subFilter.accept(this, writer); |
| | | if (e != null) { |
| | | return e; |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitApproxMatchFilter(final ASN1Writer writer, |
| | | final String attributeDescription, final ByteString assertionValue) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_APPROXIMATE); |
| | | writer.writeOctetString(attributeDescription); |
| | | writer.writeOctetString(assertionValue); |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitEqualityMatchFilter(final ASN1Writer writer, |
| | | final String attributeDescription, final ByteString assertionValue) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_EQUALITY); |
| | | writer.writeOctetString(attributeDescription); |
| | | writer.writeOctetString(assertionValue); |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitExtensibleMatchFilter(final ASN1Writer writer, |
| | | final String matchingRule, final String attributeDescription, |
| | | final ByteString assertionValue, final boolean dnAttributes) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_EXTENSIBLE_MATCH); |
| | | |
| | | if (matchingRule != null) { |
| | | writer.writeOctetString(LDAP.TYPE_MATCHING_RULE_ID, matchingRule); |
| | | } |
| | | |
| | | if (attributeDescription != null) { |
| | | writer.writeOctetString(LDAP.TYPE_MATCHING_RULE_TYPE, |
| | | attributeDescription); |
| | | } |
| | | |
| | | writer.writeOctetString(LDAP.TYPE_MATCHING_RULE_VALUE, assertionValue); |
| | | |
| | | if (dnAttributes) { |
| | | writer.writeBoolean(LDAP.TYPE_MATCHING_RULE_DN_ATTRIBUTES, true); |
| | | } |
| | | |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitGreaterOrEqualFilter(final ASN1Writer writer, |
| | | final String attributeDescription, final ByteString assertionValue) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_GREATER_OR_EQUAL); |
| | | writer.writeOctetString(attributeDescription); |
| | | writer.writeOctetString(assertionValue); |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitLessOrEqualFilter(final ASN1Writer writer, |
| | | final String attributeDescription, final ByteString assertionValue) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_LESS_OR_EQUAL); |
| | | writer.writeOctetString(attributeDescription); |
| | | writer.writeOctetString(assertionValue); |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitNotFilter(final ASN1Writer writer, final Filter subFilter) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_NOT); |
| | | final IOException e = subFilter.accept(this, writer); |
| | | if (e != null) { |
| | | return e; |
| | | } |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitOrFilter(final ASN1Writer writer, |
| | | final List<Filter> subFilters) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_OR); |
| | | for (final Filter subFilter : subFilters) { |
| | | final IOException e = subFilter.accept(this, writer); |
| | | if (e != null) { |
| | | return e; |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitPresentFilter(final ASN1Writer writer, |
| | | final String attributeDescription) { |
| | | try { |
| | | writer.writeOctetString(LDAP.TYPE_FILTER_PRESENCE, attributeDescription); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitSubstringsFilter(final ASN1Writer writer, |
| | | final String attributeDescription, final ByteString initialSubstring, |
| | | final List<ByteString> anySubstrings, final ByteString finalSubstring) { |
| | | try { |
| | | writer.writeStartSequence(LDAP.TYPE_FILTER_SUBSTRING); |
| | | writer.writeOctetString(attributeDescription); |
| | | |
| | | writer.writeStartSequence(); |
| | | if (initialSubstring != null) { |
| | | writer.writeOctetString(LDAP.TYPE_SUBINITIAL, initialSubstring); |
| | | } |
| | | |
| | | for (final ByteSequence anySubstring : anySubstrings) { |
| | | writer.writeOctetString(LDAP.TYPE_SUBANY, anySubstring); |
| | | } |
| | | |
| | | if (finalSubstring != null) { |
| | | writer.writeOctetString(LDAP.TYPE_SUBFINAL, finalSubstring); |
| | | } |
| | | writer.writeEndSequence(); |
| | | |
| | | writer.writeEndSequence(); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public IOException visitUnrecognizedFilter(final ASN1Writer writer, |
| | | final byte filterTag, final ByteString filterBytes) { |
| | | try { |
| | | writer.writeOctetString(filterTag, filterBytes); |
| | | return null; |
| | | } catch (final IOException e) { |
| | | return e; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | /** |
| | | * Creates a new LDAP reader which will read LDAP messages from an ASN.1 |
| | | * reader using the provided decoding options. |
| | | * |
| | | * @param <R> |
| | | * The type of ASN.1 reader used for decoding elements. |
| | | * @param asn1Reader |
| | | * The ASN.1 reader from which LDAP messages will be read. |
| | | * @param options |
| | | * LDAP message decoding options. |
| | | * @return A new LDAP reader which will read LDAP messages from an ASN.1 |
| | | * reader using the provided decoding options. |
| | | */ |
| | | public static <R extends ASN1Reader> LDAPReader<R> getReader(final R asn1Reader, |
| | | final DecodeOptions options) { |
| | | return new LDAPReader<R>(asn1Reader, options); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new LDAP writer which will write LDAP messages to the provided |
| | | * ASN.1 writer. |
| | | * |
| | | * @param <W> |
| | | * The type of ASN.1 writer used for encoding elements. |
| | | * @param asn1Writer |
| | | * The ASN.1 writer to which LDAP messages will be written. |
| | | * @return A new LDAP writer which will write LDAP messages to the provided |
| | | * ASN.1 writer. |
| | | */ |
| | | public static <W extends ASN1Writer> LDAPWriter<W> getWriter(final W asn1Writer) { |
| | | return new LDAPWriter<W>(asn1Writer); |
| | | } |
| | | |
| | | /** |
| | | * Reads the next ASN.1 element from the provided {@code ASN1Reader} as a |
| | | * {@code Filter}. |
| | | * |
| | | * @param reader |
| | | * The {@code ASN1Reader} from which the ASN.1 encoded |
| | | * {@code Filter} should be read. |
| | | * @return The decoded {@code Filter}. |
| | | * @throws IOException |
| | | * If an error occurs while reading from {@code reader}. |
| | | */ |
| | | public static Filter readFilter(final ASN1Reader reader) throws IOException { |
| | | final byte type = reader.peekType(); |
| | | switch (type) { |
| | | case LDAP.TYPE_FILTER_AND: |
| | | return readAndFilter(reader); |
| | | case LDAP.TYPE_FILTER_OR: |
| | | return readOrFilter(reader); |
| | | case LDAP.TYPE_FILTER_NOT: |
| | | return readNotFilter(reader); |
| | | case LDAP.TYPE_FILTER_EQUALITY: |
| | | return readEqualityMatchFilter(reader); |
| | | case LDAP.TYPE_FILTER_GREATER_OR_EQUAL: |
| | | return readGreaterOrEqualMatchFilter(reader); |
| | | case LDAP.TYPE_FILTER_LESS_OR_EQUAL: |
| | | return readLessOrEqualMatchFilter(reader); |
| | | case LDAP.TYPE_FILTER_APPROXIMATE: |
| | | return readApproxMatchFilter(reader); |
| | | case LDAP.TYPE_FILTER_SUBSTRING: |
| | | return readSubstringsFilter(reader); |
| | | case LDAP.TYPE_FILTER_PRESENCE: |
| | | return Filter.present(reader.readOctetStringAsString(type)); |
| | | case LDAP.TYPE_FILTER_EXTENSIBLE_MATCH: |
| | | return readExtensibleMatchFilter(reader); |
| | | default: |
| | | return Filter.unrecognized(type, reader.readOctetString(type)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Reads the next ASN.1 element from the provided {@code ASN1Reader} as a an |
| | | * {@code Entry}. |
| | | * |
| | | * @param reader |
| | | * The {@code ASN1Reader} from which the ASN.1 encoded |
| | | * {@code Entry} should be read. |
| | | * @param options |
| | | * The decode options to use when decoding the entry. |
| | | * @return The decoded {@code Entry}. |
| | | * @throws IOException |
| | | * If an error occurs while reading from {@code reader}. |
| | | */ |
| | | public static Entry readEntry(final ASN1Reader reader, final DecodeOptions options) |
| | | throws IOException { |
| | | return readEntry(reader, OP_TYPE_SEARCH_RESULT_ENTRY, options); |
| | | } |
| | | |
| | | /** |
| | | * Writes a {@code Filter} to the provided {@code ASN1Writer}. |
| | | * |
| | | * @param writer |
| | | * The {@code ASN1Writer} to which the ASN.1 encoded |
| | | * {@code Filter} should be written. |
| | | * @param filter |
| | | * The filter. |
| | | * @throws IOException |
| | | * If an error occurs while writing to {@code writer}. |
| | | */ |
| | | public static void writeFilter(final ASN1Writer writer, final Filter filter) throws IOException { |
| | | final IOException e = filter.accept(ASN1_ENCODER, writer); |
| | | if (e != null) { |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Writes an {@code Entry} to the provided {@code ASN1Writer}. |
| | | * |
| | | * @param writer |
| | | * The {@code ASN1Writer} to which the ASN.1 encoded |
| | | * {@code Entry} should be written. |
| | | * @param entry |
| | | * The entry. |
| | | * @throws IOException |
| | | * If an error occurs while writing to {@code writer}. |
| | | */ |
| | | public static void writeEntry(final ASN1Writer writer, final Entry entry) throws IOException { |
| | | writeEntry(writer, OP_TYPE_SEARCH_RESULT_ENTRY, entry); |
| | | } |
| | | |
| | | static AttributeDescription readAttributeDescription(final String attributeDescription, |
| | | final Schema schema) throws DecodeException { |
| | | try { |
| | | return AttributeDescription.valueOf(attributeDescription, schema); |
| | | } catch (final LocalizedIllegalArgumentException e) { |
| | | throw DecodeException.error(e.getMessageObject()); |
| | | } |
| | | } |
| | | |
| | | static DN readDN(final String dn, final Schema schema) throws DecodeException { |
| | | try { |
| | | return DN.valueOf(dn, schema); |
| | | } catch (final LocalizedIllegalArgumentException e) { |
| | | throw DecodeException.error(e.getMessageObject()); |
| | | } |
| | | } |
| | | |
| | | static Entry readEntry(final ASN1Reader reader, final byte tagType, final DecodeOptions options) |
| | | throws DecodeException, IOException { |
| | | reader.readStartSequence(tagType); |
| | | final Entry entry; |
| | | try { |
| | | final String dnString = reader.readOctetStringAsString(); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(dnString); |
| | | final DN dn = readDN(dnString, schema); |
| | | entry = options.getEntryFactory().newEntry(dn); |
| | | reader.readStartSequence(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | reader.readStartSequence(); |
| | | try { |
| | | final String ads = reader.readOctetStringAsString(); |
| | | final AttributeDescription ad = readAttributeDescription(ads, schema); |
| | | final Attribute attribute = options.getAttributeFactory().newAttribute(ad); |
| | | reader.readStartSet(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | attribute.add(reader.readOctetString()); |
| | | } |
| | | entry.addAttribute(attribute); |
| | | } finally { |
| | | reader.readEndSet(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | return entry; |
| | | } |
| | | |
| | | static void writeAttribute(final ASN1Writer writer, final Attribute attribute) |
| | | throws IOException { |
| | | writer.writeStartSequence(); |
| | | { |
| | | writer.writeOctetString(attribute.getAttributeDescriptionAsString()); |
| | | writer.writeStartSet(); |
| | | { |
| | | for (final ByteString value : attribute) { |
| | | writer.writeOctetString(value); |
| | | } |
| | | } |
| | | writer.writeEndSet(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | static void writeEntry(final ASN1Writer writer, final byte typeTag, final Entry entry) |
| | | throws IOException { |
| | | writer.writeStartSequence(typeTag); |
| | | { |
| | | writer.writeOctetString(entry.getName().toString()); |
| | | writer.writeStartSequence(); |
| | | { |
| | | for (final Attribute attr : entry.getAllAttributes()) { |
| | | writeAttribute(writer, attr); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | private static Filter readAndFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_AND); |
| | | try { |
| | | if (reader.hasNextElement()) { |
| | | final List<Filter> subFilters = new LinkedList<Filter>(); |
| | | do { |
| | | subFilters.add(readFilter(reader)); |
| | | } while (reader.hasNextElement()); |
| | | return Filter.and(subFilters); |
| | | } else { |
| | | // No sub-filters - this is an RFC 4526 absolute true filter. |
| | | return Filter.alwaysTrue(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | private static Filter readApproxMatchFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_APPROXIMATE); |
| | | try { |
| | | final String attributeDescription = reader.readOctetStringAsString(); |
| | | final ByteString assertionValue = reader.readOctetString(); |
| | | return Filter.approx(attributeDescription, assertionValue); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | } |
| | | |
| | | private static Filter readEqualityMatchFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_EQUALITY); |
| | | try { |
| | | final String attributeDescription = reader.readOctetStringAsString(); |
| | | final ByteString assertionValue = reader.readOctetString(); |
| | | return Filter.equality(attributeDescription, assertionValue); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | private static Filter readExtensibleMatchFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_EXTENSIBLE_MATCH); |
| | | try { |
| | | String matchingRule = null; |
| | | if (reader.peekType() == LDAP.TYPE_MATCHING_RULE_ID) { |
| | | matchingRule = reader.readOctetStringAsString(LDAP.TYPE_MATCHING_RULE_ID); |
| | | } |
| | | String attributeDescription = null; |
| | | if (reader.peekType() == LDAP.TYPE_MATCHING_RULE_TYPE) { |
| | | attributeDescription = reader.readOctetStringAsString(LDAP.TYPE_MATCHING_RULE_TYPE); |
| | | } |
| | | boolean dnAttributes = false; |
| | | if (reader.hasNextElement() |
| | | && (reader.peekType() == LDAP.TYPE_MATCHING_RULE_DN_ATTRIBUTES)) { |
| | | dnAttributes = reader.readBoolean(); |
| | | } |
| | | final ByteString assertionValue = reader.readOctetString(LDAP.TYPE_MATCHING_RULE_VALUE); |
| | | return Filter.extensible(matchingRule, attributeDescription, assertionValue, |
| | | dnAttributes); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | private static Filter readGreaterOrEqualMatchFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_GREATER_OR_EQUAL); |
| | | try { |
| | | final String attributeDescription = reader.readOctetStringAsString(); |
| | | final ByteString assertionValue = reader.readOctetString(); |
| | | return Filter.greaterOrEqual(attributeDescription, assertionValue); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | private static Filter readLessOrEqualMatchFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_LESS_OR_EQUAL); |
| | | try { |
| | | final String attributeDescription = reader.readOctetStringAsString(); |
| | | final ByteString assertionValue = reader.readOctetString(); |
| | | return Filter.lessOrEqual(attributeDescription, assertionValue); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | private static Filter readNotFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_NOT); |
| | | try { |
| | | return Filter.not(readFilter(reader)); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | private static Filter readOrFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_OR); |
| | | try { |
| | | if (reader.hasNextElement()) { |
| | | final List<Filter> subFilters = new LinkedList<Filter>(); |
| | | do { |
| | | subFilters.add(readFilter(reader)); |
| | | } while (reader.hasNextElement()); |
| | | return Filter.or(subFilters); |
| | | } else { |
| | | // No sub-filters - this is an RFC 4526 absolute false filter. |
| | | return Filter.alwaysFalse(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | private static Filter readSubstringsFilter(final ASN1Reader reader) throws IOException { |
| | | reader.readStartSequence(LDAP.TYPE_FILTER_SUBSTRING); |
| | | try { |
| | | final String attributeDescription = reader.readOctetStringAsString(); |
| | | reader.readStartSequence(); |
| | | try { |
| | | // FIXME: There should be at least one element in this substring |
| | | // filter sequence. |
| | | ByteString initialSubstring = null; |
| | | if (reader.peekType() == LDAP.TYPE_SUBINITIAL) { |
| | | initialSubstring = reader.readOctetString(LDAP.TYPE_SUBINITIAL); |
| | | } |
| | | final List<ByteString> anySubstrings; |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_SUBANY)) { |
| | | anySubstrings = new LinkedList<ByteString>(); |
| | | do { |
| | | anySubstrings.add(reader.readOctetString(LDAP.TYPE_SUBANY)); |
| | | } while (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_SUBANY)); |
| | | } else { |
| | | anySubstrings = Collections.emptyList(); |
| | | } |
| | | ByteString finalSubstring = null; |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_SUBFINAL)) { |
| | | finalSubstring = reader.readOctetString(LDAP.TYPE_SUBFINAL); |
| | | } |
| | | return Filter.substrings(attributeDescription, initialSubstring, anySubstrings, |
| | | finalSubstring); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | |
| | | // Prevent instantiation. |
| | | private LDAP() { |
| | | // Nothing to do. |
| | | } |
| | | } |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt |
| | | * or http://forgerock.org/license/CDDLv1.0.html. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | * If applicable, add the following below this CDDL HEADER, with the |
| | | * fields enclosed by brackets "[]" replaced with your own identifying |
| | | * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | * Portions copyright 2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.io; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.requests.AbandonRequest; |
| | | import org.forgerock.opendj.ldap.requests.AddRequest; |
| | | import org.forgerock.opendj.ldap.requests.CompareRequest; |
| | | import org.forgerock.opendj.ldap.requests.DeleteRequest; |
| | | import org.forgerock.opendj.ldap.requests.ExtendedRequest; |
| | | import org.forgerock.opendj.ldap.requests.GenericBindRequest; |
| | | import org.forgerock.opendj.ldap.requests.ModifyDNRequest; |
| | | import org.forgerock.opendj.ldap.requests.ModifyRequest; |
| | | import org.forgerock.opendj.ldap.requests.SearchRequest; |
| | | import org.forgerock.opendj.ldap.requests.UnbindRequest; |
| | | import org.forgerock.opendj.ldap.responses.BindResult; |
| | | import org.forgerock.opendj.ldap.responses.CompareResult; |
| | | import org.forgerock.opendj.ldap.responses.ExtendedResult; |
| | | import org.forgerock.opendj.ldap.responses.IntermediateResponse; |
| | | import org.forgerock.opendj.ldap.responses.Result; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultReference; |
| | | |
| | | /** |
| | | * An interface for handling LDAP messages decoded using an {@link LDAPReader}. |
| | | */ |
| | | public interface LDAPMessageHandler { |
| | | |
| | | /** |
| | | * Handles an LDAP abandon request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded abandon request. |
| | | * @throws DecodeException |
| | | * If this handler does not support abandon requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void abandonRequest(int messageID, AbandonRequest request) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP add request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded add request. |
| | | * @throws DecodeException |
| | | * If this handler does not support add requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void addRequest(int messageID, AddRequest request) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP add result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded add result. |
| | | * @throws DecodeException |
| | | * If this handler does not support add results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void addResult(int messageID, Result result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP bind request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param version |
| | | * The requested LDAP protocol version. |
| | | * @param request |
| | | * The decoded bind request. |
| | | * @throws DecodeException |
| | | * If this handler does not support bind requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void bindRequest(int messageID, int version, GenericBindRequest request) |
| | | throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP bind result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded bind result. |
| | | * @throws DecodeException |
| | | * If this handler does not support bind results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void bindResult(int messageID, BindResult result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP compare request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded compare request. |
| | | * @throws DecodeException |
| | | * If this handler does not support compare requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void compareRequest(int messageID, CompareRequest request) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP compare result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded compare result. |
| | | * @throws DecodeException |
| | | * If this handler does not support compare results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void compareResult(int messageID, CompareResult result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP delete request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded delete request. |
| | | * @throws DecodeException |
| | | * If this handler does not support delete requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void deleteRequest(int messageID, DeleteRequest request) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP delete result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded delete result. |
| | | * @throws DecodeException |
| | | * If this handler does not support delete results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void deleteResult(int messageID, Result result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP extended request message. |
| | | * |
| | | * @param <R> |
| | | * type of extended result |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded extended request. |
| | | * @throws DecodeException |
| | | * If this handler does not support extended requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | <R extends ExtendedResult> void extendedRequest(int messageID, ExtendedRequest<R> request) |
| | | throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP extended result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded extended result. |
| | | * @throws DecodeException |
| | | * If this handler does not support extended results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void extendedResult(int messageID, ExtendedResult result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP intermediate response message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param response |
| | | * The decoded intermediate response. |
| | | * @throws DecodeException |
| | | * If this handler does not support intermediate responses. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void intermediateResponse(int messageID, IntermediateResponse response) throws DecodeException, |
| | | IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP modify DN request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded modify DN request. |
| | | * @throws DecodeException |
| | | * If this handler does not support modify DN requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void modifyDNRequest(int messageID, ModifyDNRequest request) throws DecodeException, |
| | | IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP modify DN result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded modify DN result. |
| | | * @throws DecodeException |
| | | * If this handler does not support modify DN results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void modifyDNResult(int messageID, Result result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP modify request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded modify request. |
| | | * @throws DecodeException |
| | | * If this handler does not support modify requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void modifyRequest(int messageID, ModifyRequest request) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP modify result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded modify result. |
| | | * @throws DecodeException |
| | | * If this handler does not support modify results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void modifyResult(int messageID, Result result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP search request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded search request. |
| | | * @throws DecodeException |
| | | * If this handler does not support search requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void searchRequest(int messageID, SearchRequest request) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP search result message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The decoded search result. |
| | | * @throws DecodeException |
| | | * If this handler does not support search results. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void searchResult(int messageID, Result result) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP search result entry message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param entry |
| | | * The decoded search result entry. |
| | | * @throws DecodeException |
| | | * If this handler does not support search result entries. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void searchResultEntry(int messageID, SearchResultEntry entry) throws DecodeException, |
| | | IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP search result reference message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param reference |
| | | * The decoded search result reference. |
| | | * @throws DecodeException |
| | | * If this handler does not support search result references. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * response. |
| | | */ |
| | | void searchResultReference(int messageID, SearchResultReference reference) |
| | | throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an LDAP unbind request message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The decoded unbind request. |
| | | * @throws DecodeException |
| | | * If this handler does not support unbind requests. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * request. |
| | | */ |
| | | void unbindRequest(int messageID, UnbindRequest request) throws DecodeException, IOException; |
| | | |
| | | /** |
| | | * Handles an unrecognized LDAP message. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param messageTag |
| | | * The LDAP message type. |
| | | * @param messageBytes |
| | | * The contents of the LDAP message. |
| | | * @throws DecodeException |
| | | * If this handler does not support the message type. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred while processing the |
| | | * message. |
| | | */ |
| | | void unrecognizedMessage(int messageID, byte messageTag, ByteString messageBytes) |
| | | throws DecodeException, IOException; |
| | | } |
| | |
| | | |
| | | package org.forgerock.opendj.io; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.*; |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.*; |
| | | import static com.forgerock.opendj.util.StaticUtils.*; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_MODIFICATION_DECODE_INVALID_MOD_TYPE; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_DEREF; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_SCOPE; |
| | | import static com.forgerock.opendj.util.StaticUtils.IO_LOG; |
| | | import static com.forgerock.opendj.util.StaticUtils.byteToHex; |
| | | |
| | | import java.io.IOException; |
| | | |
| | |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultReference; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | import org.forgerock.opendj.ldap.spi.LDAPMessageHandler; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPUtils; |
| | | |
| | | /** |
| | | * Responsible for reading LDAP messages. |
| | | * Reads LDAP messages from an underlying ASN.1 reader. |
| | | * |
| | | * @param <R> |
| | | * type of ASN1 reader used to decode elements |
| | | * The type of ASN.1 reader used for decoding elements. |
| | | */ |
| | | public final class LDAPReader<R extends ASN1Reader> { |
| | | |
| | | private final DecodeOptions options; |
| | | private final R reader; |
| | | |
| | | private final DecodeOptions options; |
| | | |
| | | /** |
| | | * Creates a reader with the provided ASN1 reader and decoding options. |
| | | * |
| | | * @param asn1Reader |
| | | * reader capable of decoding ASN1 elements |
| | | * @param options |
| | | * allow to control how responses and requests are decoded |
| | | */ |
| | | public LDAPReader(final R asn1Reader, final DecodeOptions options) { |
| | | LDAPReader(final R asn1Reader, final DecodeOptions options) { |
| | | this.reader = asn1Reader; |
| | | this.options = options; |
| | | } |
| | | |
| | | /** |
| | | * Returns the ASN1 reader used to decode elements. |
| | | * Returns the ASN.1 reader from which LDAP messages will be read. |
| | | * |
| | | * @return ASN1 reader |
| | | * @return The ASN.1 reader from which LDAP messages will be read. |
| | | */ |
| | | public R getASN1Reader() { |
| | | return reader; |
| | | } |
| | | |
| | | /** |
| | | * Read a LDAP message by decoding the elements from the provided ASN.1 asn1Reader. |
| | | * Returns {@code true} if the next LDAP message can be read without |
| | | * blocking. |
| | | * |
| | | * @return {@code true} if the next LDAP message can be read without |
| | | * blocking or {@code false} otherwise. |
| | | * @throws DecodeException |
| | | * If the available data was not a valid LDAP message. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public boolean hasMessageAvailable() throws DecodeException, IOException { |
| | | return reader.elementAvailable(); |
| | | } |
| | | |
| | | /** |
| | | * Reads the next LDAP message from the underlying ASN.1 reader. |
| | | * |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle a decoded |
| | | * The message handler which will handle the decoded LDAP |
| | | * message. |
| | | * @throws DecodeException |
| | | * If the available data was not a valid LDAP message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void readMessage(final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | public void readMessage(final LDAPMessageHandler handler) throws DecodeException, IOException { |
| | | reader.readStartSequence(); |
| | | try { |
| | | final int messageID = (int) reader.readInteger(); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether or not the next message can be read without blocking. |
| | | * |
| | | * @return {@code true} if a complete element is available or {@code false} |
| | | * otherwise. |
| | | * @throws DecodeException |
| | | * If the available data was not valid ASN.1. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public boolean hasMessageAvailable() throws DecodeException, IOException { |
| | | return reader.elementAvailable(); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 read as an LDAP abandon |
| | | * request protocol op. |
| | | * |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readAbandonRequest(final int messageID, final LDAPMessageHandler handler) throws IOException { |
| | | final int msgToAbandon = (int) reader.readInteger(OP_TYPE_ABANDON_REQUEST); |
| | | private void readAbandonRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | final int msgToAbandon = (int) reader.readInteger(LDAP.OP_TYPE_ABANDON_REQUEST); |
| | | final AbandonRequest message = Requests.newAbandonRequest(msgToAbandon); |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP ABANDON REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.abandonRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP add |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readAddRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | Entry entry; |
| | | |
| | | reader.readStartSequence(OP_TYPE_ADD_REQUEST); |
| | | try { |
| | | final String dnString = reader.readOctetStringAsString(); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(dnString); |
| | | final DN dn = readDN(dnString, schema); |
| | | entry = options.getEntryFactory().newEntry(dn); |
| | | |
| | | reader.readStartSequence(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | reader.readStartSequence(); |
| | | try { |
| | | final String ads = reader.readOctetStringAsString(); |
| | | final AttributeDescription ad = readAttributeDescription(ads, schema); |
| | | final Attribute attribute = options.getAttributeFactory().newAttribute(ad); |
| | | |
| | | reader.readStartSet(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | attribute.add(reader.readOctetString()); |
| | | } |
| | | entry.addAttribute(attribute); |
| | | } finally { |
| | | reader.readEndSet(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | private void readAddRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | final Entry entry = LDAP.readEntry(reader, LDAP.OP_TYPE_ADD_REQUEST, options); |
| | | final AddRequest message = Requests.newAddRequest(entry); |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP ADD REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.addRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an add response |
| | | * protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readAddResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | Result message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_ADD_RESPONSE); |
| | | private void readAddResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_ADD_RESPONSE); |
| | | final Result message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP ADD RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.addResult(messageID, message); |
| | | } |
| | | |
| | | private AttributeDescription readAttributeDescription(final String attributeDescription, |
| | | final Schema schema) throws DecodeException { |
| | | try { |
| | | return AttributeDescription.valueOf(attributeDescription, schema); |
| | | } catch (final LocalizedIllegalArgumentException e) { |
| | | throw DecodeException.error(e.getMessageObject()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 read as an LDAP bind request |
| | | * protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readBindRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | reader.readStartSequence(OP_TYPE_BIND_REQUEST); |
| | | private void readBindRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_BIND_REQUEST); |
| | | try { |
| | | final int protocolVersion = (int) reader.readInteger(); |
| | | final String authName = reader.readOctetStringAsString(); |
| | | final byte authType = reader.peekType(); |
| | | final byte[] authBytes = reader.readOctetString(authType).toByteArray(); |
| | | |
| | | final GenericBindRequest request = |
| | | Requests.newGenericBindRequest(authName, authType, authBytes); |
| | | |
| | | readControls(request); |
| | | |
| | | IO_LOG.trace("DECODE LDAP BIND REQUEST(messageID={}, auth=0x{}, request={})", messageID, |
| | | byteToHex(request.getAuthenticationType()), request); |
| | | IO_LOG.trace("DECODE LDAP BIND REQUEST(messageID={}, auth=0x{}, request={})", |
| | | messageID, byteToHex(request.getAuthenticationType()), request); |
| | | |
| | | handler.bindRequest(messageID, protocolVersion, request); |
| | | } finally { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a bind response |
| | | * protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readBindResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | BindResult message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_BIND_RESPONSE); |
| | | private void readBindResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_BIND_RESPONSE); |
| | | final BindResult message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | Responses.newBindResult(resultCode).setMatchedDN(matchedDN) |
| | | .setDiagnosticMessage(diagnosticMessage); |
| | | readResponseReferrals(message); |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_SERVER_SASL_CREDENTIALS)) { |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_SERVER_SASL_CREDENTIALS)) { |
| | | message.setServerSASLCredentials(reader |
| | | .readOctetString(TYPE_SERVER_SASL_CREDENTIALS)); |
| | | .readOctetString(LDAP.TYPE_SERVER_SASL_CREDENTIALS)); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP BIND RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.bindResult(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP compare |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readCompareRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | CompareRequest message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_COMPARE_REQUEST); |
| | | private void readCompareRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_COMPARE_REQUEST); |
| | | final CompareRequest message; |
| | | try { |
| | | final String dnString = reader.readOctetStringAsString(); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(dnString); |
| | | final DN dn = readDN(dnString, schema); |
| | | |
| | | final DN dn = LDAP.readDN(dnString, schema); |
| | | reader.readStartSequence(); |
| | | try { |
| | | final String ads = reader.readOctetStringAsString(); |
| | | final AttributeDescription ad = readAttributeDescription(ads, schema); |
| | | final AttributeDescription ad = LDAP.readAttributeDescription(ads, schema); |
| | | final ByteString assertionValue = reader.readOctetString(); |
| | | message = Requests.newCompareRequest(dn, ad, assertionValue); |
| | | } finally { |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP COMPARE REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.compareRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a compare response |
| | | * protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readCompareResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | CompareResult message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_COMPARE_RESPONSE); |
| | | private void readCompareResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_COMPARE_RESPONSE); |
| | | final CompareResult message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP COMPARE RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.compareResult(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP control. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param request |
| | | * The decoded request to decode controls for. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readControl(final Request request) throws IOException { |
| | | String oid; |
| | | boolean isCritical; |
| | | ByteString value; |
| | | |
| | | private Control readControl() throws IOException { |
| | | reader.readStartSequence(); |
| | | try { |
| | | oid = reader.readOctetStringAsString(); |
| | | isCritical = false; |
| | | value = null; |
| | | final String oid = reader.readOctetStringAsString(); |
| | | final boolean isCritical; |
| | | if (reader.hasNextElement() && (reader.peekType() == ASN1.UNIVERSAL_BOOLEAN_TYPE)) { |
| | | isCritical = reader.readBoolean(); |
| | | } else { |
| | | isCritical = false; |
| | | } |
| | | final ByteString value; |
| | | if (reader.hasNextElement() && (reader.peekType() == ASN1.UNIVERSAL_OCTET_STRING_TYPE)) { |
| | | value = reader.readOctetString(); |
| | | } else { |
| | | value = null; |
| | | } |
| | | return GenericControl.newControl(oid, isCritical, value); |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | final Control c = GenericControl.newControl(oid, isCritical, value); |
| | | request.addControl(c); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP control. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param response |
| | | * The decoded message to decode controls for. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readControl(final Response response) throws IOException { |
| | | String oid; |
| | | boolean isCritical; |
| | | ByteString value; |
| | | |
| | | reader.readStartSequence(); |
| | | try { |
| | | oid = reader.readOctetStringAsString(); |
| | | isCritical = false; |
| | | value = null; |
| | | if (reader.hasNextElement() && (reader.peekType() == ASN1.UNIVERSAL_BOOLEAN_TYPE)) { |
| | | isCritical = reader.readBoolean(); |
| | | } |
| | | if (reader.hasNextElement() && (reader.peekType() == ASN1.UNIVERSAL_OCTET_STRING_TYPE)) { |
| | | value = reader.readOctetString(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | final Control c = GenericControl.newControl(oid, isCritical, value); |
| | | response.addControl(c); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a set of controls. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param request |
| | | * The decoded message to decode controls for. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readControls(final Request request) throws IOException { |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_CONTROL_SEQUENCE)) { |
| | | reader.readStartSequence(TYPE_CONTROL_SEQUENCE); |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_CONTROL_SEQUENCE)) { |
| | | reader.readStartSequence(LDAP.TYPE_CONTROL_SEQUENCE); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | readControl(request); |
| | | request.addControl(readControl()); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a set of controls. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param response |
| | | * The decoded message to decode controls for. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readControls(final Response response) |
| | | private void readControls(final Response response) throws IOException { |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_CONTROL_SEQUENCE)) { |
| | | reader.readStartSequence(LDAP.TYPE_CONTROL_SEQUENCE); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | response.addControl(readControl()); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void readDeleteRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_CONTROL_SEQUENCE)) { |
| | | reader.readStartSequence(TYPE_CONTROL_SEQUENCE); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | readControl(response); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP delete |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readDeleteRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | final String dnString = reader.readOctetStringAsString(OP_TYPE_DELETE_REQUEST); |
| | | final String dnString = reader.readOctetStringAsString(LDAP.OP_TYPE_DELETE_REQUEST); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(dnString); |
| | | final DN dn = readDN(dnString, schema); |
| | | final DN dn = LDAP.readDN(dnString, schema); |
| | | final DeleteRequest message = Requests.newDeleteRequest(dn); |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP DELETE REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.deleteRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a delete response |
| | | * protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readDeleteResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | Result message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_DELETE_RESPONSE); |
| | | private void readDeleteResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_DELETE_RESPONSE); |
| | | final Result message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP DELETE RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.deleteResult(messageID, message); |
| | | } |
| | | |
| | | private DN readDN(final String dn, final Schema schema) throws DecodeException { |
| | | private void readExtendedRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_EXTENDED_REQUEST); |
| | | final GenericExtendedRequest message; |
| | | try { |
| | | return DN.valueOf(dn, schema); |
| | | } catch (final LocalizedIllegalArgumentException e) { |
| | | throw DecodeException.error(e.getMessageObject()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP extended |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readExtendedRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | String oid; |
| | | ByteString value; |
| | | |
| | | reader.readStartSequence(OP_TYPE_EXTENDED_REQUEST); |
| | | try { |
| | | oid = reader.readOctetStringAsString(TYPE_EXTENDED_REQUEST_OID); |
| | | value = null; |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_EXTENDED_REQUEST_VALUE)) { |
| | | value = reader.readOctetString(TYPE_EXTENDED_REQUEST_VALUE); |
| | | final String oid = reader.readOctetStringAsString(LDAP.TYPE_EXTENDED_REQUEST_OID); |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_EXTENDED_REQUEST_VALUE)) { |
| | | final ByteString value = reader.readOctetString(LDAP.TYPE_EXTENDED_REQUEST_VALUE); |
| | | message = Requests.newGenericExtendedRequest(oid, value); |
| | | } else { |
| | | message = Requests.newGenericExtendedRequest(oid, null); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | final GenericExtendedRequest message = Requests.newGenericExtendedRequest(oid, value); |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP EXTENDED REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.extendedRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a extended |
| | | * response protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readExtendedResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | |
| | | GenericExtendedResult message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_EXTENDED_RESPONSE); |
| | | private void readExtendedResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_EXTENDED_RESPONSE); |
| | | final GenericExtendedResult message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | Responses.newGenericExtendedResult(resultCode).setMatchedDN(matchedDN) |
| | | .setDiagnosticMessage(diagnosticMessage); |
| | | readResponseReferrals(message); |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_EXTENDED_RESPONSE_OID)) { |
| | | message.setOID(reader.readOctetStringAsString(TYPE_EXTENDED_RESPONSE_OID)); |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_EXTENDED_RESPONSE_OID)) { |
| | | message.setOID(reader.readOctetStringAsString(LDAP.TYPE_EXTENDED_RESPONSE_OID)); |
| | | } |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_EXTENDED_RESPONSE_VALUE)) { |
| | | message.setValue(reader.readOctetString(TYPE_EXTENDED_RESPONSE_VALUE)); |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_EXTENDED_RESPONSE_VALUE)) { |
| | | message.setValue(reader.readOctetString(LDAP.TYPE_EXTENDED_RESPONSE_VALUE)); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP EXTENDED RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.extendedResult(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP |
| | | * intermediate response protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readIntermediateResponse(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | GenericIntermediateResponse message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_INTERMEDIATE_RESPONSE); |
| | | private void readIntermediateResponse(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_INTERMEDIATE_RESPONSE); |
| | | final GenericIntermediateResponse message; |
| | | try { |
| | | message = Responses.newGenericIntermediateResponse(); |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_INTERMEDIATE_RESPONSE_OID)) { |
| | | message.setOID(reader.readOctetStringAsString(TYPE_INTERMEDIATE_RESPONSE_OID)); |
| | | if (reader.hasNextElement() |
| | | && (reader.peekType() == LDAP.TYPE_INTERMEDIATE_RESPONSE_OID)) { |
| | | message.setOID(reader.readOctetStringAsString(LDAP.TYPE_INTERMEDIATE_RESPONSE_OID)); |
| | | } |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_INTERMEDIATE_RESPONSE_VALUE)) { |
| | | message.setValue(reader.readOctetString(TYPE_INTERMEDIATE_RESPONSE_VALUE)); |
| | | if (reader.hasNextElement() |
| | | && (reader.peekType() == LDAP.TYPE_INTERMEDIATE_RESPONSE_VALUE)) { |
| | | message.setValue(reader.readOctetString(LDAP.TYPE_INTERMEDIATE_RESPONSE_VALUE)); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP INTERMEDIATE RESPONSE(messageID={}, response={})", |
| | | messageID, message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP INTERMEDIATE RESPONSE(messageID={}, response={})", messageID, |
| | | message); |
| | | handler.intermediateResponse(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a modify DN |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readModifyDNRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | ModifyDNRequest message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_MODIFY_DN_REQUEST); |
| | | private void readModifyDNRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_MODIFY_DN_REQUEST); |
| | | final ModifyDNRequest message; |
| | | try { |
| | | final String dnString = reader.readOctetStringAsString(); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(dnString); |
| | | final DN dn = readDN(dnString, schema); |
| | | |
| | | final DN dn = LDAP.readDN(dnString, schema); |
| | | final String newRDNString = reader.readOctetStringAsString(); |
| | | final RDN newRDN = readRDN(newRDNString, schema); |
| | | |
| | | message = Requests.newModifyDNRequest(dn, newRDN); |
| | | |
| | | message.setDeleteOldRDN(reader.readBoolean()); |
| | | |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_MODIFY_DN_NEW_SUPERIOR)) { |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_MODIFY_DN_NEW_SUPERIOR)) { |
| | | final String newSuperiorString = |
| | | reader.readOctetStringAsString(TYPE_MODIFY_DN_NEW_SUPERIOR); |
| | | final DN newSuperior = readDN(newSuperiorString, schema); |
| | | reader.readOctetStringAsString(LDAP.TYPE_MODIFY_DN_NEW_SUPERIOR); |
| | | final DN newSuperior = LDAP.readDN(newSuperiorString, schema); |
| | | message.setNewSuperior(newSuperior); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP MODIFY DN REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.modifyDNRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a modify DN |
| | | * response protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readModifyDNResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | Result message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_MODIFY_DN_RESPONSE); |
| | | private void readModifyDNResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_MODIFY_DN_RESPONSE); |
| | | final Result message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE MODIFY DN RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.modifyDNResult(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP modify |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readModifyRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | ModifyRequest message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_MODIFY_REQUEST); |
| | | private void readModifyRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_MODIFY_REQUEST); |
| | | final ModifyRequest message; |
| | | try { |
| | | final String dnString = reader.readOctetStringAsString(); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(dnString); |
| | | final DN dn = readDN(dnString, schema); |
| | | final DN dn = LDAP.readDN(dnString, schema); |
| | | message = Requests.newModifyRequest(dn); |
| | | |
| | | reader.readStartSequence(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | |
| | | reader.readStartSequence(); |
| | | try { |
| | | final String ads = reader.readOctetStringAsString(); |
| | | final AttributeDescription ad = readAttributeDescription(ads, schema); |
| | | final AttributeDescription ad = |
| | | LDAP.readAttributeDescription(ads, schema); |
| | | final Attribute attribute = |
| | | options.getAttributeFactory().newAttribute(ad); |
| | | |
| | | reader.readStartSet(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP MODIFY REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.modifyRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a modify response |
| | | * protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readModifyResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | Result message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_MODIFY_RESPONSE); |
| | | private void readModifyResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_MODIFY_RESPONSE); |
| | | final Result message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP MODIFY RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.modifyResult(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP protocol |
| | | * op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readProtocolOp(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | private void readProtocolOp(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | final byte type = reader.peekType(); |
| | | |
| | | switch (type) { |
| | | case OP_TYPE_UNBIND_REQUEST: // 0x42 |
| | | case LDAP.OP_TYPE_UNBIND_REQUEST: // 0x42 |
| | | readUnbindRequest(messageID, handler); |
| | | break; |
| | | case 0x43: // 0x43 |
| | | case 0x44: // 0x44 |
| | | case 0x45: // 0x45 |
| | | case 0x46: // 0x46 |
| | | case 0x47: // 0x47 |
| | | case 0x48: // 0x48 |
| | | case 0x49: // 0x49 |
| | | handler.unrecognizedMessage(messageID, type, reader.readOctetString(type)); |
| | | break; |
| | | case OP_TYPE_DELETE_REQUEST: // 0x4A |
| | | case LDAP.OP_TYPE_DELETE_REQUEST: // 0x4A |
| | | readDeleteRequest(messageID, handler); |
| | | break; |
| | | case 0x4B: // 0x4B |
| | | case 0x4C: // 0x4C |
| | | case 0x4D: // 0x4D |
| | | case 0x4E: // 0x4E |
| | | case 0x4F: // 0x4F |
| | | handler.unrecognizedMessage(messageID, type, reader.readOctetString(type)); |
| | | break; |
| | | case OP_TYPE_ABANDON_REQUEST: // 0x50 |
| | | case LDAP.OP_TYPE_ABANDON_REQUEST: // 0x50 |
| | | readAbandonRequest(messageID, handler); |
| | | break; |
| | | case 0x51: // 0x51 |
| | | case 0x52: // 0x52 |
| | | case 0x53: // 0x53 |
| | | case 0x54: // 0x54 |
| | | case 0x55: // 0x55 |
| | | case 0x56: // 0x56 |
| | | case 0x57: // 0x57 |
| | | case 0x58: // 0x58 |
| | | case 0x59: // 0x59 |
| | | case 0x5A: // 0x5A |
| | | case 0x5B: // 0x5B |
| | | case 0x5C: // 0x5C |
| | | case 0x5D: // 0x5D |
| | | case 0x5E: // 0x5E |
| | | case 0x5F: // 0x5F |
| | | handler.unrecognizedMessage(messageID, type, reader.readOctetString(type)); |
| | | break; |
| | | case OP_TYPE_BIND_REQUEST: // 0x60 |
| | | case LDAP.OP_TYPE_BIND_REQUEST: // 0x60 |
| | | readBindRequest(messageID, handler); |
| | | break; |
| | | case OP_TYPE_BIND_RESPONSE: // 0x61 |
| | | case LDAP.OP_TYPE_BIND_RESPONSE: // 0x61 |
| | | readBindResult(messageID, handler); |
| | | break; |
| | | case 0x62: // 0x62 |
| | | handler.unrecognizedMessage(messageID, type, reader.readOctetString(type)); |
| | | break; |
| | | case OP_TYPE_SEARCH_REQUEST: // 0x63 |
| | | case LDAP.OP_TYPE_SEARCH_REQUEST: // 0x63 |
| | | readSearchRequest(messageID, handler); |
| | | break; |
| | | case OP_TYPE_SEARCH_RESULT_ENTRY: // 0x64 |
| | | case LDAP.OP_TYPE_SEARCH_RESULT_ENTRY: // 0x64 |
| | | readSearchResultEntry(messageID, handler); |
| | | break; |
| | | case OP_TYPE_SEARCH_RESULT_DONE: // 0x65 |
| | | case LDAP.OP_TYPE_SEARCH_RESULT_DONE: // 0x65 |
| | | readSearchResult(messageID, handler); |
| | | break; |
| | | case OP_TYPE_MODIFY_REQUEST: // 0x66 |
| | | case LDAP.OP_TYPE_MODIFY_REQUEST: // 0x66 |
| | | readModifyRequest(messageID, handler); |
| | | break; |
| | | case OP_TYPE_MODIFY_RESPONSE: // 0x67 |
| | | case LDAP.OP_TYPE_MODIFY_RESPONSE: // 0x67 |
| | | readModifyResult(messageID, handler); |
| | | break; |
| | | case OP_TYPE_ADD_REQUEST: // 0x68 |
| | | case LDAP.OP_TYPE_ADD_REQUEST: // 0x68 |
| | | readAddRequest(messageID, handler); |
| | | break; |
| | | case OP_TYPE_ADD_RESPONSE: // 0x69 |
| | | case LDAP.OP_TYPE_ADD_RESPONSE: // 0x69 |
| | | readAddResult(messageID, handler); |
| | | break; |
| | | case 0x6A: // 0x6A |
| | | handler.unrecognizedMessage(messageID, type, reader.readOctetString(type)); |
| | | break; |
| | | case OP_TYPE_DELETE_RESPONSE: // 0x6B |
| | | case LDAP.OP_TYPE_DELETE_RESPONSE: // 0x6B |
| | | readDeleteResult(messageID, handler); |
| | | break; |
| | | case OP_TYPE_MODIFY_DN_REQUEST: // 0x6C |
| | | case LDAP.OP_TYPE_MODIFY_DN_REQUEST: // 0x6C |
| | | readModifyDNRequest(messageID, handler); |
| | | break; |
| | | case OP_TYPE_MODIFY_DN_RESPONSE: // 0x6D |
| | | case LDAP.OP_TYPE_MODIFY_DN_RESPONSE: // 0x6D |
| | | readModifyDNResult(messageID, handler); |
| | | break; |
| | | case OP_TYPE_COMPARE_REQUEST: // 0x6E |
| | | case LDAP.OP_TYPE_COMPARE_REQUEST: // 0x6E |
| | | readCompareRequest(messageID, handler); |
| | | break; |
| | | case OP_TYPE_COMPARE_RESPONSE: // 0x6F |
| | | case LDAP.OP_TYPE_COMPARE_RESPONSE: // 0x6F |
| | | readCompareResult(messageID, handler); |
| | | break; |
| | | case 0x70: // 0x70 |
| | | case 0x71: // 0x71 |
| | | case 0x72: // 0x72 |
| | | handler.unrecognizedMessage(messageID, type, reader.readOctetString(type)); |
| | | break; |
| | | case OP_TYPE_SEARCH_RESULT_REFERENCE: // 0x73 |
| | | case LDAP.OP_TYPE_SEARCH_RESULT_REFERENCE: // 0x73 |
| | | readSearchResultReference(messageID, handler); |
| | | break; |
| | | case 0x74: // 0x74 |
| | | case 0x75: // 0x75 |
| | | case 0x76: // 0x76 |
| | | handler.unrecognizedMessage(messageID, type, reader.readOctetString(type)); |
| | | break; |
| | | case OP_TYPE_EXTENDED_REQUEST: // 0x77 |
| | | case LDAP.OP_TYPE_EXTENDED_REQUEST: // 0x77 |
| | | readExtendedRequest(messageID, handler); |
| | | break; |
| | | case OP_TYPE_EXTENDED_RESPONSE: // 0x78 |
| | | case LDAP.OP_TYPE_EXTENDED_RESPONSE: // 0x78 |
| | | readExtendedResult(messageID, handler); |
| | | break; |
| | | case OP_TYPE_INTERMEDIATE_RESPONSE: // 0x79 |
| | | case LDAP.OP_TYPE_INTERMEDIATE_RESPONSE: // 0x79 |
| | | readIntermediateResponse(messageID, handler); |
| | | break; |
| | | default: |
| | |
| | | } |
| | | } |
| | | |
| | | private void readResponseReferrals(final Result message) |
| | | throws IOException { |
| | | if (reader.hasNextElement() && (reader.peekType() == TYPE_REFERRAL_SEQUENCE)) { |
| | | reader.readStartSequence(TYPE_REFERRAL_SEQUENCE); |
| | | private void readResponseReferrals(final Result message) throws IOException { |
| | | if (reader.hasNextElement() && (reader.peekType() == LDAP.TYPE_REFERRAL_SEQUENCE)) { |
| | | reader.readStartSequence(LDAP.TYPE_REFERRAL_SEQUENCE); |
| | | try { |
| | | // Should have at least 1. |
| | | do { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP search |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readSearchRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | SearchRequest message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_SEARCH_REQUEST); |
| | | private void readSearchRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_SEARCH_REQUEST); |
| | | final SearchRequest message; |
| | | try { |
| | | final String baseDNString = reader.readOctetStringAsString(); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(baseDNString); |
| | | final DN baseDN = readDN(baseDNString, schema); |
| | | |
| | | final DN baseDN = LDAP.readDN(baseDNString, schema); |
| | | final int scopeIntValue = reader.readEnumerated(); |
| | | final SearchScope scope = SearchScope.valueOf(scopeIntValue); |
| | | if (scope == null) { |
| | | throw DecodeException.error(ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_SCOPE |
| | | .get(scopeIntValue)); |
| | | } |
| | | |
| | | final int dereferencePolicyIntValue = reader.readEnumerated(); |
| | | final DereferenceAliasesPolicy dereferencePolicy = |
| | | DereferenceAliasesPolicy.valueOf(dereferencePolicyIntValue); |
| | |
| | | throw DecodeException.error(ERR_LDAP_SEARCH_REQUEST_DECODE_INVALID_DEREF |
| | | .get(dereferencePolicyIntValue)); |
| | | } |
| | | |
| | | final int sizeLimit = (int) reader.readInteger(); |
| | | final int timeLimit = (int) reader.readInteger(); |
| | | final boolean typesOnly = reader.readBoolean(); |
| | | final Filter filter = LDAPUtils.decodeFilter(reader); |
| | | |
| | | final Filter filter = LDAP.readFilter(reader); |
| | | message = Requests.newSearchRequest(baseDN, scope, filter); |
| | | message.setDereferenceAliasesPolicy(dereferencePolicy); |
| | | try { |
| | |
| | | throw DecodeException.error(e.getMessageObject()); |
| | | } |
| | | message.setTypesOnly(typesOnly); |
| | | |
| | | reader.readStartSequence(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP SEARCH REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.searchRequest(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a search result |
| | | * done protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readSearchResult(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | |
| | | Result message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_SEARCH_RESULT_DONE); |
| | | private void readSearchResult(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_SEARCH_RESULT_DONE); |
| | | final Result message; |
| | | try { |
| | | final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); |
| | | final String matchedDN = reader.readOctetStringAsString(); |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP SEARCH RESULT(messageID={}, result={})", messageID, message); |
| | | |
| | | handler.searchResult(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as an LDAP search |
| | | * result entry protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readSearchResultEntry(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | Entry entry; |
| | | |
| | | reader.readStartSequence(OP_TYPE_SEARCH_RESULT_ENTRY); |
| | | try { |
| | | final String dnString = reader.readOctetStringAsString(); |
| | | final Schema schema = options.getSchemaResolver().resolveSchema(dnString); |
| | | final DN dn = readDN(dnString, schema); |
| | | entry = options.getEntryFactory().newEntry(dn); |
| | | |
| | | reader.readStartSequence(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | reader.readStartSequence(); |
| | | try { |
| | | final String ads = reader.readOctetStringAsString(); |
| | | final AttributeDescription ad = readAttributeDescription(ads, schema); |
| | | final Attribute attribute = options.getAttributeFactory().newAttribute(ad); |
| | | |
| | | reader.readStartSet(); |
| | | try { |
| | | while (reader.hasNextElement()) { |
| | | attribute.add(reader.readOctetString()); |
| | | } |
| | | entry.addAttribute(attribute); |
| | | } finally { |
| | | reader.readEndSet(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | private void readSearchResultEntry(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | final Entry entry = LDAP.readEntry(reader, LDAP.OP_TYPE_SEARCH_RESULT_ENTRY, options); |
| | | final SearchResultEntry message = Responses.newSearchResultEntry(entry); |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP SEARCH RESULT ENTRY(messageID={}, entry={})", messageID, message); |
| | | |
| | | handler.searchResultEntry(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 reader as a search result |
| | | * reference protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readSearchResultReference(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | SearchResultReference message; |
| | | |
| | | reader.readStartSequence(OP_TYPE_SEARCH_RESULT_REFERENCE); |
| | | private void readSearchResultReference(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readStartSequence(LDAP.OP_TYPE_SEARCH_RESULT_REFERENCE); |
| | | final SearchResultReference message; |
| | | try { |
| | | message = Responses.newSearchResultReference(reader.readOctetStringAsString()); |
| | | while (reader.hasNextElement()) { |
| | |
| | | } finally { |
| | | reader.readEndSequence(); |
| | | } |
| | | |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP SEARCH RESULT REFERENCE(messageID={}, result={})", |
| | | messageID, message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP SEARCH RESULT REFERENCE(messageID={}, result={})", messageID, |
| | | message); |
| | | handler.searchResultReference(messageID, message); |
| | | } |
| | | |
| | | /** |
| | | * Decodes the elements from the provided ASN.1 read as an LDAP unbind |
| | | * request protocol op. |
| | | * |
| | | * @param reader |
| | | * The ASN.1 reader |
| | | * @param messageID |
| | | * The decoded message ID for this message. |
| | | * @param handler |
| | | * The <code>LDAPMessageHandler</code> that will handle this |
| | | * decoded message. |
| | | * @throws IOException |
| | | * If an error occurred while reading bytes to decode. |
| | | */ |
| | | private void readUnbindRequest(final int messageID, |
| | | final LDAPMessageHandler handler) throws IOException { |
| | | UnbindRequest message; |
| | | reader.readNull(OP_TYPE_UNBIND_REQUEST); |
| | | message = Requests.newUnbindRequest(); |
| | | |
| | | private void readUnbindRequest(final int messageID, final LDAPMessageHandler handler) |
| | | throws IOException { |
| | | reader.readNull(LDAP.OP_TYPE_UNBIND_REQUEST); |
| | | final UnbindRequest message = Requests.newUnbindRequest(); |
| | | readControls(message); |
| | | |
| | | IO_LOG.trace("DECODE LDAP UNBIND REQUEST(messageID={}, request={})", messageID, message); |
| | | |
| | | handler.unbindRequest(messageID, message); |
| | | } |
| | | } |
| | |
| | | |
| | | package org.forgerock.opendj.io; |
| | | |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.*; |
| | | import static com.forgerock.opendj.util.StaticUtils.IO_LOG; |
| | | import static com.forgerock.opendj.util.StaticUtils.byteToHex; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.List; |
| | | |
| | | import org.forgerock.opendj.ldap.Attribute; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DN; |
| | | import org.forgerock.opendj.ldap.Modification; |
| | |
| | | import org.forgerock.opendj.ldap.requests.GenericBindRequest; |
| | | import org.forgerock.opendj.ldap.requests.ModifyDNRequest; |
| | | import org.forgerock.opendj.ldap.requests.ModifyRequest; |
| | | import org.forgerock.opendj.ldap.requests.Request; |
| | | import org.forgerock.opendj.ldap.requests.SearchRequest; |
| | | import org.forgerock.opendj.ldap.requests.UnbindRequest; |
| | | import org.forgerock.opendj.ldap.responses.BindResult; |
| | | import org.forgerock.opendj.ldap.responses.CompareResult; |
| | | import org.forgerock.opendj.ldap.responses.ExtendedResult; |
| | | import org.forgerock.opendj.ldap.responses.IntermediateResponse; |
| | | import org.forgerock.opendj.ldap.responses.Response; |
| | | import org.forgerock.opendj.ldap.responses.Result; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultReference; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPUtils; |
| | | import com.forgerock.opendj.util.StaticUtils; |
| | | |
| | | /** |
| | | * Responsible for writing LDAP messages. |
| | | * Writes LDAP messages to an underlying ASN.1 writer. |
| | | * <p> |
| | | * Methods for creating {@link LDAPWriter}s are provided in the {@link LDAP} |
| | | * class. |
| | | * |
| | | * @param <W> |
| | | * type of ASN1 writer used to encode elements |
| | | * The type of ASN.1 writer used for encoding elements. |
| | | */ |
| | | public final class LDAPWriter<W extends ASN1Writer> { |
| | | // @Checkstyle:ignore AvoidNestedBlocks |
| | | |
| | | private final W writer; |
| | | |
| | | /** |
| | | * Creates a writer based on the provided ASN1 writer. |
| | | * |
| | | * @param asn1Writer |
| | | * writer to encode ASN.1 elements |
| | | */ |
| | | public LDAPWriter(W asn1Writer) { |
| | | LDAPWriter(final W asn1Writer) { |
| | | this.writer = asn1Writer; |
| | | } |
| | | |
| | | /** |
| | | * Returns the ASN1 writer used to encode elements. |
| | | * Returns the ASN.1 writer to which LDAP messages will be written. |
| | | * |
| | | * @return the ASN1 writer |
| | | * @return The ASN.1 writer to which LDAP messages will be written. |
| | | */ |
| | | public W getASN1Writer() { |
| | | return writer; |
| | | } |
| | | |
| | | /** |
| | | * Write the provided control. |
| | | * Writes the provided abandon request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeAbandonRequest(final int messageID, final AbandonRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP ABANDON REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeInteger(LDAP.OP_TYPE_ABANDON_REQUEST, request.getRequestID()); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided add request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeAddRequest(final int messageID, final AddRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP ADD REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | LDAP.writeEntry(writer, LDAP.OP_TYPE_ADD_REQUEST, request); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided add result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeAddResult(final int messageID, final Result result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP ADD RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_ADD_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | } |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided bind request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param version |
| | | * The requested LDAP protocol version. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeBindRequest(final int messageID, final int version, |
| | | final GenericBindRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP BIND REQUEST(messageID={}, auth=0x{}, request={})", messageID, |
| | | byteToHex(request.getAuthenticationType()), request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_BIND_REQUEST); |
| | | { |
| | | writer.writeInteger(version); |
| | | writer.writeOctetString(request.getName()); |
| | | writer.writeOctetString(request.getAuthenticationType(), request |
| | | .getAuthenticationValue()); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided bind result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeBindResult(final int messageID, final BindResult result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP BIND RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_BIND_RESPONSE, result); |
| | | { |
| | | final ByteString saslCredentials = result.getServerSASLCredentials(); |
| | | if (saslCredentials != null && saslCredentials.length() > 0) { |
| | | writer.writeOctetString(LDAP.TYPE_SERVER_SASL_CREDENTIALS, result |
| | | .getServerSASLCredentials()); |
| | | } |
| | | } |
| | | writeResultFooter(writer); |
| | | } |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided compare request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeCompareRequest(final int messageID, final CompareRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP COMPARE REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_COMPARE_REQUEST); |
| | | { |
| | | writer.writeOctetString(request.getName().toString()); |
| | | writer.writeStartSequence(); |
| | | { |
| | | writer.writeOctetString(request.getAttributeDescription().toString()); |
| | | writer.writeOctetString(request.getAssertionValue()); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided compare result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeCompareResult(final int messageID, final CompareResult result) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP COMPARE RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_COMPARE_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | } |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided control. |
| | | * |
| | | * @param control |
| | | * the control |
| | | * The control. |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeControl(final Control control) |
| | | throws IOException { |
| | | public void writeControl(final Control control) throws IOException { |
| | | writer.writeStartSequence(); |
| | | writer.writeOctetString(control.getOID()); |
| | | if (control.isCritical()) { |
| | | writer.writeBoolean(control.isCritical()); |
| | | } |
| | | if (control.getValue() != null) { |
| | | writer.writeOctetString(control.getValue()); |
| | | { |
| | | writer.writeOctetString(control.getOID()); |
| | | if (control.isCritical()) { |
| | | writer.writeBoolean(control.isCritical()); |
| | | } |
| | | if (control.getValue() != null) { |
| | | writer.writeOctetString(control.getValue()); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided entry. |
| | | * Writes the provided delete request. |
| | | * |
| | | * @param searchResultEntry |
| | | * entry |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeEntry(final SearchResultEntry searchResultEntry) throws IOException { |
| | | writer.writeStartSequence(OP_TYPE_SEARCH_RESULT_ENTRY); |
| | | writer.writeOctetString(searchResultEntry.getName().toString()); |
| | | |
| | | writer.writeStartSequence(); |
| | | for (final Attribute attr : searchResultEntry.getAllAttributes()) { |
| | | writeAttribute(attr); |
| | | public void writeDeleteRequest(final int messageID, final DeleteRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP DELETE REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeOctetString(LDAP.OP_TYPE_DELETE_REQUEST, request.getName().toString()); |
| | | } |
| | | writer.writeEndSequence(); |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | private void writeAttribute(final Attribute attribute) |
| | | throws IOException { |
| | | writer.writeStartSequence(); |
| | | writer.writeOctetString(attribute.getAttributeDescriptionAsString()); |
| | | |
| | | writer.writeStartSet(); |
| | | for (final ByteString value : attribute) { |
| | | writer.writeOctetString(value); |
| | | /** |
| | | * Writes the provided delete result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeDeleteResult(final int messageID, final Result result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP DELETE RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_DELETE_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | } |
| | | writer.writeEndSequence(); |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | private void writeChange(final Modification change) |
| | | /** |
| | | * Writes the provided extended request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeExtendedRequest(final int messageID, final ExtendedRequest<?> request) |
| | | throws IOException { |
| | | writer.writeStartSequence(); |
| | | writer.writeEnumerated(change.getModificationType().intValue()); |
| | | writeAttribute(change.getAttribute()); |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | private void writeMessageFooter(final Request request) |
| | | throws IOException { |
| | | final List<Control> controls = request.getControls(); |
| | | if (!controls.isEmpty()) { |
| | | writer.writeStartSequence(TYPE_CONTROL_SEQUENCE); |
| | | for (final Control control : controls) { |
| | | writeControl(control); |
| | | IO_LOG.trace("ENCODE LDAP EXTENDED REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_EXTENDED_REQUEST); |
| | | { |
| | | writer.writeOctetString(LDAP.TYPE_EXTENDED_REQUEST_OID, request.getOID()); |
| | | final ByteString requestValue = request.getValue(); |
| | | if (requestValue != null) { |
| | | writer.writeOctetString(LDAP.TYPE_EXTENDED_REQUEST_VALUE, requestValue); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | private void writeMessageFooter(final Response response) |
| | | /** |
| | | * Writes the provided extended result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeExtendedResult(final int messageID, final ExtendedResult result) |
| | | throws IOException { |
| | | final List<Control> controls = response.getControls(); |
| | | if (!controls.isEmpty()) { |
| | | writer.writeStartSequence(TYPE_CONTROL_SEQUENCE); |
| | | for (final Control control : controls) { |
| | | writeControl(control); |
| | | IO_LOG.trace("ENCODE LDAP EXTENDED RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_EXTENDED_RESPONSE, result); |
| | | { |
| | | final String responseName = result.getOID(); |
| | | if (responseName != null) { |
| | | writer.writeOctetString(LDAP.TYPE_EXTENDED_RESPONSE_OID, responseName); |
| | | } |
| | | final ByteString responseValue = result.getValue(); |
| | | if (responseValue != null) { |
| | | writer.writeOctetString(LDAP.TYPE_EXTENDED_RESPONSE_VALUE, responseValue); |
| | | } |
| | | } |
| | | writeResultFooter(writer); |
| | | } |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided intermediate response. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param response |
| | | * The response. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeIntermediateResponse(final int messageID, final IntermediateResponse response) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP INTERMEDIATE RESPONSE(messageID={}, response={})", messageID, |
| | | response); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_INTERMEDIATE_RESPONSE); |
| | | { |
| | | final String responseName = response.getOID(); |
| | | if (responseName != null) { |
| | | writer.writeOctetString(LDAP.TYPE_INTERMEDIATE_RESPONSE_OID, response.getOID()); |
| | | } |
| | | final ByteString responseValue = response.getValue(); |
| | | if (responseValue != null) { |
| | | writer.writeOctetString(LDAP.TYPE_INTERMEDIATE_RESPONSE_VALUE, response |
| | | .getValue()); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writeMessageFooter(response.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided modify DN request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeModifyDNRequest(final int messageID, final ModifyDNRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY DN REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_MODIFY_DN_REQUEST); |
| | | { |
| | | writer.writeOctetString(request.getName().toString()); |
| | | writer.writeOctetString(request.getNewRDN().toString()); |
| | | writer.writeBoolean(request.isDeleteOldRDN()); |
| | | final DN newSuperior = request.getNewSuperior(); |
| | | if (newSuperior != null) { |
| | | writer.writeOctetString(LDAP.TYPE_MODIFY_DN_NEW_SUPERIOR, newSuperior |
| | | .toString()); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided modify DN result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeModifyDNResult(final int messageID, final Result result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY DN RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_MODIFY_DN_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | } |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided modify request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeModifyRequest(final int messageID, final ModifyRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_MODIFY_REQUEST); |
| | | { |
| | | writer.writeOctetString(request.getName().toString()); |
| | | writer.writeStartSequence(); |
| | | { |
| | | for (final Modification change : request.getModifications()) { |
| | | writeChange(change); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided extended result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeModifyResult(final int messageID, final Result result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_MODIFY_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | } |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided search request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeSearchRequest(final int messageID, final SearchRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_SEARCH_REQUEST); |
| | | { |
| | | writer.writeOctetString(request.getName().toString()); |
| | | writer.writeEnumerated(request.getScope().intValue()); |
| | | writer.writeEnumerated(request.getDereferenceAliasesPolicy().intValue()); |
| | | writer.writeInteger(request.getSizeLimit()); |
| | | writer.writeInteger(request.getTimeLimit()); |
| | | writer.writeBoolean(request.isTypesOnly()); |
| | | LDAP.writeFilter(writer, request.getFilter()); |
| | | writer.writeStartSequence(); |
| | | { |
| | | for (final String attribute : request.getAttributes()) { |
| | | writer.writeOctetString(attribute); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided search result. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param result |
| | | * The result. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeSearchResult(final int messageID, final Result result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writeResultHeader(LDAP.OP_TYPE_SEARCH_RESULT_DONE, result); |
| | | writeResultFooter(writer); |
| | | } |
| | | writeMessageFooter(result.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided search result entry. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param entry |
| | | * The entry. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeSearchResultEntry(final int messageID, final SearchResultEntry entry) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH RESULT ENTRY(messageID={}, entry={})", messageID, entry); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | LDAP.writeEntry(writer, LDAP.OP_TYPE_SEARCH_RESULT_ENTRY, entry); |
| | | } |
| | | writeMessageFooter(entry.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided search result reference. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param reference |
| | | * The reference. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeSearchResultReference(final int messageID, |
| | | final SearchResultReference reference) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH RESULT REFERENCE(messageID={}, reference={})", messageID, |
| | | reference); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeStartSequence(LDAP.OP_TYPE_SEARCH_RESULT_REFERENCE); |
| | | { |
| | | for (final String url : reference.getURIs()) { |
| | | writer.writeOctetString(url); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writeMessageFooter(reference.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes the provided unbind request. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param request |
| | | * The request. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeUnbindRequest(final int messageID, final UnbindRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP UNBIND REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeNull(LDAP.OP_TYPE_UNBIND_REQUEST); |
| | | } |
| | | writeMessageFooter(request.getControls()); |
| | | } |
| | | |
| | | /** |
| | | * Writes a message with the provided id, tag and content bytes. |
| | | * |
| | | * @param messageID |
| | | * The LDAP message ID. |
| | | * @param messageTag |
| | | * The LDAP message type. |
| | | * @param messageBytes |
| | | * The contents of the LDAP message. |
| | | * @throws IOException |
| | | * If an unexpected IO error occurred. |
| | | */ |
| | | public void writeUnrecognizedMessage(final int messageID, final byte messageTag, |
| | | final ByteString messageBytes) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP UNKNOWN MESSAGE(messageID={}, messageTag={}, messageBytes={})", |
| | | messageID, StaticUtils.byteToHex(messageTag), messageBytes); |
| | | writeMessageHeader(messageID); |
| | | { |
| | | writer.writeOctetString(messageTag, messageBytes); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | private void writeMessageHeader(final int messageID) |
| | | throws IOException { |
| | | private void writeChange(final Modification change) throws IOException { |
| | | writer.writeStartSequence(); |
| | | { |
| | | writer.writeEnumerated(change.getModificationType().intValue()); |
| | | LDAP.writeAttribute(writer, change.getAttribute()); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | private void writeMessageFooter(final List<Control> controls) throws IOException { |
| | | if (!controls.isEmpty()) { |
| | | writer.writeStartSequence(LDAP.TYPE_CONTROL_SEQUENCE); |
| | | { |
| | | for (final Control control : controls) { |
| | | writeControl(control); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | private void writeMessageHeader(final int messageID) throws IOException { |
| | | writer.writeStartSequence(); |
| | | writer.writeInteger(messageID); |
| | | } |
| | |
| | | writer.writeEndSequence(); |
| | | } |
| | | |
| | | private void writeResultHeader(final byte typeTag, |
| | | final Result rawMessage) throws IOException { |
| | | private void writeResultHeader(final byte typeTag, final Result rawMessage) throws IOException { |
| | | writer.writeStartSequence(typeTag); |
| | | writer.writeEnumerated(rawMessage.getResultCode().intValue()); |
| | | writer.writeOctetString(rawMessage.getMatchedDN()); |
| | | writer.writeOctetString(rawMessage.getDiagnosticMessage()); |
| | | |
| | | final List<String> referralURIs = rawMessage.getReferralURIs(); |
| | | if (!referralURIs.isEmpty()) { |
| | | writer.writeStartSequence(TYPE_REFERRAL_SEQUENCE); |
| | | for (final String s : referralURIs) { |
| | | writer.writeOctetString(s); |
| | | writer.writeStartSequence(LDAP.TYPE_REFERRAL_SEQUENCE); |
| | | { |
| | | for (final String s : referralURIs) { |
| | | writer.writeOctetString(s); |
| | | } |
| | | } |
| | | writer.writeEndSequence(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Write the provided abandon request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeAbandonRequest(final int messageID, final AbandonRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP ABANDON REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeInteger(OP_TYPE_ABANDON_REQUEST, request.getRequestID()); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided add request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeAddRequest(final int messageID, final AddRequest request) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP ADD REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_ADD_REQUEST); |
| | | writer.writeOctetString(request.getName().toString()); |
| | | |
| | | // Write the attributes |
| | | writer.writeStartSequence(); |
| | | for (final Attribute attr : request.getAllAttributes()) { |
| | | writeAttribute(attr); |
| | | } |
| | | writer.writeEndSequence(); |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided add result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeAddResult(final int messageID, final Result result) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP ADD RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_ADD_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided bind request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param version |
| | | * version of the protocol |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeBindRequest(final int messageID, final int version, |
| | | final GenericBindRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP BIND REQUEST(messageID={}, auth=0x{}, request={})", |
| | | messageID, byteToHex(request.getAuthenticationType()), request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_BIND_REQUEST); |
| | | |
| | | writer.writeInteger(version); |
| | | writer.writeOctetString(request.getName()); |
| | | writer.writeOctetString(request.getAuthenticationType(), request.getAuthenticationValue()); |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided bind result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeBindResult(final int messageID, final BindResult result) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP BIND RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_BIND_RESPONSE, result); |
| | | |
| | | final ByteString saslCredentials = result.getServerSASLCredentials(); |
| | | if (saslCredentials != null && saslCredentials.length() > 0) { |
| | | writer.writeOctetString(TYPE_SERVER_SASL_CREDENTIALS, result.getServerSASLCredentials()); |
| | | } |
| | | |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided compare request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeCompareRequest(final int messageID, |
| | | final CompareRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP COMPARE REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_COMPARE_REQUEST); |
| | | writer.writeOctetString(request.getName().toString()); |
| | | |
| | | writer.writeStartSequence(); |
| | | writer.writeOctetString(request.getAttributeDescription().toString()); |
| | | writer.writeOctetString(request.getAssertionValue()); |
| | | writer.writeEndSequence(); |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided compare result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeCompareResult(final int messageID, |
| | | final CompareResult result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP COMPARE RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_COMPARE_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided delete request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeDeleteRequest(final int messageID, |
| | | final DeleteRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP DELETE REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeOctetString(OP_TYPE_DELETE_REQUEST, request.getName().toString()); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided delete result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeDeleteResult(final int messageID, final Result result) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP DELETE RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_DELETE_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided extended request. |
| | | * |
| | | * @param <R> |
| | | * type of extended result returned by the request |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public <R extends ExtendedResult> void writeExtendedRequest(final int messageID, |
| | | final ExtendedRequest<R> request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP EXTENDED REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_EXTENDED_REQUEST); |
| | | writer.writeOctetString(TYPE_EXTENDED_REQUEST_OID, request.getOID()); |
| | | |
| | | final ByteString requestValue = request.getValue(); |
| | | if (requestValue != null) { |
| | | writer.writeOctetString(TYPE_EXTENDED_REQUEST_VALUE, requestValue); |
| | | } |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided extended result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeExtendedResult(final int messageID, |
| | | final ExtendedResult result) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP EXTENDED RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_EXTENDED_RESPONSE, result); |
| | | |
| | | final String responseName = result.getOID(); |
| | | final ByteString responseValue = result.getValue(); |
| | | |
| | | if (responseName != null) { |
| | | writer.writeOctetString(TYPE_EXTENDED_RESPONSE_OID, responseName); |
| | | } |
| | | |
| | | if (responseValue != null) { |
| | | writer.writeOctetString(TYPE_EXTENDED_RESPONSE_VALUE, responseValue); |
| | | } |
| | | |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided intermediate response. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param response |
| | | * the response |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeIntermediateResponse(final int messageID, |
| | | final IntermediateResponse response) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP INTERMEDIATE RESPONSE(messageID={}, response={})", messageID, response); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_INTERMEDIATE_RESPONSE); |
| | | |
| | | final String responseName = response.getOID(); |
| | | final ByteString responseValue = response.getValue(); |
| | | |
| | | if (responseName != null) { |
| | | writer.writeOctetString(TYPE_INTERMEDIATE_RESPONSE_OID, response.getOID()); |
| | | } |
| | | |
| | | if (responseValue != null) { |
| | | writer.writeOctetString(TYPE_INTERMEDIATE_RESPONSE_VALUE, response.getValue()); |
| | | } |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(response); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided modify DN request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeModifyDNRequest(final int messageID, |
| | | final ModifyDNRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY DN REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_MODIFY_DN_REQUEST); |
| | | writer.writeOctetString(request.getName().toString()); |
| | | writer.writeOctetString(request.getNewRDN().toString()); |
| | | writer.writeBoolean(request.isDeleteOldRDN()); |
| | | |
| | | final DN newSuperior = request.getNewSuperior(); |
| | | if (newSuperior != null) { |
| | | writer.writeOctetString(TYPE_MODIFY_DN_NEW_SUPERIOR, newSuperior.toString()); |
| | | } |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided modify DN result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeModifyDNResult(final int messageID, final Result result) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY DN RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_MODIFY_DN_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided modify request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeModifyRequest(final int messageID, |
| | | final ModifyRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_MODIFY_REQUEST); |
| | | writer.writeOctetString(request.getName().toString()); |
| | | |
| | | writer.writeStartSequence(); |
| | | for (final Modification change : request.getModifications()) { |
| | | writeChange(change); |
| | | } |
| | | writer.writeEndSequence(); |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided extended result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeModifyResult(final int messageID, final Result result) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP MODIFY RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_MODIFY_RESPONSE, result); |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided search request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeSearchRequest(final int messageID, |
| | | final SearchRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_SEARCH_REQUEST); |
| | | writer.writeOctetString(request.getName().toString()); |
| | | writer.writeEnumerated(request.getScope().intValue()); |
| | | writer.writeEnumerated(request.getDereferenceAliasesPolicy().intValue()); |
| | | writer.writeInteger(request.getSizeLimit()); |
| | | writer.writeInteger(request.getTimeLimit()); |
| | | writer.writeBoolean(request.isTypesOnly()); |
| | | LDAPUtils.encodeFilter(writer, request.getFilter()); |
| | | |
| | | writer.writeStartSequence(); |
| | | for (final String attribute : request.getAttributes()) { |
| | | writer.writeOctetString(attribute); |
| | | } |
| | | writer.writeEndSequence(); |
| | | |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided search result. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param result |
| | | * the result |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeSearchResult(final int messageID, final Result result) |
| | | throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH RESULT(messageID={}, result={})", messageID, result); |
| | | writeMessageHeader(messageID); |
| | | writeResultHeader(OP_TYPE_SEARCH_RESULT_DONE, result); |
| | | writeResultFooter(writer); |
| | | writeMessageFooter(result); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided search result entry. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param entry |
| | | * the entry |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeSearchResultEntry(final int messageID, |
| | | final SearchResultEntry entry) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH RESULT ENTRY(messageID={}, entry={})", messageID, entry); |
| | | writeMessageHeader(messageID); |
| | | writeEntry(entry); |
| | | writeMessageFooter(entry); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided search result reference. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param reference |
| | | * the reference |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeSearchResultReference(final int messageID, |
| | | final SearchResultReference reference) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP SEARCH RESULT REFERENCE(messageID={}, reference={})", messageID, reference); |
| | | writeMessageHeader(messageID); |
| | | writer.writeStartSequence(OP_TYPE_SEARCH_RESULT_REFERENCE); |
| | | for (final String url : reference.getURIs()) { |
| | | writer.writeOctetString(url); |
| | | } |
| | | writer.writeEndSequence(); |
| | | writeMessageFooter(reference); |
| | | } |
| | | |
| | | /** |
| | | * Write the provided unbind request. |
| | | * |
| | | * @param messageID |
| | | * identifier of the request message |
| | | * @param request |
| | | * the request |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeUnbindRequest(final int messageID, |
| | | final UnbindRequest request) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP UNBIND REQUEST(messageID={}, request={})", messageID, request); |
| | | writeMessageHeader(messageID); |
| | | writer.writeNull(OP_TYPE_UNBIND_REQUEST); |
| | | writeMessageFooter(request); |
| | | } |
| | | |
| | | /** |
| | | * Write a message with the provided id, tag and content bytes. |
| | | * |
| | | * @param messageID |
| | | * identifier of the result message |
| | | * @param messageTag |
| | | * tag identifying the type of message |
| | | * @param messageBytes |
| | | * content of message |
| | | * @throws IOException |
| | | * if an error occurs during write operation |
| | | */ |
| | | public void writeUnrecognizedMessage(final int messageID, |
| | | final byte messageTag, final ByteString messageBytes) throws IOException { |
| | | IO_LOG.trace("ENCODE LDAP UNKNOWN MESSAGE(messageID={}, messageTag={}, messageBytes={})", |
| | | messageID, StaticUtils.byteToHex(messageTag), messageBytes); |
| | | writeMessageHeader(messageID); |
| | | writer.writeOctetString(messageTag, messageBytes); |
| | | writer.writeEndSequence(); |
| | | } |
| | | } |
| | |
| | | /** |
| | | * Classes and interfaces providing I/O functionality. |
| | | * <p> |
| | | * It includes facilities for encoding and decoding ASN.1 data streams. |
| | | * It includes facilities for encoding and decoding ASN.1 data streams, as |
| | | * well as LDAP protocol messages. |
| | | * <p> |
| | | * Note that this particular implementation is limited to the subset of elements |
| | | * that are typically used by LDAP clients. As such, it does not include all |
| | |
| | | |
| | | package org.forgerock.opendj.ldap.controls; |
| | | |
| | | import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAPASSERT_CONTROL_BAD_OID; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAPASSERT_INVALID_CONTROL_VALUE; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_LDAPASSERT_NO_CONTROL_VALUE; |
| | | import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage; |
| | | |
| | | import java.io.IOException; |
| | | |
| | |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.ASN1Writer; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.ByteStringBuilder; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | | import org.forgerock.opendj.ldap.Filter; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPUtils; |
| | | import com.forgerock.opendj.util.Validator; |
| | | |
| | | /** |
| | |
| | | throw DecodeException.error(message); |
| | | } |
| | | |
| | | final ASN1Reader reader = ASN1.getReader(control.getValue()); |
| | | Filter filter; |
| | | try { |
| | | filter = LDAPUtils.decodeFilter(reader); |
| | | final ASN1Reader reader = ASN1.getReader(control.getValue()); |
| | | final Filter filter = LDAP.readFilter(reader); |
| | | return new AssertionRequestControl(control.isCritical(), filter); |
| | | } catch (final IOException e) { |
| | | throw DecodeException.error(ERR_LDAPASSERT_INVALID_CONTROL_VALUE |
| | | .get(getExceptionMessage(e)), e); |
| | | } |
| | | |
| | | return new AssertionRequestControl(control.isCritical(), filter); |
| | | } |
| | | |
| | | public String getOID() { |
| | |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(); |
| | | final ASN1Writer writer = ASN1.getWriter(buffer); |
| | | try { |
| | | LDAPUtils.encodeFilter(writer, filter); |
| | | LDAP.writeFilter(writer, filter); |
| | | return buffer.toByteString(); |
| | | } catch (final IOException ioe) { |
| | | // This should never happen unless there is a bug somewhere. |
| | |
| | | |
| | | package org.forgerock.opendj.ldap.controls; |
| | | |
| | | import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.*; |
| | | import static com.forgerock.opendj.util.StaticUtils.getExceptionMessage; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.ASN1Writer; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.ldap.AbstractFilterVisitor; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.ByteStringBuilder; |
| | |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | | import org.forgerock.opendj.ldap.Filter; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPUtils; |
| | | import com.forgerock.opendj.util.StaticUtils; |
| | | import com.forgerock.opendj.util.Validator; |
| | | |
| | |
| | | |
| | | final LinkedList<Filter> filters = new LinkedList<Filter>(); |
| | | do { |
| | | final Filter filter = LDAPUtils.decodeFilter(reader); |
| | | |
| | | final Filter filter = LDAP.readFilter(reader); |
| | | try { |
| | | validateFilter(filter); |
| | | } catch (final LocalizedIllegalArgumentException e) { |
| | | throw DecodeException.error(e.getMessageObject()); |
| | | } |
| | | |
| | | filters.add(filter); |
| | | } while (reader.hasNextElement()); |
| | | |
| | |
| | | try { |
| | | writer.writeStartSequence(); |
| | | for (final Filter f : filters) { |
| | | LDAPUtils.encodeFilter(writer, f); |
| | | LDAP.writeFilter(writer, f); |
| | | } |
| | | writer.writeEndSequence(); |
| | | return buffer.toByteString(); |
| | |
| | | |
| | | package org.forgerock.opendj.ldap.controls; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_POSTREADRESP_CANNOT_DECODE_VALUE; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_POSTREADRESP_NO_CONTROL_VALUE; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_POSTREAD_CONTROL_BAD_OID; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.*; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.ASN1Writer; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.ByteStringBuilder; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | | import org.forgerock.opendj.ldap.Entries; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.responses.Responses; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPUtils; |
| | | import com.forgerock.opendj.util.StaticUtils; |
| | | import com.forgerock.opendj.util.Validator; |
| | | |
| | |
| | | } |
| | | |
| | | final ASN1Reader reader = ASN1.getReader(control.getValue()); |
| | | SearchResultEntry searchEntry; |
| | | final Entry entry; |
| | | try { |
| | | searchEntry = LDAPUtils.decodeSearchResultEntry(reader, options); |
| | | entry = LDAP.readEntry(reader, options); |
| | | } catch (final IOException le) { |
| | | StaticUtils.CONTROLS_LOG.debug("Unable to read result entry ", le); |
| | | |
| | | final LocalizableMessage message = |
| | | ERR_POSTREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage()); |
| | | throw DecodeException.error(message, le); |
| | |
| | | * controls? |
| | | */ |
| | | return new PostReadResponseControl(control.isCritical(), Entries |
| | | .unmodifiableEntry(searchEntry)); |
| | | .unmodifiableEntry(entry)); |
| | | } |
| | | |
| | | public String getOID() { |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public ByteString getValue() { |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(); |
| | | final ASN1Writer writer = ASN1.getWriter(buffer); |
| | | try { |
| | | LDAPUtils.encodeSearchResultEntry(writer, Responses.newSearchResultEntry(entry)); |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(); |
| | | LDAP.writeEntry(ASN1.getWriter(buffer), entry); |
| | | return buffer.toByteString(); |
| | | } catch (final IOException ioe) { |
| | | // This should never happen unless there is a bug somewhere. |
| | |
| | | |
| | | package org.forgerock.opendj.ldap.controls; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_PREREADRESP_CANNOT_DECODE_VALUE; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_PREREADRESP_NO_CONTROL_VALUE; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_PREREAD_CONTROL_BAD_OID; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.*; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.ASN1Writer; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.ByteStringBuilder; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | | import org.forgerock.opendj.ldap.Entries; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.responses.Responses; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPUtils; |
| | | import com.forgerock.opendj.util.StaticUtils; |
| | | import com.forgerock.opendj.util.Validator; |
| | | |
| | |
| | | } |
| | | |
| | | final ASN1Reader reader = ASN1.getReader(control.getValue()); |
| | | SearchResultEntry searchEntry; |
| | | final Entry entry; |
| | | try { |
| | | searchEntry = LDAPUtils.decodeSearchResultEntry(reader, options); |
| | | entry = LDAP.readEntry(reader, options); |
| | | } catch (final IOException le) { |
| | | StaticUtils.CONTROLS_LOG.debug("Unable to read result entry", le); |
| | | |
| | | final LocalizableMessage message = |
| | | ERR_PREREADRESP_CANNOT_DECODE_VALUE.get(le.getMessage()); |
| | | throw DecodeException.error(message, le); |
| | |
| | | * controls? |
| | | */ |
| | | return new PreReadResponseControl(control.isCritical(), Entries |
| | | .unmodifiableEntry(searchEntry)); |
| | | .unmodifiableEntry(entry)); |
| | | } |
| | | |
| | | public String getOID() { |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public ByteString getValue() { |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(); |
| | | final ASN1Writer writer = ASN1.getWriter(buffer); |
| | | try { |
| | | LDAPUtils.encodeSearchResultEntry(writer, Responses.newSearchResultEntry(entry)); |
| | | final ByteStringBuilder buffer = new ByteStringBuilder(); |
| | | LDAP.writeEntry(ASN1.getWriter(buffer), entry); |
| | | return buffer.toByteString(); |
| | | } catch (final IOException ioe) { |
| | | // This should never happen unless there is a bug somewhere. |
| | |
| | | * |
| | | * |
| | | * Copyright 2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2013 ForgeRock AS. |
| | | */ |
| | | |
| | | package org.forgerock.opendj.ldap.requests; |
| | | |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.TYPE_AUTHENTICATION_SASL; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | |
| | | /** |
| | | * An abstract SASL Bind request which can be used as the basis for implementing |
| | |
| | | |
| | | @Override |
| | | public final byte getAuthenticationType() { |
| | | return TYPE_AUTHENTICATION_SASL; |
| | | return LDAP.TYPE_AUTHENTICATION_SASL; |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | package org.forgerock.opendj.ldap.requests; |
| | | |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.TYPE_AUTHENTICATION_SIMPLE; |
| | | |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.ldap.ErrorResultException; |
| | | |
| | | import com.forgerock.opendj.util.StaticUtils; |
| | |
| | | |
| | | @Override |
| | | public byte getAuthenticationType() { |
| | | return TYPE_AUTHENTICATION_SIMPLE; |
| | | return LDAP.TYPE_AUTHENTICATION_SIMPLE; |
| | | } |
| | | |
| | | @Override |
| | |
| | | // The attribute usage for this attribute type. |
| | | private final AttributeUsage attributeUsage; |
| | | |
| | | // The definition string used to create this objectclass. |
| | | private final String definition; |
| | | |
| | | // The equality matching rule for this attribute type. |
| | | private final String equalityMatchingRuleOID; |
| | | |
| | |
| | | final boolean collective, final boolean noUserModification, |
| | | final AttributeUsage attributeUsage, final Map<String, List<String>> extraProperties, |
| | | final String definition) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, definition); |
| | | |
| | | Validator.ensureNotNull(oid, names, description, attributeUsage); |
| | | Validator.ensureTrue(superiorType != null || syntax != null, |
| | |
| | | this.isCollective = collective; |
| | | this.isNoUserModification = noUserModification; |
| | | this.attributeUsage = attributeUsage; |
| | | |
| | | if (definition != null) { |
| | | this.definition = definition; |
| | | } else { |
| | | this.definition = buildDefinition(); |
| | | } |
| | | |
| | | this.isObjectClassType = oid.equals("2.5.4.0"); |
| | | this.isPlaceHolder = false; |
| | | this.normalizedName = StaticUtils.toLowerCase(getNameOrOID()); |
| | |
| | | * The name of the place-holder attribute type. |
| | | */ |
| | | AttributeType(final String name) { |
| | | super("", Collections.<String, List<String>> emptyMap()); |
| | | |
| | | final StringBuilder builder = new StringBuilder(name.length() + 4); |
| | | StaticUtils.toLowerCase(name, builder); |
| | | builder.append("-oid"); |
| | |
| | | this.isCollective = false; |
| | | this.isNoUserModification = false; |
| | | this.attributeUsage = AttributeUsage.USER_APPLICATIONS; |
| | | this.definition = buildDefinition(); |
| | | this.isObjectClassType = false; |
| | | this.isPlaceHolder = true; |
| | | this.normalizedName = StaticUtils.toLowerCase(getNameOrOID()); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Returns the string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | AttributeType duplicate() { |
| | | return new AttributeType(oid, names, description, isObsolete, superiorTypeOID, |
| | | return new AttributeType(oid, names, getDescription(), isObsolete, superiorTypeOID, |
| | | equalityMatchingRuleOID, orderingMatchingRuleOID, substringMatchingRuleOID, |
| | | approximateMatchingRuleOID, syntaxOID, isSingleValue, isCollective, |
| | | isNoUserModification, attributeUsage, extraProperties, definition); |
| | | isNoUserModification, attributeUsage, getExtraProperties(), toString()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | |
| | | if (isObsolete) { |
| | | buffer.append(" OBSOLETE"); |
| | |
| | | // The set of required attribute types for this DIT content rule. |
| | | private final Set<String> requiredAttributeOIDs; |
| | | |
| | | // The definition string used to create this objectclass. |
| | | private final String definition; |
| | | |
| | | private ObjectClass structuralClass; |
| | | private Set<ObjectClass> auxiliaryClasses = Collections.emptySet(); |
| | | private Set<AttributeType> optionalAttributes = Collections.emptySet(); |
| | |
| | | final Set<String> optionalAttributeOIDs, final Set<String> prohibitedAttributeOIDs, |
| | | final Set<String> requiredAttributeOIDs, |
| | | final Map<String, List<String>> extraProperties, final String definition) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, definition); |
| | | |
| | | Validator.ensureNotNull(structuralClassOID, names); |
| | | Validator.ensureNotNull(auxiliaryClassOIDs, optionalAttributeOIDs, prohibitedAttributeOIDs, |
| | |
| | | this.optionalAttributeOIDs = optionalAttributeOIDs; |
| | | this.prohibitedAttributeOIDs = prohibitedAttributeOIDs; |
| | | this.requiredAttributeOIDs = requiredAttributeOIDs; |
| | | |
| | | if (definition != null) { |
| | | this.definition = definition; |
| | | } else { |
| | | this.definition = buildDefinition(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | return isRequired(attributeType) || isOptional(attributeType); |
| | | } |
| | | |
| | | /** |
| | | * Returns the string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | DITContentRule duplicate() { |
| | | return new DITContentRule(structuralClassOID, names, description, isObsolete, |
| | | return new DITContentRule(structuralClassOID, names, getDescription(), isObsolete, |
| | | auxiliaryClassOIDs, optionalAttributeOIDs, prohibitedAttributeOIDs, |
| | | requiredAttributeOIDs, extraProperties, definition); |
| | | requiredAttributeOIDs, getExtraProperties(), toString()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | |
| | | if (isObsolete) { |
| | | buffer.append(" OBSOLETE"); |
| | |
| | | // The set of superior DIT structure rules. |
| | | private final Set<Integer> superiorRuleIDs; |
| | | |
| | | // The definition string used to create this objectclass. |
| | | private final String definition; |
| | | |
| | | private NameForm nameForm; |
| | | private Set<DITStructureRule> superiorRules = Collections.emptySet(); |
| | | |
| | |
| | | DITStructureRule(final Integer ruleID, final List<String> names, final String description, |
| | | final boolean obsolete, final String nameFormOID, final Set<Integer> superiorRuleIDs, |
| | | final Map<String, List<String>> extraProperties, final String definition) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, definition); |
| | | |
| | | Validator.ensureNotNull(ruleID, nameFormOID, superiorRuleIDs); |
| | | this.ruleID = ruleID; |
| | |
| | | this.isObsolete = obsolete; |
| | | this.nameFormOID = nameFormOID; |
| | | this.superiorRuleIDs = superiorRuleIDs; |
| | | |
| | | if (definition != null) { |
| | | this.definition = definition; |
| | | } else { |
| | | this.definition = buildDefinition(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | return isObsolete; |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | DITStructureRule duplicate() { |
| | | return new DITStructureRule(ruleID, names, description, isObsolete, nameFormOID, |
| | | superiorRuleIDs, extraProperties, definition); |
| | | return new DITStructureRule(ruleID, names, getDescription(), isObsolete, nameFormOID, |
| | | superiorRuleIDs, getExtraProperties(), toString()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | |
| | | if (isObsolete) { |
| | | buffer.append(" OBSOLETE"); |
| | |
| | | private final List<String> names; |
| | | private final boolean isObsolete; |
| | | private final String syntaxOID; |
| | | private final String definition; |
| | | private MatchingRuleImpl impl; |
| | | private Syntax syntax; |
| | | private Schema schema; |
| | |
| | | final boolean obsolete, final String syntax, |
| | | final Map<String, List<String>> extraProperties, final String definition, |
| | | final MatchingRuleImpl implementation) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, definition); |
| | | |
| | | Validator.ensureNotNull(oid, names, description, syntax); |
| | | Validator.ensureNotNull(extraProperties); |
| | |
| | | this.names = names; |
| | | this.isObsolete = obsolete; |
| | | this.syntaxOID = syntax; |
| | | |
| | | if (definition != null) { |
| | | this.definition = definition; |
| | | } else { |
| | | this.definition = buildDefinition(); |
| | | } |
| | | this.impl = implementation; |
| | | } |
| | | |
| | |
| | | return impl.normalizeAttributeValue(schema, value); |
| | | } |
| | | |
| | | /** |
| | | * Returns the string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | MatchingRule duplicate() { |
| | | return new MatchingRule(oid, names, description, isObsolete, syntaxOID, extraProperties, |
| | | definition, impl); |
| | | return new MatchingRule(oid, names, getDescription(), isObsolete, syntaxOID, |
| | | getExtraProperties(), toString(), impl); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | |
| | | if (isObsolete) { |
| | | buffer.append(" OBSOLETE"); |
| | |
| | | // associated. |
| | | private final Set<String> attributeOIDs; |
| | | |
| | | // The definition string used to create this objectclass. |
| | | private final String definition; |
| | | |
| | | private MatchingRule matchingRule; |
| | | private Set<AttributeType> attributes = Collections.emptySet(); |
| | | |
| | | MatchingRuleUse(final String oid, final List<String> names, final String description, |
| | | final boolean obsolete, final Set<String> attributeOIDs, |
| | | final Map<String, List<String>> extraProperties, final String definition) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, definition); |
| | | |
| | | Validator.ensureNotNull(oid, names, attributeOIDs); |
| | | this.oid = oid; |
| | | this.names = names; |
| | | this.isObsolete = obsolete; |
| | | this.attributeOIDs = attributeOIDs; |
| | | |
| | | if (definition != null) { |
| | | this.definition = definition; |
| | | } else { |
| | | this.definition = buildDefinition(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | return isObsolete; |
| | | } |
| | | |
| | | /** |
| | | * Returns the string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | MatchingRuleUse duplicate() { |
| | | return new MatchingRuleUse(oid, names, description, isObsolete, attributeOIDs, |
| | | extraProperties, definition); |
| | | return new MatchingRuleUse(oid, names, getDescription(), isObsolete, attributeOIDs, |
| | | getExtraProperties(), toString()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | |
| | | if (isObsolete) { |
| | | buffer.append(" OBSOLETE"); |
| | |
| | | |
| | | package org.forgerock.opendj.ldap.schema; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_NAME_FORM_STRUCTURAL_CLASS_NOT_STRUCTURAL1; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_NAME_FORM_UNKNOWN_OPTIONAL_ATTR1; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_NAME_FORM_UNKNOWN_REQUIRED_ATTR1; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.ERR_ATTR_SYNTAX_NAME_FORM_UNKNOWN_STRUCTURAL_CLASS1; |
| | | import static com.forgerock.opendj.ldap.CoreMessages.*; |
| | | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collection; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | |
| | | * RDN of an entry with a given structural objectclass. |
| | | */ |
| | | public final class NameForm extends SchemaElement { |
| | | |
| | | // The OID that may be used to reference this definition. |
| | | private final String oid; |
| | | |
| | | // The set of user defined names for this definition. |
| | | private final List<String> names; |
| | | |
| | | // Indicates whether this definition is declared "obsolete". |
| | | private final boolean isObsolete; |
| | | |
| | | // The reference to the structural objectclass for this name form. |
| | | private final String structuralClassOID; |
| | | |
| | | // The set of optional attribute types for this name form. |
| | | private final Set<String> optionalAttributeOIDs; |
| | | |
| | | // The set of required attribute types for this name form. |
| | | private final Set<String> requiredAttributeOIDs; |
| | | |
| | | // The definition string used to create this objectclass. |
| | | private final String definition; |
| | | |
| | | private ObjectClass structuralClass; |
| | | private Set<AttributeType> optionalAttributes = Collections.emptySet(); |
| | | private Set<AttributeType> requiredAttributes = Collections.emptySet(); |
| | | |
| | | /** |
| | | * The name form builder. |
| | | * A fluent API for incrementally constructing name forms. |
| | | */ |
| | | public static class Builder extends SchemaElementBuilder<Builder> { |
| | | |
| | | // Required attributes |
| | | private String oid; |
| | | private String structuralObjectClassOID; |
| | | private Set<String> requiredAttribute = new LinkedHashSet<String>(); |
| | | |
| | | // Optional attributes - initialized to default values. |
| | | private List<String> names = new LinkedList<String>(); |
| | | private Set<String> optionalAttributes = new LinkedHashSet<String>(); |
| | | private String definition; |
| | | private boolean isObsolete = false; |
| | | private final List<String> names = new LinkedList<String>(); |
| | | private String oid; |
| | | private final Set<String> optionalAttributes = new LinkedHashSet<String>(); |
| | | private final Set<String> requiredAttributes = new LinkedHashSet<String>(); |
| | | private String structuralObjectClassOID; |
| | | |
| | | /** |
| | | * Sets the OID of the name form definition. |
| | | * <p> |
| | | * RFC 4512 : numericoid ; object identifier. |
| | | * |
| | | * @param oid |
| | | * Like 1.3.6.1.4.1.1466.115.121.1.35. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder oid(final String oid) { |
| | | this.oid = oid; |
| | | return this; |
| | | Builder(final NameForm nf, final SchemaBuilder builder) { |
| | | super(builder, nf); |
| | | this.oid = nf.oid; |
| | | this.structuralObjectClassOID = nf.structuralClassOID; |
| | | this.isObsolete = nf.isObsolete; |
| | | this.names.addAll(nf.names); |
| | | this.requiredAttributes.addAll(nf.requiredAttributeOIDs); |
| | | this.optionalAttributes.addAll(nf.optionalAttributeOIDs); |
| | | } |
| | | |
| | | Builder(final String oid, final SchemaBuilder builder) { |
| | | super(builder); |
| | | this.oid(oid); |
| | | } |
| | | |
| | | /** |
| | | * Sets the structural object class OID. |
| | | * <p> |
| | | * e.g : OC person. |
| | | * Adds this name form to the schema overwriting any existing name form |
| | | * with the same numeric OID. |
| | | * |
| | | * @param oid |
| | | * = SP "OC" SP oid (RFC 4512). |
| | | * @return This name form builder. |
| | | * @return The parent schema builder. |
| | | */ |
| | | public Builder structuralObjectClassOID(final String oid) { |
| | | this.structuralObjectClassOID = oid; |
| | | return this; |
| | | public SchemaBuilder addToSchema() { |
| | | return this.getSchemaBuilder().addNameForm(new NameForm(this), true); |
| | | } |
| | | |
| | | /** |
| | | * Sets the user defined names for this definition. |
| | | * <p> |
| | | * RFC 4512 : [ SP "NAME" SP qdescrs ] ; short names (descriptors). |
| | | * Adds this name form to the schema, throwing an |
| | | * {@code ConflictingSchemaElementException} if there is an existing |
| | | * name form with the same numeric OID. |
| | | * |
| | | * @return The parent schema builder. |
| | | * @throws ConflictingSchemaElementException |
| | | * If there is an existing name form with the same numeric |
| | | * OID. |
| | | */ |
| | | public SchemaBuilder addToSchemaNoOverwrite() { |
| | | return this.getSchemaBuilder().addNameForm(new NameForm(this), false); |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided user friendly names. |
| | | * |
| | | * @param names |
| | | * Contains a collection of strings. |
| | | * @return This name form builder. |
| | | * The user friendly names. |
| | | * @return This builder. |
| | | */ |
| | | public Builder names(final Collection<String> names) { |
| | | this.names.addAll(names); |
| | |
| | | } |
| | | |
| | | /** |
| | | * Sets the user defined names for this definition. |
| | | * <p> |
| | | * RFC 4512 : [ SP "NAME" SP qdescrs ] ; short names (descriptors). |
| | | * Adds the provided user friendly names. |
| | | * |
| | | * @param names |
| | | * Contains a series of strings. |
| | | * @return This name form builder. |
| | | * The user friendly names. |
| | | * @return This builder. |
| | | */ |
| | | public Builder names(final String... names) { |
| | | return names(Arrays.asList(names)); |
| | | } |
| | | |
| | | /** |
| | | * Erases all the names. |
| | | * |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder removeAllNames() { |
| | | this.names.clear(); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes the defined name. |
| | | * |
| | | * @param name |
| | | * The name to remove. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder removeName(String name) { |
| | | names.remove(name); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Specifies which attributes are required by this name form. |
| | | * <p> |
| | | * RFC 4512 : SP "MUST" SP oids ; attribute types. |
| | | * |
| | | * @param oids |
| | | * The OIDs of the required attributes. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder requiredAttributes(final String... oids) { |
| | | return requiredAttributes(Arrays.asList(oids)); |
| | | } |
| | | |
| | | /** |
| | | * Specifies which attributes are required by this name form. |
| | | * <p> |
| | | * RFC 4512 : SP "MUST" SP oids ; attribute types. |
| | | * |
| | | * @param oids |
| | | * The OIDs of the required attributes. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder requiredAttributes(final Collection<String> oids) { |
| | | this.requiredAttribute.addAll(oids); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes the specified required attribute. |
| | | * |
| | | * @param oid |
| | | * The OID of the required attributes. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder removeRequiredAttribute(final String oid) { |
| | | this.requiredAttribute.remove(oid); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes all the required attributes. |
| | | * |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder removeAllRequiredAttributes() { |
| | | this.requiredAttribute.clear(); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Sets the optional attribute OIDs. |
| | | * <p> |
| | | * RFC 4512 : [ SP "MAY" SP oids ] ; attribute types. |
| | | * |
| | | * @param oids |
| | | * The OIDs of the optional attributes. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder optionalAttributes(final String... oids) { |
| | | return optionalAttributes(Arrays.asList(oids)); |
| | | } |
| | | |
| | | /** |
| | | * Sets the optional attributes. |
| | | * <p> |
| | | * RFC 4512 : [ SP "MAY" SP oids ] ; attribute types. |
| | | * |
| | | * @param oids |
| | | * The OIDs of the optional attributes. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder optionalAttributes(final Collection<String> oids) { |
| | | this.optionalAttributes.addAll(oids); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes the specified attributes. |
| | | * |
| | | * @param oid |
| | | * The OID of the optional attributes. |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder removeOptionalAttribute(final String oid) { |
| | | this.optionalAttributes.remove(oid); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes all the optional attributes. |
| | | * |
| | | * @return This name form builder. |
| | | */ |
| | | public Builder removeAllOptionalAttributes() { |
| | | this.optionalAttributes.clear(); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * {@code true} if the object class definition is obsolete, otherwise |
| | | * {@code false}. |
| | | * <p> |
| | | * RFC 4512 : [ SP "OBSOLETE" ] ; not active. |
| | | * Specifies whether or not this schema element is obsolete. |
| | | * |
| | | * @param isObsolete |
| | | * default is {@code false}. |
| | | * @return This name form builder. |
| | | * {@code true} if this schema element is obsolete (default |
| | | * is {@code false}). |
| | | * @return This builder. |
| | | */ |
| | | public Builder obsolete(final boolean isObsolete) { |
| | | this.isObsolete = isObsolete; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Sets the definition string used to create this object class. |
| | | * Sets the numeric OID which uniquely identifies this name form. |
| | | * |
| | | * @param definition |
| | | * The definition to set. |
| | | * @return This name form builder. |
| | | * @param oid |
| | | * The numeric OID. |
| | | * @return This builder. |
| | | */ |
| | | Builder definition(final String definition) { |
| | | this.definition = definition; |
| | | public Builder oid(final String oid) { |
| | | this.oid = oid; |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Returns the builder. |
| | | * Adds the provided optional attributes. |
| | | * |
| | | * @return This name form builder. |
| | | * @param nameOrOIDs |
| | | * The list of optional attributes. |
| | | * @return This builder. |
| | | */ |
| | | public Builder optionalAttributes(final Collection<String> nameOrOIDs) { |
| | | this.optionalAttributes.addAll(nameOrOIDs); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided optional attributes. |
| | | * |
| | | * @param nameOrOIDs |
| | | * The list of optional attributes. |
| | | * @return This builder. |
| | | */ |
| | | public Builder optionalAttributes(final String... nameOrOIDs) { |
| | | return optionalAttributes(Arrays.asList(nameOrOIDs)); |
| | | } |
| | | |
| | | /** |
| | | * Removes all user friendly names. |
| | | * |
| | | * @return This builder. |
| | | */ |
| | | public Builder removeAllNames() { |
| | | this.names.clear(); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes all optional attributes. |
| | | * |
| | | * @return This builder. |
| | | */ |
| | | public Builder removeAllOptionalAttributes() { |
| | | this.optionalAttributes.clear(); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes all required attributes. |
| | | * |
| | | * @return This builder. |
| | | */ |
| | | public Builder removeAllRequiredAttributes() { |
| | | this.requiredAttributes.clear(); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes the provided user friendly name. |
| | | * |
| | | * @param name |
| | | * The user friendly name to be removed. |
| | | * @return This builder. |
| | | */ |
| | | public Builder removeName(final String name) { |
| | | names.remove(name); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes the specified optional attribute. |
| | | * |
| | | * @param nameOrOID |
| | | * The optional attribute to be removed. |
| | | * @return This builder. |
| | | */ |
| | | public Builder removeOptionalAttribute(final String nameOrOID) { |
| | | this.optionalAttributes.remove(nameOrOID); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Removes the specified required attribute. |
| | | * |
| | | * @param nameOrOID |
| | | * The required attribute to be removed. |
| | | * @return This builder. |
| | | */ |
| | | public Builder removeRequiredAttribute(final String nameOrOID) { |
| | | this.requiredAttributes.remove(nameOrOID); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided required attributes. |
| | | * |
| | | * @param nameOrOIDs |
| | | * The list of required attributes. |
| | | * @return This builder. |
| | | */ |
| | | public Builder requiredAttributes(final Collection<String> nameOrOIDs) { |
| | | this.requiredAttributes.addAll(nameOrOIDs); |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided required attributes. |
| | | * |
| | | * @param nameOrOIDs |
| | | * The list of required attributes. |
| | | * @return This builder. |
| | | */ |
| | | public Builder requiredAttributes(final String... nameOrOIDs) { |
| | | return requiredAttributes(Arrays.asList(nameOrOIDs)); |
| | | } |
| | | |
| | | /** |
| | | * Sets the structural object class. |
| | | * |
| | | * @param nameOrOID |
| | | * The structural object class. |
| | | * @return This builder. |
| | | */ |
| | | public Builder structuralObjectClassOID(final String nameOrOID) { |
| | | this.structuralObjectClassOID = nameOrOID; |
| | | return this; |
| | | } |
| | | |
| | | @Override |
| | | Builder getThis() { |
| | | return this; |
| | | } |
| | | |
| | | /** |
| | | * Creates a new name form builder implementation. |
| | | * |
| | | * @param oid |
| | | * The OID of the name form definition. |
| | | * @param builder |
| | | * The schema builder linked. |
| | | */ |
| | | Builder(final String oid, final SchemaBuilder builder) { |
| | | this.oid(oid); |
| | | this.schemaBuilder(builder); |
| | | } |
| | | |
| | | /** |
| | | * Duplicates an existing name form builder. |
| | | * |
| | | * @param nf |
| | | * The name form to duplicate. |
| | | * @param builder |
| | | * The schema builder where to adds this new name form |
| | | * @throws ConflictingSchemaElementException |
| | | * If {@code overwrite} was {@code false} and a conflicting |
| | | * schema element was found. |
| | | */ |
| | | Builder(final NameForm nf, final SchemaBuilder builder) { |
| | | this.oid = nf.oid; |
| | | this.definition = nf.buildDefinition(); |
| | | this.description(nf.description); |
| | | this.structuralObjectClassOID = nf.structuralClassOID; |
| | | this.isObsolete = nf.isObsolete; |
| | | this.names = new ArrayList<String>(nf.names); |
| | | this.extraProperties(new LinkedHashMap<String, List<String>>(nf.extraProperties)); |
| | | this.requiredAttribute = new LinkedHashSet<String>(nf.requiredAttributeOIDs); |
| | | this.optionalAttributes = new LinkedHashSet<String>(nf.optionalAttributeOIDs); |
| | | this.schemaBuilder(builder); |
| | | } |
| | | |
| | | /** |
| | | * Adds the name form to the builder overwriting any existing name form |
| | | * with the same OID. |
| | | * |
| | | * @return A schema builder. |
| | | */ |
| | | public SchemaBuilder addToSchema() { |
| | | return this.getSchemaBuilder().addNameForm(new NameForm(this), true); |
| | | } |
| | | |
| | | /** |
| | | * Adds the name form to the builder throwing an |
| | | * ConflictingSchemaElementException if there is an existing name form |
| | | * with the same OID. |
| | | * |
| | | * @return A schema builder. |
| | | * @throws ConflictingSchemaElementException |
| | | * If there is an existing name form with the same OID. |
| | | */ |
| | | public SchemaBuilder addNoOverwriteToSchema() { |
| | | return this.getSchemaBuilder().addNameForm(new NameForm(this), false); |
| | | } |
| | | } |
| | | |
| | | // Indicates whether this definition is declared "obsolete". |
| | | private final boolean isObsolete; |
| | | |
| | | // The set of user defined names for this definition. |
| | | private final List<String> names; |
| | | |
| | | // The OID that may be used to reference this definition. |
| | | private final String oid; |
| | | |
| | | // The set of optional attribute types for this name form. |
| | | private final Set<String> optionalAttributeOIDs; |
| | | private Set<AttributeType> optionalAttributes = Collections.emptySet(); |
| | | |
| | | // The set of required attribute types for this name form. |
| | | private final Set<String> requiredAttributeOIDs; |
| | | private Set<AttributeType> requiredAttributes = Collections.emptySet(); |
| | | |
| | | // The reference to the structural objectclass for this name form. |
| | | private ObjectClass structuralClass; |
| | | private final String structuralClassOID; |
| | | |
| | | private NameForm(final Builder builder) { |
| | | super(builder.description, builder.extraProperties); |
| | | super(builder); |
| | | |
| | | // Checks for required attributes. |
| | | if (builder.oid == null || builder.oid.isEmpty()) { |
| | | throw new IllegalArgumentException("An OID must be specified."); |
| | |
| | | if (builder.structuralObjectClassOID == null || builder.structuralObjectClassOID.isEmpty()) { |
| | | throw new IllegalArgumentException("A structural class OID must be specified."); |
| | | } |
| | | if (builder.requiredAttribute == null || builder.requiredAttribute.isEmpty()) { |
| | | if (builder.requiredAttributes == null || builder.requiredAttributes.isEmpty()) { |
| | | throw new IllegalArgumentException("Required attribute must be specified."); |
| | | } |
| | | |
| | | oid = builder.oid; |
| | | structuralClassOID = builder.structuralObjectClassOID; |
| | | names = SchemaUtils.unmodifiableCopyOfList(builder.names); |
| | | requiredAttributeOIDs = SchemaUtils.unmodifiableCopyOfSet(builder.requiredAttribute); |
| | | requiredAttributeOIDs = SchemaUtils.unmodifiableCopyOfSet(builder.requiredAttributes); |
| | | optionalAttributeOIDs = SchemaUtils.unmodifiableCopyOfSet(builder.optionalAttributes); |
| | | isObsolete = builder.isObsolete; |
| | | |
| | | definition = buildDefinition(); |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the name or OID for this schema definition. If it has one or more |
| | | * Returns the name or numeric OID of this name form. If it has one or more |
| | | * names, then the primary name will be returned. If it does not have any |
| | | * names, then the OID will be returned. |
| | | * names, then the numeric OID will be returned. |
| | | * |
| | | * @return The name or OID for this schema definition. |
| | | * @return The name or numeric OID of this name form. |
| | | */ |
| | | public String getNameOrOID() { |
| | | if (names.isEmpty()) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns an unmodifiable list containing the user-defined names that may |
| | | * be used to reference this schema definition. |
| | | * Returns an unmodifiable list containing the user-friendly names that may |
| | | * be used to reference this name form. |
| | | * |
| | | * @return Returns an unmodifiable list containing the user-defined names |
| | | * that may be used to reference this schema definition. |
| | | * @return An unmodifiable list containing the user-friendly names that may |
| | | * be used to reference this name form. |
| | | */ |
| | | public List<String> getNames() { |
| | | return names; |
| | | } |
| | | |
| | | /** |
| | | * Returns the OID for this schema definition. |
| | | * Returns the numeric OID of this name form. |
| | | * |
| | | * @return The OID for this schema definition. |
| | | * @return The numeric OID of this name form. |
| | | */ |
| | | public String getOID() { |
| | | |
| | | return oid; |
| | | } |
| | | |
| | | /** |
| | | * Returns an unmodifiable set containing the optional attributes for this |
| | | * Returns an unmodifiable set containing the optional attributes of this |
| | | * name form. |
| | | * |
| | | * @return An unmodifiable set containing the optional attributes for this |
| | | * @return An unmodifiable set containing the optional attributes of this |
| | | * name form. |
| | | */ |
| | | public Set<AttributeType> getOptionalAttributes() { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns an unmodifiable set containing the required attributes for this |
| | | * Returns an unmodifiable set containing the required attributes of this |
| | | * name form. |
| | | * |
| | | * @return An unmodifiable set containing the required attributes for this |
| | | * @return An unmodifiable set containing the required attributes of this |
| | | * name form. |
| | | */ |
| | | public Set<AttributeType> getRequiredAttributes() { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Returns the reference to the structural objectclass for this name form. |
| | | * Returns the structural objectclass of this name form. |
| | | * |
| | | * @return The reference to the structural objectclass for this name form. |
| | | * @return The structural objectclass of this name form. |
| | | */ |
| | | public ObjectClass getStructuralClass() { |
| | | return structuralClass; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether this schema definition has the specified name. |
| | | * Returns {@code true} if this name form has the specified user-friendly |
| | | * name. |
| | | * |
| | | * @param name |
| | | * The name for which to make the determination. |
| | | * @return <code>true</code> if the specified name is assigned to this |
| | | * schema definition, or <code>false</code> if not. |
| | | * The name. |
| | | * @return {@code true} if this name form has the specified user-friendly |
| | | * name. |
| | | */ |
| | | public boolean hasName(final String name) { |
| | | for (final String n : names) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether this schema definition has the specified name or OID. |
| | | * Returns {@code true} if this name form has the specified user-friendly |
| | | * name or numeric OID. |
| | | * |
| | | * @param value |
| | | * The value for which to make the determination. |
| | | * @return <code>true</code> if the provided value matches the OID or one of |
| | | * the names assigned to this schema definition, or |
| | | * <code>false</code> if not. |
| | | * @param nameOrOID |
| | | * The name or numeric OID. |
| | | * @return {@code true} if this name form has the specified user-friendly |
| | | * name or numeric OID. |
| | | */ |
| | | public boolean hasNameOrOID(final String value) { |
| | | return hasName(value) || getOID().equals(value); |
| | | public boolean hasNameOrOID(final String nameOrOID) { |
| | | return hasName(nameOrOID) || getOID().equals(nameOrOID); |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether this schema definition is declared "obsolete". |
| | | * Returns {@code true} if this name form is "obsolete". |
| | | * |
| | | * @return <code>true</code> if this schema definition is declared |
| | | * "obsolete", or <code>false</code> if not. |
| | | * @return {@code true} if this name form is "obsolete". |
| | | */ |
| | | public boolean isObsolete() { |
| | | return isObsolete; |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether the provided attribute type is included in the optional |
| | | * attribute list for this name form. |
| | | * Returns {@code true} if the provided attribute type is included in the |
| | | * list of optional attributes for this name form. |
| | | * |
| | | * @param attributeType |
| | | * The attribute type for which to make the determination. |
| | | * @return <code>true</code> if the provided attribute type is optional for |
| | | * this name form, or <code>false</code> if not. |
| | | * The attribute type. |
| | | * @return {@code true} if the provided attribute type is included in the |
| | | * list of optional attributes for this name form. |
| | | */ |
| | | public boolean isOptional(final AttributeType attributeType) { |
| | | return optionalAttributes.contains(attributeType); |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether the provided attribute type is included in the required |
| | | * attribute list for this name form. |
| | | * Returns {@code true} if the provided attribute type is included in the |
| | | * list of required attributes for this name form. |
| | | * |
| | | * @param attributeType |
| | | * The attribute type for which to make the determination. |
| | | * @return <code>true</code> if the provided attribute type is required by |
| | | * this name form, or <code>false</code> if not. |
| | | * The attribute type. |
| | | * @return {@code true} if the provided attribute type is included in the |
| | | * list of required attributes for this name form. |
| | | */ |
| | | public boolean isRequired(final AttributeType attributeType) { |
| | | return requiredAttributes.contains(attributeType); |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether the provided attribute type is in the list of required |
| | | * or optional attributes for this name form. |
| | | * Returns {@code true} if the provided attribute type is included in the |
| | | * list of optional or required attributes for this name form. |
| | | * |
| | | * @param attributeType |
| | | * The attribute type for which to make the determination. |
| | | * @return <code>true</code> if the provided attribute type is required or |
| | | * allowed for this name form, or <code>false</code> if it is not. |
| | | * The attribute type. |
| | | * @return {@code true} if the provided attribute type is included in the |
| | | * list of optional or required attributes for this name form. |
| | | */ |
| | | public boolean isRequiredOrOptional(final AttributeType attributeType) { |
| | | return isRequired(attributeType) || isOptional(attributeType); |
| | | } |
| | | |
| | | /** |
| | | * Returns the string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | @Override |
| | | void toStringContent(final StringBuilder buffer) { |
| | | buffer.append(oid); |
| | | |
| | | if (!names.isEmpty()) { |
| | | final Iterator<String> iterator = names.iterator(); |
| | | |
| | | final String firstName = iterator.next(); |
| | | if (iterator.hasNext()) { |
| | | buffer.append(" NAME ( '"); |
| | | buffer.append(firstName); |
| | | |
| | | while (iterator.hasNext()) { |
| | | buffer.append("' '"); |
| | | buffer.append(iterator.next()); |
| | | } |
| | | |
| | | buffer.append("' )"); |
| | | } else { |
| | | buffer.append(" NAME '"); |
| | |
| | | } |
| | | } |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | |
| | | if (isObsolete) { |
| | | buffer.append(" OBSOLETE"); |
| | |
| | | |
| | | if (!requiredAttributeOIDs.isEmpty()) { |
| | | final Iterator<String> iterator = requiredAttributeOIDs.iterator(); |
| | | |
| | | final String firstName = iterator.next(); |
| | | if (iterator.hasNext()) { |
| | | buffer.append(" MUST ( "); |
| | | buffer.append(firstName); |
| | | |
| | | while (iterator.hasNext()) { |
| | | buffer.append(" $ "); |
| | | buffer.append(iterator.next()); |
| | | } |
| | | |
| | | buffer.append(" )"); |
| | | } else { |
| | | buffer.append(" MUST "); |
| | |
| | | |
| | | if (!optionalAttributeOIDs.isEmpty()) { |
| | | final Iterator<String> iterator = optionalAttributeOIDs.iterator(); |
| | | |
| | | final String firstName = iterator.next(); |
| | | if (iterator.hasNext()) { |
| | | buffer.append(" MAY ( "); |
| | | buffer.append(firstName); |
| | | |
| | | while (iterator.hasNext()) { |
| | | buffer.append(" $ "); |
| | | buffer.append(iterator.next()); |
| | | } |
| | | |
| | | buffer.append(" )"); |
| | | } else { |
| | | buffer.append(" MAY "); |
| | |
| | | // The set of optional attribute types for this objectclass. |
| | | private final Set<String> optionalAttributeOIDs; |
| | | |
| | | // The definition string used to create this objectclass. |
| | | private final String definition; |
| | | |
| | | private Set<ObjectClass> superiorClasses = Collections.emptySet(); |
| | | private Set<AttributeType> declaredRequiredAttributes = Collections.emptySet(); |
| | | private Set<AttributeType> requiredAttributes = Collections.emptySet(); |
| | |
| | | final Set<String> requiredAttributeOIDs, final Set<String> optionalAttributeOIDs, |
| | | final ObjectClassType objectClassType, final Map<String, List<String>> extraProperties, |
| | | final String definition) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, definition); |
| | | |
| | | Validator.ensureNotNull(oid, names); |
| | | Validator.ensureNotNull(superiorClassOIDs, requiredAttributeOIDs, optionalAttributeOIDs, |
| | |
| | | this.objectClassType = objectClassType; |
| | | this.requiredAttributeOIDs = requiredAttributeOIDs; |
| | | this.optionalAttributeOIDs = optionalAttributeOIDs; |
| | | |
| | | if (definition != null) { |
| | | this.definition = definition; |
| | | } else { |
| | | this.definition = buildDefinition(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * The map of "extra" properties for this schema definition |
| | | */ |
| | | ObjectClass(final String description, final Map<String, List<String>> extraProperties) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, null); |
| | | this.oid = EXTENSIBLE_OBJECT_OBJECTCLASS_OID; |
| | | this.names = Collections.singletonList(EXTENSIBLE_OBJECT_OBJECTCLASS_NAME); |
| | | this.isObsolete = false; |
| | |
| | | this.objectClassType = ObjectClassType.AUXILIARY; |
| | | this.requiredAttributeOIDs = Collections.emptySet(); |
| | | this.optionalAttributeOIDs = Collections.emptySet(); |
| | | |
| | | this.definition = buildDefinition(); |
| | | } |
| | | |
| | | /** |
| | |
| | | return isRequired(attributeType) || isOptional(attributeType); |
| | | } |
| | | |
| | | /** |
| | | * Returns the string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | ObjectClass duplicate() { |
| | | return new ObjectClass(oid, names, description, isObsolete, superiorClassOIDs, |
| | | requiredAttributeOIDs, optionalAttributeOIDs, objectClassType, extraProperties, |
| | | definition); |
| | | return new ObjectClass(oid, names, getDescription(), isObsolete, superiorClassOIDs, |
| | | requiredAttributeOIDs, optionalAttributeOIDs, objectClassType, |
| | | getExtraProperties(), toString()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | } |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | |
| | | if (isObsolete) { |
| | | buffer.append(" OBSOLETE"); |
| | |
| | | // The next set of characters must be the OID. |
| | | final NameForm.Builder nameFormBuilder = |
| | | new NameForm.Builder( |
| | | SchemaUtils.readOID(reader, allowMalformedNamesAndOptions), this); |
| | | |
| | | SchemaUtils.readOID(reader, allowMalformedNamesAndOptions), this) |
| | | .definition(definition); |
| | | |
| | | // Required properties : |
| | | String structuralOID = null; |
| | |
| | | } |
| | | } |
| | | |
| | | nameFormBuilder.definition(definition); |
| | | |
| | | // Make sure that a structural class was specified. If not, then |
| | | // it cannot be valid and the name form cannot be build. |
| | | if (structuralOID == null) { |
| | |
| | | if (overwrite) { |
| | | nameFormBuilder.addToSchema(); |
| | | } else { |
| | | nameFormBuilder.addNoOverwriteToSchema(); |
| | | nameFormBuilder.addToSchemaNoOverwrite(); |
| | | } |
| | | } catch (final DecodeException e) { |
| | | final LocalizableMessage msg = |
| | |
| | | |
| | | package org.forgerock.opendj.ldap.schema; |
| | | |
| | | import static org.forgerock.opendj.ldap.schema.SchemaUtils.unmodifiableCopyOfExtraProperties; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.Collections; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import com.forgerock.opendj.util.Validator; |
| | | |
| | |
| | | * definitions). |
| | | */ |
| | | abstract class SchemaElement { |
| | | static abstract class SchemaElementBuilder<T extends SchemaElementBuilder<T>> { |
| | | private String definition; |
| | | private String description; |
| | | private final Map<String, List<String>> extraProperties; |
| | | private final SchemaBuilder schemaBuilder; |
| | | |
| | | SchemaElementBuilder(final SchemaBuilder schemaBuilder) { |
| | | this.schemaBuilder = schemaBuilder; |
| | | this.description = ""; |
| | | this.extraProperties = new LinkedHashMap<String, List<String>>(1); |
| | | } |
| | | |
| | | SchemaElementBuilder(final SchemaBuilder schemaBuilder, final SchemaElement copy) { |
| | | this.schemaBuilder = schemaBuilder; |
| | | this.description = copy.description; |
| | | this.extraProperties = new LinkedHashMap<String, List<String>>(copy.extraProperties); |
| | | } |
| | | |
| | | /** |
| | | * Sets the description. |
| | | * |
| | | * @param description |
| | | * The description, which may be {@code null} in which case |
| | | * the empty string will be used. |
| | | * @return This builder. |
| | | */ |
| | | public T description(final String description) { |
| | | this.description = description == null ? "" : description; |
| | | return getThis(); |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided collection of extended properties. |
| | | * |
| | | * @param extraProperties |
| | | * The collection of extended properties. |
| | | * @return This builder. |
| | | */ |
| | | public T extraProperties(final Map<String, List<String>> extraProperties) { |
| | | this.extraProperties.putAll(extraProperties); |
| | | return getThis(); |
| | | } |
| | | |
| | | /** |
| | | * Adds the provided extended property. |
| | | * |
| | | * @param extensionName |
| | | * The name of the extended property. |
| | | * @param extensionValues |
| | | * The optional list of values for the extended property. |
| | | * @return This builder. |
| | | */ |
| | | public T extraProperties(final String extensionName, final String... extensionValues) { |
| | | if (this.extraProperties.get(extensionName) != null) { |
| | | final List<String> tempExtraProperties = |
| | | new ArrayList<String>(this.extraProperties.get(extensionName)); |
| | | tempExtraProperties.addAll(Arrays.asList(extensionValues)); |
| | | this.extraProperties.put(extensionName, tempExtraProperties); |
| | | } else { |
| | | this.extraProperties.put(extensionName, Arrays.asList(extensionValues)); |
| | | } |
| | | return getThis(); |
| | | } |
| | | |
| | | /** |
| | | * Removes all extra properties. |
| | | * |
| | | * @return This builder. |
| | | */ |
| | | public T removeAllExtraProperties() { |
| | | this.extraProperties.clear(); |
| | | return getThis(); |
| | | } |
| | | |
| | | /** |
| | | * Removes the specified extended property. |
| | | * |
| | | * @param extensionName |
| | | * The name of the extended property. |
| | | * @param extensionValues |
| | | * The optional list of values for the extended property, |
| | | * which may be empty indicating that the entire property |
| | | * should be removed. |
| | | * @return This builder. |
| | | */ |
| | | public T removeExtraProperty(final String extensionName, final String... extensionValues) { |
| | | if (this.extraProperties.get(extensionName) != null && extensionValues.length > 0) { |
| | | final List<String> tempExtraProperties = |
| | | new ArrayList<String>(this.extraProperties.get(extensionName)); |
| | | tempExtraProperties.removeAll(Arrays.asList(extensionValues)); |
| | | this.extraProperties.put(extensionName, tempExtraProperties); |
| | | } else if (this.extraProperties.get(extensionName) != null) { |
| | | this.extraProperties.remove(extensionName); |
| | | } |
| | | return getThis(); |
| | | } |
| | | |
| | | T definition(final String definition) { |
| | | this.definition = definition; |
| | | return getThis(); |
| | | } |
| | | |
| | | String getDescription() { |
| | | return description; |
| | | } |
| | | |
| | | Map<String, List<String>> getExtraProperties() { |
| | | return extraProperties; |
| | | } |
| | | |
| | | SchemaBuilder getSchemaBuilder() { |
| | | return schemaBuilder; |
| | | } |
| | | |
| | | abstract T getThis(); |
| | | } |
| | | |
| | | /** |
| | | * Lazily created string representation. |
| | | */ |
| | | private String definition; |
| | | |
| | | // The description for this definition. |
| | | final String description; |
| | | private final String description; |
| | | |
| | | // The set of additional name-value pairs. |
| | | final Map<String, List<String>> extraProperties; |
| | | private final Map<String, List<String>> extraProperties; |
| | | |
| | | SchemaElement(final String description, final Map<String, List<String>> extraProperties) { |
| | | SchemaElement() { |
| | | this.description = ""; |
| | | this.extraProperties = Collections.<String, List<String>> emptyMap(); |
| | | this.definition = null; |
| | | } |
| | | |
| | | SchemaElement(final SchemaElementBuilder<?> builder) { |
| | | this.description = builder.description; |
| | | this.extraProperties = unmodifiableCopyOfExtraProperties(builder.extraProperties); |
| | | this.definition = builder.definition; |
| | | } |
| | | |
| | | SchemaElement(final String description, final Map<String, List<String>> extraProperties, |
| | | final String definition) { |
| | | Validator.ensureNotNull(description, extraProperties); |
| | | this.description = description; |
| | | |
| | | // Assumes caller has made the map unmodifiable. |
| | | this.extraProperties = extraProperties; |
| | | this.extraProperties = extraProperties; // Should already be unmodifiable. |
| | | this.definition = definition; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public abstract boolean equals(Object obj); |
| | | |
| | | /** |
| | | * Returns the description of this schema definition. |
| | | * Returns the description of this schema element, or the empty string if it |
| | | * does not have a description. |
| | | * |
| | | * @return The description of this schema definition. |
| | | * @return The description of this schema element, or the empty string if it |
| | | * does not have a description. |
| | | */ |
| | | public final String getDescription() { |
| | | |
| | | return description; |
| | | } |
| | | |
| | | /** |
| | | * Returns an unmodifiable list containing the values of the named "extra" |
| | | * property for this schema definition. |
| | | * Returns an unmodifiable map containing all of the extra properties |
| | | * associated with this schema element. |
| | | * |
| | | * @param name |
| | | * The name of the "extra" property whose values are to be |
| | | * returned. |
| | | * @return Returns an unmodifiable list containing the values of the named |
| | | * "extra" property for this schema definition, which may be empty |
| | | * if no such property is defined. |
| | | * @return An unmodifiable map containing all of the extra properties |
| | | * associated with this schema element. |
| | | */ |
| | | public final List<String> getExtraProperty(final String name) { |
| | | |
| | | final List<String> values = extraProperties.get(name); |
| | | return values != null ? values : Collections.<String> emptyList(); |
| | | } |
| | | |
| | | /** |
| | | * Returns an unmodifiable set containing the names of the "extra" |
| | | * properties associated with this schema definition. |
| | | * |
| | | * @return Returns an unmodifiable set containing the names of the "extra" |
| | | * properties associated with this schema definition. |
| | | */ |
| | | public final Set<String> getExtraPropertyNames() { |
| | | |
| | | return extraProperties.keySet(); |
| | | public final Map<String, List<String>> getExtraProperties() { |
| | | return extraProperties; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public abstract int hashCode(); |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public abstract String toString(); |
| | | |
| | | /** |
| | | * Builds a string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * Returns the string representation of this schema element as defined in |
| | | * RFC 2252. |
| | | * |
| | | * @return The string representation of this schema definition in the form |
| | | * specified in RFC 2252. |
| | | * @return The string representation of this schema element as defined in |
| | | * RFC 2252. |
| | | */ |
| | | final String buildDefinition() { |
| | | @Override |
| | | public final String toString() { |
| | | if (definition == null) { |
| | | definition = buildDefinition(); |
| | | } |
| | | return definition; |
| | | } |
| | | |
| | | final void appendDescription(final StringBuilder buffer) { |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | } |
| | | |
| | | abstract void toStringContent(StringBuilder buffer); |
| | | |
| | | private final String buildDefinition() { |
| | | final StringBuilder buffer = new StringBuilder(); |
| | | |
| | | buffer.append("( "); |
| | | |
| | | toStringContent(buffer); |
| | | |
| | | if (!extraProperties.isEmpty()) { |
| | | for (final Map.Entry<String, List<String>> e : extraProperties.entrySet()) { |
| | | |
| | | final String property = e.getKey(); |
| | | |
| | | final List<String> valueList = e.getValue(); |
| | | |
| | | buffer.append(" "); |
| | | buffer.append(property); |
| | | |
| | | if (valueList.size() == 1) { |
| | | buffer.append(" '"); |
| | | buffer.append(valueList.get(0)); |
| | | buffer.append("'"); |
| | | } else { |
| | | buffer.append(" ( "); |
| | | |
| | | for (final String value : valueList) { |
| | | buffer.append("'"); |
| | | buffer.append(value); |
| | | buffer.append("' "); |
| | | } |
| | | |
| | | buffer.append(")"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | buffer.append(" )"); |
| | | |
| | | return buffer.toString(); |
| | | } |
| | | |
| | | /** |
| | | * Appends a string representation of this schema definition's non-generic |
| | | * properties to the provided buffer. |
| | | * |
| | | * @param buffer |
| | | * The buffer to which the information should be appended. |
| | | */ |
| | | abstract void toStringContent(StringBuilder buffer); |
| | | } |
| | |
| | | */ |
| | | public final class Syntax extends SchemaElement { |
| | | private final String oid; |
| | | private final String definition; |
| | | private MatchingRule equalityMatchingRule; |
| | | private MatchingRule orderingMatchingRule; |
| | | private MatchingRule substringMatchingRule; |
| | |
| | | |
| | | Syntax(final String oid) { |
| | | super("", Collections.singletonMap("X-SUBST", Collections.singletonList(Schema |
| | | .getDefaultSyntax().getOID()))); |
| | | .getDefaultSyntax().getOID())), null); |
| | | |
| | | Validator.ensureNotNull(oid); |
| | | this.oid = oid; |
| | | this.definition = buildDefinition(); |
| | | this.impl = Schema.getDefaultSyntax().impl; |
| | | } |
| | | |
| | | Syntax(final String oid, final String description, |
| | | final Map<String, List<String>> extraProperties, final String definition, |
| | | final SyntaxImpl implementation) { |
| | | super(description, extraProperties); |
| | | super(description, extraProperties, definition); |
| | | |
| | | Validator.ensureNotNull(oid); |
| | | this.oid = oid; |
| | | |
| | | if (definition != null) { |
| | | this.definition = definition; |
| | | } else { |
| | | this.definition = buildDefinition(); |
| | | } |
| | | this.impl = implementation; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Retrieves a string representation of this attribute syntax in the format |
| | | * defined in RFC 2252. |
| | | * |
| | | * @return A string representation of this attribute syntax in the format |
| | | * defined in RFC 2252. |
| | | */ |
| | | @Override |
| | | public String toString() { |
| | | return definition; |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether the provided value is acceptable for use in an |
| | | * attribute with this syntax. If it is not, then the reason may be appended |
| | | * to the provided buffer. |
| | |
| | | } |
| | | |
| | | Syntax duplicate() { |
| | | return new Syntax(oid, description, extraProperties, definition, impl); |
| | | return new Syntax(oid, getDescription(), getExtraProperties(), toString(), impl); |
| | | } |
| | | |
| | | @Override |
| | | void toStringContent(final StringBuilder buffer) { |
| | | buffer.append(oid); |
| | | |
| | | if (description != null && description.length() > 0) { |
| | | buffer.append(" DESC '"); |
| | | buffer.append(description); |
| | | buffer.append("'"); |
| | | } |
| | | appendDescription(buffer); |
| | | } |
| | | |
| | | void validate(final Schema schema, final List<LocalizableMessage> warnings) |
| | |
| | | this.schema = schema; |
| | | if (impl == null) { |
| | | // See if we need to override the implementation of the syntax |
| | | for (final Map.Entry<String, List<String>> property : extraProperties.entrySet()) { |
| | | for (final Map.Entry<String, List<String>> property : getExtraProperties().entrySet()) { |
| | | // Enums are handled in the schema builder. |
| | | if (property.getKey().equalsIgnoreCase("x-subst")) { |
| | | /** |
| | |
| | | import com.forgerock.opendj.util.Validator; |
| | | |
| | | /** |
| | | * Generator of entries based on a {@code TemplateFile template file}, which can |
| | | * be provided as a file, a list of lines, an array of lines, or an input |
| | | * stream. |
| | | * A template driven entry generator, as used by the make-ldif tool. |
| | | * <p> |
| | | * To build a generator with all default values, including default template |
| | | * file, use the empty constructor: |
| | | * To build a generator with default values, including default template file, |
| | | * use the empty constructor: |
| | | * |
| | | * <pre> |
| | | * generator = new EntryGenerator(); |
| | | * generator = new EntryGenerator(); |
| | | * </pre> |
| | | * <p> |
| | | * To build a generator with some custom values, use the non-empty constructor |
| | | * and the <code>set</code> methods: |
| | | * |
| | | * <pre> |
| | | * generator = new EntryGenerator(templatePath) |
| | | * .setResourcePath(path) |
| | | * .setSchema(schema) |
| | | * generator = new EntryGenerator(templatePath).setResourcePath(path).setSchema(schema) |
| | | * </pre> |
| | | */ |
| | | public final class EntryGenerator implements EntryReader { |
| | |
| | | * Sets the random seed to use when generating entries. |
| | | * |
| | | * @param seed |
| | | * Seed to use. |
| | | * The random seed to use. |
| | | * @return A reference to this {@code EntryGenerator}. |
| | | */ |
| | | public EntryGenerator setRandomSeed(final int seed) { |
| | |
| | | * names, last names, or other custom resources. |
| | | * |
| | | * @param path |
| | | * Resource path. |
| | | * The resource path. |
| | | * @return A reference to this {@code EntryGenerator}. |
| | | */ |
| | | public EntryGenerator setResourcePath(final String path) { |
| | |
| | | * the template file. |
| | | * |
| | | * @param name |
| | | * Name of the constant. |
| | | * The name of the constant. |
| | | * @param value |
| | | * Value of the constant. |
| | | * The value of the constant. |
| | | * @return A reference to this {@code EntryGenerator}. |
| | | */ |
| | | public EntryGenerator setConstant(String name, Object value) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Checks if there are some warning(s) after the parsing of template file. |
| | | * Checks if there are some warning(s) after parsing the template file. |
| | | * <p> |
| | | * Warnings are available only after the first call to {@code hasNext()} or |
| | | * {@code readEntry()} methods. |
| | | * |
| | | * @return true if there is at least one warning |
| | | * @return {@code true} if there is at least one warning. |
| | | */ |
| | | public boolean hasWarning() { |
| | | public boolean hasWarnings() { |
| | | return !warnings.isEmpty(); |
| | | } |
| | | |
| | | /** |
| | | * Returns the warnings generated by the parsing of template file. |
| | | * <p> |
| | | * Warnings are available only after the first call to {@code hasNext()} |
| | | * or {@code readEntry()} methods. |
| | | * Warnings are available only after the first call to {@code hasNext()} or |
| | | * {@code readEntry()} methods. |
| | | * |
| | | * @return the list of warnings, which is empty if there is no warning |
| | | * @return The list of warnings, which is empty if there are no warnings. |
| | | */ |
| | | public List<LocalizableMessage> getWarnings() { |
| | | return Collections.unmodifiableList(warnings); |
| | |
| | | import java.util.TreeMap; |
| | | |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.ASN1Writer; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.ldap.AVA; |
| | | import org.forgerock.opendj.ldap.Attribute; |
| | | import org.forgerock.opendj.ldap.AttributeDescription; |
| | |
| | | import org.forgerock.opendj.ldap.requests.ModifyRequest; |
| | | import org.forgerock.opendj.ldap.requests.Requests; |
| | | import org.forgerock.opendj.ldap.requests.SearchRequest; |
| | | import org.forgerock.opendj.ldap.responses.Responses; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.schema.AttributeUsage; |
| | | import org.forgerock.opendj.ldap.schema.Schema; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPUtils; |
| | | |
| | | /** |
| | | * This class contains common utility methods for creating and manipulating |
| | | * readers and writers. |
| | |
| | | return entries; |
| | | } |
| | | |
| | | private static SearchResultEntry decodeEntry(final byte[] asn1EntryFormat) { |
| | | final ASN1Reader readerASN1 = ASN1.getReader(asn1EntryFormat); |
| | | private static Entry decodeEntry(final byte[] asn1EntryFormat) { |
| | | try { |
| | | final SearchResultEntry sr = |
| | | LDAPUtils.decodeSearchResultEntry(readerASN1, new DecodeOptions()); |
| | | readerASN1.close(); |
| | | return sr; |
| | | return LDAP.readEntry(ASN1.getReader(asn1EntryFormat), new DecodeOptions()); |
| | | } catch (IOException ex) { |
| | | throw new IllegalStateException(ex); |
| | | } |
| | |
| | | |
| | | private static byte[][] encodeEntry(final Entry entry) { |
| | | final byte[][] bEntry = new byte[2][]; |
| | | |
| | | final ByteStringBuilder bsb = new ByteStringBuilder(); |
| | | final ASN1Writer writer = ASN1.getWriter(bsb); |
| | | // Store normalized DN |
| | | bEntry[0] = getBytes(entry.getName().toNormalizedString()); |
| | | try { |
| | | // Store ASN1 representation of the entry. |
| | | LDAPUtils.encodeSearchResultEntry(writer, Responses.newSearchResultEntry(entry)); |
| | | final ByteStringBuilder bsb = new ByteStringBuilder(); |
| | | LDAP.writeEntry(ASN1.getWriter(bsb), entry); |
| | | bEntry[1] = bsb.toByteArray(); |
| | | return bEntry; |
| | | } catch (final IOException ioe) { |
| | |
| | | * |
| | | * @see EntryGenerator |
| | | */ |
| | | class TemplateFile { |
| | | final class TemplateFile { |
| | | |
| | | /** Default resource path used if no resource path is provided. */ |
| | | private static final File DEFAULT_RESOURCES_PATH = new File("org/forgerock/opendj/ldif"); |
| | |
| | | * The path provided for the file, which can be absolute or |
| | | * relative. |
| | | * @return A reader on the file, or <code>null</code> if it could not be |
| | | * found. It is the responsability of caller to close the returned |
| | | * found. It is the responsibility of caller to close the returned |
| | | * reader. |
| | | */ |
| | | @SuppressWarnings("resource") |
| | | BufferedReader getReader(final String filePath) { |
| | | BufferedReader reader = null; |
| | | File file = new File(filePath); |
| | |
| | | * The line number on which this template line appears in the template |
| | | * file. |
| | | */ |
| | | @SuppressWarnings("unused") |
| | | private final int lineNumber; |
| | | |
| | | /** The set of tags for this template line. */ |
| | | private final List<TemplateTag> tags; |
| | | |
| | | /** Whether this line corresponds to an URL value or not. */ |
| | | @SuppressWarnings("unused") |
| | | private final boolean isURL; |
| | | |
| | | /** Whether this line corresponds to a base64 encoded value or not. */ |
| | | @SuppressWarnings("unused") |
| | | private final boolean isBase64; |
| | | |
| | | /** |
| | |
| | | * Represents a tag that may be used in a template line when generating entries. |
| | | * It can be used to generate content. |
| | | * |
| | | * @see TemplateFile |
| | | * @see EntryGenerator |
| | | */ |
| | | abstract class TemplateTag { |
| | |
| | | import java.io.IOException; |
| | | |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | | import org.forgerock.opendj.ldap.DecodeException; |
| | | import org.forgerock.opendj.ldap.Entry; |
| | | import org.forgerock.opendj.ldap.LDAPOptions; |
| | | import org.forgerock.opendj.ldap.LinkedHashMapEntry; |
| | |
| | | import org.forgerock.opendj.ldap.responses.Result; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultReference; |
| | | import org.forgerock.opendj.ldap.spi.AbstractLDAPMessageHandler; |
| | | import org.forgerock.opendj.ldap.spi.LDAPMessageHandler; |
| | | import org.forgerock.opendj.ldap.spi.UnexpectedRequestException; |
| | | import org.forgerock.opendj.ldap.spi.UnexpectedResponseException; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | |
| | | |
| | | @DataProvider |
| | | protected Object[][] messagesFactories() { |
| | | return new Object[][] { |
| | | abandonRequest(), |
| | | addRequest(), |
| | | addResult(), |
| | | abandonRequest(), |
| | | bindRequest(), |
| | | bindResult(), |
| | | compareRequest(), |
| | | compareResult(), |
| | | deleteRequest(), |
| | | deleteResult(), |
| | | extendedRequest(), |
| | | extendedResult(), |
| | | intermediateResponse(), |
| | | modifyDNRequest(), |
| | | modifyDNResult(), |
| | | modifyRequest(), |
| | | modifyResult(), |
| | | searchRequest(), |
| | | searchResult(), |
| | | searchResultEntry(), |
| | | searchResultReference(), |
| | | unbindRequest(), |
| | | unrecognizedMessage() |
| | | }; |
| | | return new Object[][] { abandonRequest(), addRequest(), addResult(), abandonRequest(), |
| | | bindRequest(), bindResult(), compareRequest(), compareResult(), deleteRequest(), |
| | | deleteResult(), extendedRequest(), extendedResult(), intermediateResponse(), |
| | | modifyDNRequest(), modifyDNResult(), modifyRequest(), modifyResult(), searchRequest(), |
| | | searchResult(), searchResultEntry(), searchResultReference(), unbindRequest(), |
| | | unrecognizedMessage() }; |
| | | } |
| | | |
| | | Object[] abandonRequest() { |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void abandonRequest(int messageID, AbandonRequest request) throws UnexpectedRequestException, |
| | | IOException { |
| | | public void abandonRequest(int messageID, AbandonRequest request) |
| | | throws DecodeException, IOException { |
| | | assertThat(request.getRequestID()).isEqualTo(requestID); |
| | | } |
| | | } }; |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void addRequest(int messageID, AddRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | public void addRequest(int messageID, AddRequest request) throws DecodeException, |
| | | IOException { |
| | | assertThat(request.getName().toString()).isEqualTo(TEST_DN); |
| | | } |
| | | } }; |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeAddResult(MESSAGE_ID, Responses.newResult(resultCode).setMatchedDN(TEST_DN)); |
| | | writer.writeAddResult(MESSAGE_ID, Responses.newResult(resultCode).setMatchedDN( |
| | | TEST_DN)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void addResult(int messageID, Result result) throws UnexpectedResponseException, IOException { |
| | | public void addResult(int messageID, Result result) throws DecodeException, IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | assertThat(result.getMatchedDN().toString()).isEqualTo(TEST_DN); |
| | | } |
| | |
| | | Object[] bindRequest() { |
| | | final int version = 1; |
| | | final byte type = 0x01; |
| | | final byte[] value = new byte[] {0x01, 0x02}; |
| | | final byte[] value = new byte[] { 0x01, 0x02 }; |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeBindRequest(MESSAGE_ID, version, |
| | | Requests.newGenericBindRequest(TEST_DN, type, value)); |
| | | writer.writeBindRequest(MESSAGE_ID, version, Requests.newGenericBindRequest( |
| | | TEST_DN, type, value)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void bindRequest(final int messageID, final int version, final GenericBindRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | public void bindRequest(final int messageID, final int version, |
| | | final GenericBindRequest request) throws DecodeException, IOException { |
| | | assertThat(request.getAuthenticationType()).isEqualTo(type); |
| | | assertThat(request.getAuthenticationValue()).isEqualTo(value); |
| | | assertThat(request.getName()).isEqualTo(TEST_DN); |
| | |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void bindResult(final int messageID, final BindResult result) |
| | | throws UnexpectedRequestException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | } |
| | | } }; |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeCompareRequest(MESSAGE_ID, Requests.newCompareRequest(TEST_DN, description, value)); |
| | | writer.writeCompareRequest(MESSAGE_ID, Requests.newCompareRequest(TEST_DN, |
| | | description, value)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void compareRequest(final int messageID, final CompareRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(request.getName().toString()).isEqualTo(TEST_DN); |
| | | assertThat(request.getAttributeDescription().toString()).isEqualTo(description); |
| | | assertThat(request.getAssertionValue().toString()).isEqualTo(value); |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void compareResult(int messageID, CompareResult result) |
| | | throws UnexpectedResponseException, IOException { |
| | | public void compareResult(int messageID, CompareResult result) throws DecodeException, |
| | | IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | } |
| | | } }; |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void deleteRequest(int messageID, DeleteRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | public void deleteRequest(int messageID, DeleteRequest request) throws DecodeException, |
| | | IOException { |
| | | assertThat(request.getName().toString()).isEqualTo(TEST_DN); |
| | | } |
| | | } }; |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void deleteResult(int messageID, Result result) throws UnexpectedResponseException, IOException { |
| | | public void deleteResult(int messageID, Result result) throws DecodeException, |
| | | IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | } |
| | | } }; |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeExtendedRequest(MESSAGE_ID, Requests.newCancelExtendedRequest(requestID)); |
| | | writer.writeExtendedRequest(MESSAGE_ID, Requests |
| | | .newCancelExtendedRequest(requestID)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public <R extends ExtendedResult> void extendedRequest(int messageID, ExtendedRequest<R> request) |
| | | throws UnexpectedRequestException, IOException { |
| | | public <R extends ExtendedResult> void extendedRequest(int messageID, |
| | | ExtendedRequest<R> request) throws DecodeException, IOException { |
| | | CancelExtendedRequest cancelRequest = |
| | | CancelExtendedRequest.DECODER.decodeExtendedRequest( |
| | | request, new LDAPOptions().getDecodeOptions()); |
| | | CancelExtendedRequest.DECODER.decodeExtendedRequest(request, |
| | | new LDAPOptions().getDecodeOptions()); |
| | | assertThat(cancelRequest.getOID().toString()).isEqualTo(oidCancel); |
| | | assertThat(cancelRequest.getRequestID()).isEqualTo(requestID); |
| | | } |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeExtendedResult(MESSAGE_ID, |
| | | Responses.newGenericExtendedResult(resultCode).setOID(oidCancel)); |
| | | writer.writeExtendedResult(MESSAGE_ID, Responses.newGenericExtendedResult( |
| | | resultCode).setOID(oidCancel)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void extendedResult(int messageID, ExtendedResult result) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | assertThat(result.getOID()).isEqualTo(oidCancel); |
| | | } |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeIntermediateResponse(MESSAGE_ID, |
| | | Responses.newGenericIntermediateResponse(oid, responseValue)); |
| | | writer.writeIntermediateResponse(MESSAGE_ID, Responses |
| | | .newGenericIntermediateResponse(oid, responseValue)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void intermediateResponse(int messageID, IntermediateResponse response) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(response.getOID()).isEqualTo(oid); |
| | | assertThat(response.getValue()).isEqualTo(ByteString.valueOf(responseValue)); |
| | | } |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeModifyDNRequest(MESSAGE_ID, Requests.newModifyDNRequest(TEST_DN, newRDN)); |
| | | writer.writeModifyDNRequest(MESSAGE_ID, Requests |
| | | .newModifyDNRequest(TEST_DN, newRDN)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void modifyDNRequest(int messageID, ModifyDNRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(request.getName().toString()).isEqualTo(TEST_DN); |
| | | assertThat(request.getNewRDN().toString()).isEqualTo(newRDN); |
| | | } |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void modifyDNResult(int messageID, Result result) |
| | | throws UnexpectedResponseException, IOException { |
| | | public void modifyDNResult(int messageID, Result result) throws DecodeException, |
| | | IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | } |
| | | } }; |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void modifyRequest(int messageID, ModifyRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | public void modifyRequest(int messageID, ModifyRequest request) throws DecodeException, |
| | | IOException { |
| | | assertThat(request.getName().toString()).isEqualTo(TEST_DN); |
| | | } |
| | | } }; |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void modifyResult(int messageID, Result result) throws UnexpectedResponseException, IOException { |
| | | public void modifyResult(int messageID, Result result) throws DecodeException, |
| | | IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | } |
| | | } }; |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeSearchRequest(MESSAGE_ID, Requests.newSearchRequest(TEST_DN, scope, filter, attribute)); |
| | | writer.writeSearchRequest(MESSAGE_ID, Requests.newSearchRequest(TEST_DN, scope, |
| | | filter, attribute)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void searchRequest(int messageID, SearchRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | public void searchRequest(int messageID, SearchRequest request) throws DecodeException, |
| | | IOException { |
| | | assertThat(request.getName().toString()).isEqualTo(TEST_DN); |
| | | assertThat(request.getScope()).isEqualTo(scope); |
| | | assertThat(request.getFilter().toString()).isEqualTo(filter); |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void searchResult(int messageID, Result result) throws UnexpectedResponseException, IOException { |
| | | public void searchResult(int messageID, Result result) throws DecodeException, |
| | | IOException { |
| | | assertThat(result.getResultCode()).isEqualTo(resultCode); |
| | | } |
| | | } }; |
| | | } |
| | | |
| | | Object[] searchResultEntry() { |
| | | final Entry entry = new LinkedHashMapEntry( |
| | | "dn: cn=test", |
| | | "objectClass: top", |
| | | "objectClass: test"); |
| | | final Entry entry = |
| | | new LinkedHashMapEntry("dn: cn=test", "objectClass: top", "objectClass: test"); |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void searchResultEntry(int messageID, SearchResultEntry resultEntry) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(resultEntry).isEqualTo(entry); |
| | | } |
| | | } }; |
| | |
| | | return new Object[] { new LDAPWrite() { |
| | | @Override |
| | | public void perform(LDAPWriter<? extends ASN1Writer> writer) throws IOException { |
| | | writer.writeSearchResultReference(MESSAGE_ID, Responses.newSearchResultReference(uri)); |
| | | writer.writeSearchResultReference(MESSAGE_ID, Responses |
| | | .newSearchResultReference(uri)); |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void searchResultReference(int messageID, SearchResultReference reference) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(reference.getURIs()).containsExactly(uri); |
| | | } |
| | | } }; |
| | |
| | | } |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void unbindRequest(int messageID, UnbindRequest request) |
| | | throws UnexpectedRequestException, IOException { |
| | | public void unbindRequest(int messageID, UnbindRequest request) throws DecodeException, |
| | | IOException { |
| | | assertThat(request).isNotNull(); |
| | | } |
| | | } }; |
| | |
| | | }, new AbstractLDAPMessageHandler() { |
| | | @Override |
| | | public void unrecognizedMessage(int messageID, byte tag, ByteString message) |
| | | throws UnexpectedRequestException, IOException { |
| | | throws DecodeException, IOException { |
| | | assertThat(messageID).isEqualTo(MESSAGE_ID); |
| | | assertThat(tag).isEqualTo(messageTag); |
| | | assertThat(message).isEqualTo(messageBytes); |
| | |
| | | |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | | import static org.forgerock.opendj.ldap.TestCaseUtils.*; |
| | | |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.TYPE_AUTHENTICATION_SASL; |
| | | import static org.forgerock.opendj.ldap.TestCaseUtils.findFreeSocketAddress; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.SocketAddress; |
| | |
| | | |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.ldap.controls.Control; |
| | | import org.forgerock.opendj.ldap.controls.ControlDecoder; |
| | | import org.forgerock.opendj.ldap.requests.AbandonRequest; |
| | |
| | | // TODO: all bind types. |
| | | final AbandonableRequest abReq = new AbandonableRequest(request); |
| | | requestsInProgress.put(context, abReq); |
| | | if (request.getAuthenticationType() == TYPE_AUTHENTICATION_SASL |
| | | if (request.getAuthenticationType() == LDAP.TYPE_AUTHENTICATION_SASL |
| | | && request instanceof GenericBindRequest) { |
| | | ASN1Reader reader = |
| | | ASN1.getReader(((GenericBindRequest) request).getAuthenticationValue()); |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2012 ForgeRock AS. |
| | | * Copyright 2012-2013 ForgeRock AS. |
| | | */ |
| | | package org.forgerock.opendj.ldap; |
| | | |
| | |
| | | * A connection event listener which records events and signals when it has been |
| | | * notified. |
| | | */ |
| | | @SuppressWarnings("javadoc") |
| | | public final class MockConnectionEventListener implements ConnectionEventListener { |
| | | private final CountDownLatch closedLatch = new CountDownLatch(1); |
| | | private final CountDownLatch errorLatch = new CountDownLatch(1); |
| | |
| | | |
| | | import static org.testng.Assert.assertNotNull; |
| | | |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPConstants; |
| | | |
| | | /** |
| | | * Tests the BIND requests. |
| | |
| | | @Test(dataProvider = "testRequests") |
| | | public void testAuthType(final BindRequest request) throws Exception { |
| | | final byte b = request.getAuthenticationType(); |
| | | if (!(b == LDAPConstants.TYPE_AUTHENTICATION_SASL || b == LDAPConstants.TYPE_AUTHENTICATION_SIMPLE)) { |
| | | if (!(b == LDAP.TYPE_AUTHENTICATION_SASL || b == LDAP.TYPE_AUTHENTICATION_SIMPLE)) { |
| | | throw new Exception("Invalid bind type"); |
| | | } |
| | | } |
| | |
| | | import org.testng.annotations.DataProvider; |
| | | |
| | | /** |
| | | * @author sin |
| | | * Tests compare requests. |
| | | */ |
| | | @SuppressWarnings("javadoc") |
| | | public class CompareRequestTestCase extends RequestTestCase { |
| | |
| | | import static com.forgerock.opendj.util.StaticUtils.EMPTY_BYTES; |
| | | import static com.forgerock.opendj.util.StaticUtils.getBytes; |
| | | |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.testng.annotations.DataProvider; |
| | | |
| | | import com.forgerock.opendj.ldap.LDAPConstants; |
| | | |
| | | /** |
| | | * Tests Generic Bind requests. |
| | |
| | | @Override |
| | | protected GenericBindRequest[] createTestRequests() throws Exception { |
| | | return new GenericBindRequest[] { |
| | | Requests.newGenericBindRequest(LDAPConstants.TYPE_AUTHENTICATION_SASL, EMPTY_BYTES), |
| | | Requests.newGenericBindRequest(LDAPConstants.TYPE_AUTHENTICATION_SIMPLE, getBytes("password")), |
| | | Requests.newGenericBindRequest("username", LDAPConstants.TYPE_AUTHENTICATION_SIMPLE, |
| | | Requests.newGenericBindRequest(LDAP.TYPE_AUTHENTICATION_SASL, EMPTY_BYTES), |
| | | Requests.newGenericBindRequest(LDAP.TYPE_AUTHENTICATION_SIMPLE, getBytes("password")), |
| | | Requests.newGenericBindRequest("username", LDAP.TYPE_AUTHENTICATION_SIMPLE, |
| | | getBytes("password")) |
| | | }; |
| | | } |
| | |
| | | @Test(dataProvider = "equalsTestData") |
| | | public final void testEquals(final SchemaElement e1, final SchemaElement e2, |
| | | final boolean result) throws Exception { |
| | | |
| | | Assert.assertEquals(e1.equals(e2), result); |
| | | Assert.assertEquals(e2.equals(e1), result); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Check that the {@link SchemaElement#getExtraProperty(String)} method |
| | | * Check that the {@link SchemaElement#getExtraProperties()} method |
| | | * returns values. |
| | | * |
| | | * @throws Exception |
| | |
| | | final SchemaElement e = getElement("", props); |
| | | |
| | | int i = 0; |
| | | for (final String value : e.getExtraProperty("test")) { |
| | | for (final String value : e.getExtraProperties().get("test")) { |
| | | Assert.assertEquals(value, values.get(i)); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Check that the {@link SchemaElement#getExtraProperty(String)} method |
| | | * Check that the {@link SchemaElement#getExtraProperties()} method |
| | | * returns <code>null</code> when there is no property. |
| | | * |
| | | * @throws Exception |
| | |
| | | @Test |
| | | public final void testGetExtraPropertyDefault() throws Exception { |
| | | final SchemaElement e = getElement("", EMPTY_PROPS); |
| | | Assert.assertTrue(e.getExtraProperty("test").isEmpty()); |
| | | } |
| | | |
| | | /** |
| | | * Check that the {@link SchemaElement#getExtraPropertyNames()} method. |
| | | * |
| | | * @throws Exception |
| | | * If the test failed unexpectedly. |
| | | */ |
| | | @Test |
| | | public final void testGetExtraPropertyNames() throws Exception { |
| | | final SchemaElement e = getElement("", EMPTY_PROPS); |
| | | Assert.assertTrue(e.getExtraProperty("test").isEmpty()); |
| | | Assert.assertNull(e.getExtraProperties().get("test")); |
| | | } |
| | | |
| | | /** |
| | |
| | | @Test(dataProvider = "equalsTestData") |
| | | public final void testHashCode(final SchemaElement e1, final SchemaElement e2, |
| | | final boolean result) throws Exception { |
| | | |
| | | Assert.assertEquals(e1.hashCode() == e2.hashCode(), result); |
| | | } |
| | | |
| | |
| | | .buildNameForm("1.3.6.1.4.1.1466.115.121.1.35") |
| | | .structuralObjectClassOID("person") |
| | | .requiredAttributes("sn", "cn") // ("cn, sn") is not supported. |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | |
| | | assertThat(schema.getWarnings()).isEmpty(); |
| | |
| | | .structuralObjectClassOID("person") |
| | | .names("MyNewForm") |
| | | .requiredAttributes("sn", "cn") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .names("MyNewForm") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("owner") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("owner") |
| | | .extraProperties("X-ORIGIN", "RFC xxx") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | assertThat(schema.getNameForms().size()).isGreaterThan(0); |
| | | |
| | | for (final NameForm nf : schema.getNameForms()) { |
| | | |
| | | assertThat(nf.hasName("hasAName ?")).isFalse(); |
| | | assertThat(nf.getNameOrOID()).isEqualTo("MyNewForm"); |
| | | assertThat(nf.getOID()).isEqualTo("1.3.6.1.4.1.1466.115.121.1.35"); |
| | | assertThat(nf.getExtraProperty("X-ORIGIN").get(0)).isEqualTo("RFC xxx"); |
| | | |
| | | assertThat(nf.getExtraProperties().get("X-ORIGIN").get(0)).isEqualTo("RFC xxx"); |
| | | assertThat(nf.toString()).isEqualTo( |
| | | "( 1.3.6.1.4.1.1466.115.121.1.35 NAME 'MyNewForm' OC person " |
| | | + "MUST ( sn $ cn ) MAY owner X-ORIGIN 'RFC xxx' )"); |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .structuralObjectClassOID("person") |
| | | .requiredAttributes("sn, cn") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | } |
| | |
| | | .names("MyNewForm") |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn, cn") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | } |
| | |
| | | .structuralObjectClassOID("person") |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes() |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | } |
| | |
| | | .names("MyNewForm") |
| | | .structuralObjectClassOID("person") |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | } |
| | |
| | | .structuralObjectClassOID("person") |
| | | .requiredAttributes("sn, cn") |
| | | .requiredAttributes((String[]) null) |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | } |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | // .optionalAttributeOIDs("") empty by default. |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | } |
| | |
| | | .requiredAttributes("sn") |
| | | .removeRequiredAttribute("unknown") |
| | | .removeOptionalAttribute("optionalunknown") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | assertThat(schema.getNameForms()).isNotEmpty(); |
| | | final NameForm nf = schema.getNameForms().iterator().next(); |
| | | assertThat(nf.getOID()).isEqualTo("1.3.6.1.4.1.1466.115.121.1.35"); |
| | | assertThat(nf.getExtraPropertyNames()).isNotEmpty(); |
| | | assertThat(nf.getExtraProperties()).isNotEmpty(); |
| | | |
| | | // @formatter:off |
| | | assertThat(nf.toString()).isEqualTo( |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema(); |
| | | .addToSchemaNoOverwrite(); |
| | | |
| | | Schema schema = sb.toSchema(); |
| | | assertThat(schema.getWarnings()).isEmpty(); |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema(); |
| | | .addToSchemaNoOverwrite(); |
| | | |
| | | Schema schema = sb.toSchema(); |
| | | assertThat(schema.getWarnings()).isEmpty(); |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .names("MyNewForm") |
| | | .structuralObjectClassOID("person") |
| | | .requiredAttributes("sn", "cn") |
| | | .addNoOverwriteToSchema().toSchema(); |
| | | .addToSchemaNoOverwrite().toSchema(); |
| | | final NameForm nf2 = schema2.getNameForm("MyNewForm"); |
| | | |
| | | assertThat(nf1.equals(nf2)).isTrue(); |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | final NameForm nf1 = schema.getNameForms().iterator().next(); |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormCheckingTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .optionalAttributes("owner") |
| | | .optionalAttributes("l") |
| | | .names("Rock") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | |
| | | assertThat(nf.getNames().get(0)).isEqualTo("multipleAttributes"); |
| | | assertThat(nf.getNames().get(1)).isEqualTo("Rock"); |
| | | assertThat(nf.getExtraProperty("X-ORIGIN").get(0)) |
| | | assertThat(nf.getExtraProperties().get("X-ORIGIN").get(0)) |
| | | .isEqualTo("NameFormCheckingTestCase"); |
| | | assertThat(nf.getExtraProperty("X-ORIGIN").get(1)).isEqualTo( |
| | | assertThat(nf.getExtraProperties().get("X-ORIGIN").get(1)).isEqualTo( |
| | | "NameFormCheckingTestCase2"); |
| | | |
| | | assertThat(nf.getStructuralClass().getNameOrOID()).isEqualTo("person"); |
| | |
| | | .removeName("nameform2") |
| | | .removeRequiredAttribute("cn") |
| | | .removeOptionalAttribute("l") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .extraProperties("FROM", "NameFormTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .toSchema(); |
| | | // @formatter:on |
| | | |
| | |
| | | .removeOptionalAttribute("nonExistentUid") |
| | | .requiredAttributes("street") |
| | | .removeRequiredAttribute("sn") |
| | | .removeExtraProperties("X-ORIGIN", "extra") |
| | | .removeExtraProperties("X-ORIGIN", "Forgerock") |
| | | .removeExtraProperties("FROM", null); |
| | | .removeExtraProperty("X-ORIGIN", "extra") |
| | | .removeExtraProperty("X-ORIGIN", "Forgerock") |
| | | .removeExtraProperty("FROM"); |
| | | |
| | | // @formatter:on |
| | | sb.addSchema(schema, true); |
| | | sb.addSchema(nfBuilder.addToSchema().toSchema(), true); |
| | |
| | | assertThat(dolly.getRequiredAttributes().toString()).contains("cn"); |
| | | |
| | | assertThat(dolly.getOptionalAttributes().size()).isEqualTo(1); |
| | | assertThat(dolly.getExtraProperty("X-ORIGIN").size()).isEqualTo(1); |
| | | assertThat(dolly.getExtraProperty("FROM")).isEmpty(); |
| | | assertThat(dolly.getExtraProperties().get("X-ORIGIN").size()).isEqualTo(1); |
| | | assertThat(dolly.getExtraProperties().get("FROM")).isNull(); |
| | | } |
| | | |
| | | /** |
| | |
| | | .extraProperties("FROM", "NameFormTestCase") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema(); |
| | | .addToSchemaNoOverwrite(); |
| | | |
| | | Schema schema = sb.toSchema(); |
| | | assertThat(schema.getWarnings()).isEmpty(); |
| | |
| | | |
| | | final NameForm nf = schema.getNameForms().iterator().next(); |
| | | assertThat(nf.getOID()).isEqualTo("1.3.6.1.4.1.1466.115.121.1.35"); |
| | | assertThat(nf.getRequiredAttributes().size()).isEqualTo(2); |
| | | assertThat(nf.getOptionalAttributes().size()).isEqualTo(2); |
| | | assertThat(nf.getExtraPropertyNames().size()).isEqualTo(2); |
| | | assertThat(nf.getRequiredAttributes()).hasSize(2); |
| | | assertThat(nf.getOptionalAttributes()).hasSize(2); |
| | | assertThat(nf.getExtraProperties()).hasSize(2); |
| | | |
| | | sb.buildNameForm(nf) |
| | | .removeAllNames() |
| | |
| | | .removeName("thisOneDoesntExist") |
| | | .oid("1.3.6.1.4.1.1466.115.121.1.36") |
| | | .removeAllOptionalAttributes() |
| | | .clearExtraProperties() |
| | | .removeAllExtraProperties() |
| | | .removeAllRequiredAttributes() |
| | | .requiredAttributes("businessCategory") |
| | | .addToSchema(); |
| | |
| | | assertThat(dolly.getRequiredAttributes().size()).isEqualTo(1); |
| | | assertThat(dolly.getRequiredAttributes().iterator().next().getOID()).isEqualTo("2.5.4.15"); |
| | | assertThat(dolly.getRequiredAttributes().iterator().next().getNameOrOID()).isEqualTo("businessCategory"); |
| | | |
| | | assertThat(dolly.getOptionalAttributes().size()).isEqualTo(0); |
| | | |
| | | assertThat(dolly.getExtraPropertyNames().size()).isEqualTo(0); |
| | | assertThat(dolly.getOptionalAttributes()).isEmpty(); |
| | | assertThat(dolly.getExtraProperties()).isEmpty(); |
| | | } |
| | | |
| | | /** |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormTestCase", "Forgerock", "extra") |
| | | .requiredAttributes("sn", "cn") |
| | | .optionalAttributes("description", "uid") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .buildNameForm("1.3.6.1.4.1.1466.115.121.1.36") |
| | | .description("Description of the second form") |
| | | .names("SecondForm") |
| | |
| | | .extraProperties("X-ORIGIN", "NameFormTestCase2") |
| | | .requiredAttributes("name") |
| | | .optionalAttributes("owner") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | .buildNameForm("1.3.6.1.4.1.1466.115.121.1.37") |
| | | .description("Description of the third form") |
| | | .names("ThirdForm") |
| | |
| | | .requiredAttributes("sn", "l") |
| | | .optionalAttributes("description", "uid") |
| | | .description("Description of the third form") |
| | | .addNoOverwriteToSchema() |
| | | .addToSchemaNoOverwrite() |
| | | // we overwritten the third name form. |
| | | .buildNameForm("1.3.6.1.4.1.1466.115.121.1.37") |
| | | .names("ThirdFormOverwritten") |
| | |
| | | assertThat(schema.getNameForm("ThirdFormOverwritten").getOID()).isEqualTo( |
| | | "1.3.6.1.4.1.1466.115.121.1.37"); |
| | | assertThat(schema.getNameForm("ThirdFormOverwritten").getDescription()).isEmpty(); |
| | | assertThat(schema.getNameForm("ThirdFormOverwritten").getExtraProperty("X-ORIGIN").get(0)) |
| | | assertThat(schema.getNameForm("ThirdFormOverwritten").getExtraProperties().get("X-ORIGIN").get(0)) |
| | | .isEqualTo("RFC 2252"); |
| | | } |
| | | } |
| | |
| | | package com.forgerock.opendj.grizzly; |
| | | |
| | | import static com.forgerock.opendj.ldap.CoreMessages.*; |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.*; |
| | | import static com.forgerock.opendj.util.StaticUtils.*; |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.forgerock.i18n.LocalizableMessage; |
| | | import org.forgerock.opendj.io.ASN1; |
| | | import org.forgerock.opendj.io.ASN1Reader; |
| | | import org.forgerock.opendj.io.AbstractASN1Reader; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | |
| | | final class ASN1BufferReader extends AbstractASN1Reader { |
| | | private final class ChildSequenceLimiter implements SequenceLimiter { |
| | | private SequenceLimiter parent; |
| | | |
| | | private ChildSequenceLimiter child; |
| | | |
| | | private int readLimit; |
| | | |
| | | private int bytesRead; |
| | | |
| | | public void checkLimit(final int readSize) throws IOException { |
| | |
| | | final LocalizableMessage message = ERR_ASN1_TRUNCATED_LENGTH_BYTE.get(); |
| | | throw DecodeException.fatalError(message); |
| | | } |
| | | |
| | | parent.checkLimit(readSize); |
| | | |
| | | bytesRead += readSize; |
| | | } |
| | | |
| | | public SequenceLimiter endSequence() throws IOException { |
| | | parent.checkLimit(remaining()); |
| | | |
| | | if (remaining() > 0) { |
| | | IO_LOG.debug("Ignoring {} unused trailing bytes in ASN.1 SEQUENCE", remaining()); |
| | | } |
| | | |
| | | for (int i = 0; i < remaining(); i++) { |
| | | buffer.get(); |
| | | } |
| | | |
| | | return parent; |
| | | } |
| | | |
| | |
| | | child = new ChildSequenceLimiter(); |
| | | child.parent = this; |
| | | } |
| | | |
| | | child.readLimit = readLimit; |
| | | child.bytesRead = 0; |
| | | |
| | | return child; |
| | | } |
| | | } |
| | |
| | | child = new ChildSequenceLimiter(); |
| | | child.parent = this; |
| | | } |
| | | |
| | | child.readLimit = readLimit; |
| | | child.bytesRead = 0; |
| | | |
| | | return child; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | private static final int MAX_STRING_BUFFER_SIZE = 1024; |
| | | |
| | | private int state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | |
| | | private int state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | private byte peekType = 0; |
| | | |
| | | private int peekLength = -1; |
| | | |
| | | private int lengthBytesNeeded = 0; |
| | | |
| | | private final int maxElementSize; |
| | | |
| | | private final CompositeBuffer buffer; |
| | | |
| | | private SequenceLimiter readLimiter; |
| | | |
| | | private final byte[] stringBuffer; |
| | | |
| | | /** |
| | |
| | | * If an error occurs while trying to decode an ASN1 element. |
| | | */ |
| | | public boolean elementAvailable() throws IOException { |
| | | return !((state == ELEMENT_READ_STATE_NEED_TYPE) && !needTypeState(true)) |
| | | && !((state == ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE) |
| | | return !((state == ASN1.ELEMENT_READ_STATE_NEED_TYPE) |
| | | && !needTypeState(true)) |
| | | && !((state == ASN1.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE) |
| | | && !needFirstLengthByteState(true)) |
| | | && !((state == ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES) |
| | | && !((state == ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES) |
| | | && !needAdditionalLengthBytesState(true)) |
| | | && peekLength <= readLimiter.remaining(); |
| | | |
| | |
| | | * If an error occurs while trying to decode an ASN1 element. |
| | | */ |
| | | public boolean hasNextElement() throws IOException { |
| | | return (state != ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(true); |
| | | return (state != ASN1.ELEMENT_READ_STATE_NEED_TYPE) || needTypeState(true); |
| | | } |
| | | |
| | | /** |
| | |
| | | peekType(); |
| | | |
| | | switch (state) { |
| | | case ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE: |
| | | case ASN1.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE: |
| | | needFirstLengthByteState(false); |
| | | break; |
| | | |
| | | case ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES: |
| | | case ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES: |
| | | needAdditionalLengthBytesState(false); |
| | | } |
| | | |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | public byte peekType() throws IOException { |
| | | if (state == ELEMENT_READ_STATE_NEED_TYPE) { |
| | | if (state == ASN1.ELEMENT_READ_STATE_NEED_TYPE) { |
| | | needTypeState(false); |
| | | } |
| | | |
| | |
| | | readLimiter.checkLimit(peekLength); |
| | | final byte readByte = buffer.get(); |
| | | |
| | | IO_LOG.trace("READ ASN.1 BOOLEAN(type=0x{}, length={}, value={})", |
| | | byteToHex(peekType), peekLength, String.valueOf(readByte != 0x00)); |
| | | IO_LOG.trace("READ ASN.1 BOOLEAN(type=0x{}, length={}, value={})", byteToHex(peekType), |
| | | peekLength, String.valueOf(readByte != 0x00)); |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return readByte != 0x00; |
| | | } |
| | | |
| | |
| | | IO_LOG.debug("READ ASN.1 END SEQUENCE"); |
| | | |
| | | // Reset the state |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | } |
| | | |
| | | /** |
| | |
| | | longValue = (longValue << 8) | (readByte & 0xFF); |
| | | } |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return longValue; |
| | | } else { |
| | | int intValue = 0; |
| | |
| | | intValue = (intValue << 8) | (readByte & 0xFF); |
| | | } |
| | | |
| | | IO_LOG.trace("READ ASN.1 INTEGER(type=0x{}, length={}, value={})", |
| | | byteToHex(peekType), peekLength, intValue); |
| | | IO_LOG.trace("READ ASN.1 INTEGER(type=0x{}, length={}, value={})", byteToHex(peekType), |
| | | peekLength, intValue); |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return intValue; |
| | | } |
| | | } |
| | |
| | | throw DecodeException.fatalError(message); |
| | | } |
| | | |
| | | IO_LOG.trace("READ ASN.1 NULL(type=0x{}, length={})", |
| | | byteToHex(peekType), peekLength); |
| | | IO_LOG.trace("READ ASN.1 NULL(type=0x{}, length={})", byteToHex(peekType), peekLength); |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | } |
| | | |
| | | /** |
| | |
| | | peekLength(); |
| | | |
| | | if (peekLength == 0) { |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return ByteString.empty(); |
| | | } |
| | | |
| | |
| | | final byte[] value = new byte[peekLength]; |
| | | buffer.get(value); |
| | | |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={})", byteToHex(peekType), peekLength); |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={})", byteToHex(peekType), |
| | | peekLength); |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return ByteString.wrap(value); |
| | | } |
| | | |
| | |
| | | peekLength(); |
| | | |
| | | if (peekLength == 0) { |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return builder; |
| | | } |
| | | |
| | |
| | | builder.append(buffer.get()); |
| | | } |
| | | |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={})", byteToHex(peekType), peekLength); |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={})", byteToHex(peekType), |
| | | peekLength); |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return builder; |
| | | } |
| | | |
| | |
| | | peekLength(); |
| | | |
| | | if (peekLength == 0) { |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return ""; |
| | | } |
| | | |
| | |
| | | readLimiter.checkLimit(peekLength); |
| | | buffer.get(readBuffer, 0, peekLength); |
| | | |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | |
| | | String str; |
| | | try { |
| | |
| | | str = new String(stringBuffer, 0, peekLength); |
| | | } |
| | | |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={}, value={})", |
| | | byteToHex(peekType), peekLength, str); |
| | | IO_LOG.trace("READ ASN.1 OCTETSTRING(type=0x{}, length={}, value={})", byteToHex(peekType), |
| | | peekLength, str); |
| | | |
| | | return str; |
| | | } |
| | |
| | | |
| | | readLimiter = readLimiter.startSequence(peekLength); |
| | | |
| | | IO_LOG.trace("READ ASN.1 START SEQUENCE(type=0x{}, length={})", |
| | | byteToHex(peekType), peekLength); |
| | | IO_LOG.trace("READ ASN.1 START SEQUENCE(type=0x{}, length={})", byteToHex(peekType), |
| | | peekLength); |
| | | |
| | | // Reset the state |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | } |
| | | |
| | | /** |
| | |
| | | for (int i = 0; i < peekLength; i++) { |
| | | buffer.get(); |
| | | } |
| | | state = ELEMENT_READ_STATE_NEED_TYPE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_TYPE; |
| | | return this; |
| | | } |
| | | |
| | |
| | | .get(peekLength, maxElementSize); |
| | | throw DecodeException.fatalError(m); |
| | | } |
| | | state = ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | return true; |
| | | } |
| | | |
| | |
| | | peekLength = 0x00; |
| | | |
| | | if (ensureRead && (readLimiter.remaining() < lengthBytesNeeded)) { |
| | | state = ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_ADDITIONAL_LENGTH_BYTES; |
| | | return false; |
| | | } |
| | | |
| | |
| | | .get(peekLength, maxElementSize); |
| | | throw DecodeException.fatalError(m); |
| | | } |
| | | state = ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_VALUE_BYTES; |
| | | return true; |
| | | } |
| | | |
| | |
| | | |
| | | readLimiter.checkLimit(1); |
| | | peekType = buffer.get(); |
| | | state = ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE; |
| | | state = ASN1.ELEMENT_READ_STATE_NEED_FIRST_LENGTH_BYTE; |
| | | return true; |
| | | } |
| | | } |
| | |
| | | */ |
| | | package com.forgerock.opendj.grizzly; |
| | | |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.io.LDAPReader; |
| | | import org.forgerock.opendj.io.LDAPWriter; |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | |
| | | * Common utility methods. |
| | | */ |
| | | final class GrizzlyUtils { |
| | | |
| | | |
| | | @SuppressWarnings("rawtypes") |
| | | private static final ThreadCache.CachedTypeIndex<LDAPWriter> WRITER_INDEX = ThreadCache |
| | | .obtainIndex(LDAPWriter.class, 1); |
| | |
| | | public static LDAPReader<ASN1BufferReader> createReader(DecodeOptions decodeOptions, int maxASN1ElementSize, |
| | | MemoryManager<?> memoryManager) { |
| | | ASN1BufferReader asn1Reader = new ASN1BufferReader(maxASN1ElementSize, memoryManager); |
| | | return new LDAPReader<ASN1BufferReader>(asn1Reader, decodeOptions); |
| | | return LDAP.getReader(asn1Reader, decodeOptions); |
| | | } |
| | | |
| | | /** |
| | |
| | | public static LDAPWriter<ASN1BufferWriter> getWriter() { |
| | | LDAPWriter<ASN1BufferWriter> writer = ThreadCache.takeFromCache(WRITER_INDEX); |
| | | if (writer == null) { |
| | | writer = new LDAPWriter<ASN1BufferWriter>(new ASN1BufferWriter()); |
| | | writer = LDAP.getWriter(new ASN1BufferWriter()); |
| | | } |
| | | writer.getASN1Writer().reset(); |
| | | return writer; |
| | |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.forgerock.opendj.io.LDAPMessageHandler; |
| | | import org.forgerock.opendj.io.LDAPReader; |
| | | import org.forgerock.opendj.ldap.DecodeOptions; |
| | | import org.forgerock.opendj.ldap.spi.LDAPMessageHandler; |
| | | import org.glassfish.grizzly.Buffer; |
| | | import org.glassfish.grizzly.filterchain.BaseFilter; |
| | | import org.glassfish.grizzly.filterchain.FilterChainContext; |
| | |
| | | |
| | | package com.forgerock.opendj.grizzly; |
| | | |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.*; |
| | | |
| | | import java.io.EOFException; |
| | | import java.io.IOException; |
| | | |
| | | import javax.net.ssl.SSLEngine; |
| | | |
| | | import org.forgerock.opendj.io.AbstractLDAPMessageHandler; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.io.LDAPReader; |
| | | import org.forgerock.opendj.io.LDAPWriter; |
| | | import org.forgerock.opendj.ldap.ConnectionSecurityLayer; |
| | |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultReference; |
| | | import org.forgerock.opendj.ldap.spi.AbstractLDAPFutureResultImpl; |
| | | import org.forgerock.opendj.ldap.spi.AbstractLDAPMessageHandler; |
| | | import org.forgerock.opendj.ldap.spi.LDAPBindFutureResultImpl; |
| | | import org.forgerock.opendj.ldap.spi.LDAPCompareFutureResultImpl; |
| | | import org.forgerock.opendj.ldap.spi.LDAPExtendedFutureResultImpl; |
| | | import org.forgerock.opendj.ldap.spi.LDAPFutureResultImpl; |
| | | import org.forgerock.opendj.ldap.spi.LDAPSearchFutureResultImpl; |
| | | import org.forgerock.opendj.ldap.spi.UnexpectedResponseException; |
| | | import org.glassfish.grizzly.Connection; |
| | | import org.glassfish.grizzly.EmptyCompletionHandler; |
| | | import org.glassfish.grizzly.Grizzly; |
| | |
| | | private static final Attribute<ClientResponseHandler> RESPONSE_HANDLER_ATTR = |
| | | Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createAttribute("ClientResponseHandler"); |
| | | |
| | | static final class ClientResponseHandler extends AbstractLDAPMessageHandler implements LDAPBaseHandler { |
| | | static final class ClientResponseHandler extends AbstractLDAPMessageHandler implements |
| | | LDAPBaseHandler { |
| | | |
| | | private final LDAPReader<ASN1BufferReader> reader; |
| | | private FilterChainContext context; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void addResult(final int messageID, final Result result) |
| | | throws UnexpectedResponseException, IOException { |
| | | public void addResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | |
| | | if (pendingRequest != null) { |
| | | if (pendingRequest instanceof LDAPFutureResultImpl) { |
| | | final LDAPFutureResultImpl future = |
| | | (LDAPFutureResultImpl) pendingRequest; |
| | | final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest; |
| | | if (future.getRequest() instanceof AddRequest) { |
| | | future.setResultOrError(result); |
| | | return; |
| | | } |
| | | } |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void bindResult(final int messageID, final BindResult result) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | if (!bindClient.evaluateResult(result)) { |
| | | // The server is expecting a multi stage |
| | | // bind response. |
| | | final int msgID = |
| | | ldapConnection.continuePendingBindRequest(future); |
| | | final int msgID = ldapConnection.continuePendingBindRequest(future); |
| | | |
| | | LDAPWriter<ASN1BufferWriter> ldapWriter = GrizzlyUtils.getWriter(); |
| | | try { |
| | |
| | | if (l != null) { |
| | | // The connection needs to be secured by |
| | | // the SASL mechanism. |
| | | ldapConnection |
| | | .installFilter(new ConnectionSecurityLayerFilter(l, |
| | | context.getConnection().getTransport() |
| | | .getMemoryManager())); |
| | | ldapConnection.installFilter(new ConnectionSecurityLayerFilter(l, |
| | | context.getConnection().getTransport().getMemoryManager())); |
| | | } |
| | | } |
| | | |
| | |
| | | future.setResultOrError(result); |
| | | return; |
| | | } |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void compareResult(final int messageID, final CompareResult result) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | future.setResultOrError(result); |
| | | return; |
| | | } |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void deleteResult(final int messageID, final Result result) |
| | | throws UnexpectedResponseException, IOException { |
| | | public void deleteResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | |
| | | if (pendingRequest != null) { |
| | | if (pendingRequest instanceof LDAPFutureResultImpl) { |
| | | final LDAPFutureResultImpl future = |
| | | (LDAPFutureResultImpl) pendingRequest; |
| | | final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest; |
| | | if (future.getRequest() instanceof DeleteRequest) { |
| | | future.setResultOrError(result); |
| | | return; |
| | | } |
| | | } |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void extendedResult(final int messageID, final ExtendedResult result) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | | if (messageID == 0) { |
| | | // Unsolicited notification received. |
| | | if ((result.getOID() != null) |
| | | && result.getOID().equals(OID_NOTICE_OF_DISCONNECTION)) { |
| | | && result.getOID().equals(LDAP.OID_NOTICE_OF_DISCONNECTION)) { |
| | | // Treat this as a connection error. |
| | | final Result errorResult = |
| | | Responses |
| | | .newResult(result.getResultCode()) |
| | | .setDiagnosticMessage(result.getDiagnosticMessage()); |
| | | Responses.newResult(result.getResultCode()).setDiagnosticMessage( |
| | | result.getDiagnosticMessage()); |
| | | ldapConnection.close(null, true, errorResult); |
| | | } else { |
| | | ldapConnection.handleUnsolicitedNotification(result); |
| | |
| | | final LDAPExtendedFutureResultImpl<?> extendedFuture = |
| | | ((LDAPExtendedFutureResultImpl<?>) pendingRequest); |
| | | try { |
| | | handleExtendedResult0(ldapConnection, extendedFuture, |
| | | result); |
| | | handleExtendedResult0(ldapConnection, extendedFuture, result); |
| | | } catch (final DecodeException de) { |
| | | // FIXME: should the connection be closed as |
| | | // well? |
| | | final Result errorResult = |
| | | Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_DECODING_ERROR) |
| | | .setDiagnosticMessage( |
| | | de.getLocalizedMessage()).setCause( |
| | | de); |
| | | Responses.newResult(ResultCode.CLIENT_SIDE_DECODING_ERROR) |
| | | .setDiagnosticMessage(de.getLocalizedMessage()) |
| | | .setCause(de); |
| | | extendedFuture.adaptErrorResult(errorResult); |
| | | } |
| | | } else { |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | @Override |
| | | public void intermediateResponse(final int messageID, final IntermediateResponse response) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | |
| | | @Override |
| | | public void modifyDNResult(final int messageID, final Result result) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | |
| | | if (pendingRequest != null) { |
| | | if (pendingRequest instanceof LDAPFutureResultImpl) { |
| | | final LDAPFutureResultImpl future = |
| | | (LDAPFutureResultImpl) pendingRequest; |
| | | final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest; |
| | | if (future.getRequest() instanceof ModifyDNRequest) { |
| | | future.setResultOrError(result); |
| | | return; |
| | | } |
| | | } |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void modifyResult(final int messageID, final Result result) |
| | | throws UnexpectedResponseException, IOException { |
| | | public void modifyResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | |
| | | if (pendingRequest != null) { |
| | | if (pendingRequest instanceof LDAPFutureResultImpl) { |
| | | final LDAPFutureResultImpl future = |
| | | (LDAPFutureResultImpl) pendingRequest; |
| | | final LDAPFutureResultImpl future = (LDAPFutureResultImpl) pendingRequest; |
| | | if (future.getRequest() instanceof ModifyRequest) { |
| | | future.setResultOrError(result); |
| | | return; |
| | | } |
| | | } |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void searchResult(final int messageID, final Result result) |
| | | throws UnexpectedResponseException, IOException { |
| | | public void searchResult(final int messageID, final Result result) throws DecodeException, |
| | | IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | |
| | | if (pendingRequest != null) { |
| | | if (pendingRequest instanceof LDAPSearchFutureResultImpl) { |
| | | ((LDAPSearchFutureResultImpl) pendingRequest) |
| | | .setResultOrError(result); |
| | | ((LDAPSearchFutureResultImpl) pendingRequest).setResultOrError(result); |
| | | } else { |
| | | throw new UnexpectedResponseException(messageID, result); |
| | | throw newUnexpectedResponseException(messageID, result); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | @Override |
| | | public void searchResultEntry(final int messageID, final SearchResultEntry entry) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | if (pendingRequest instanceof LDAPSearchFutureResultImpl) { |
| | | ((LDAPSearchFutureResultImpl) pendingRequest).handleEntry(entry); |
| | | } else { |
| | | throw new UnexpectedResponseException(messageID, entry); |
| | | throw newUnexpectedResponseException(messageID, entry); |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | @Override |
| | | public void searchResultReference(final int messageID, final SearchResultReference reference) |
| | | throws UnexpectedResponseException, IOException { |
| | | throws DecodeException, IOException { |
| | | final GrizzlyLDAPConnection ldapConnection = |
| | | LDAP_CONNECTION_ATTR.get(context.getConnection()); |
| | | if (ldapConnection != null) { |
| | |
| | | |
| | | if (pendingRequest != null) { |
| | | if (pendingRequest instanceof LDAPSearchFutureResultImpl) { |
| | | ((LDAPSearchFutureResultImpl) pendingRequest) |
| | | .handleReference(reference); |
| | | ((LDAPSearchFutureResultImpl) pendingRequest).handleReference(reference); |
| | | } else { |
| | | throw new UnexpectedResponseException(messageID, reference); |
| | | throw newUnexpectedResponseException(messageID, reference); |
| | | } |
| | | } |
| | | } |
| | |
| | | try { |
| | | final StartTLSExtendedRequest request = |
| | | (StartTLSExtendedRequest) future.getRequest(); |
| | | conn.startTLS(request.getSSLContext(), request |
| | | .getEnabledProtocols(), request.getEnabledCipherSuites(), |
| | | conn.startTLS(request.getSSLContext(), request.getEnabledProtocols(), |
| | | request.getEnabledCipherSuites(), |
| | | new EmptyCompletionHandler<SSLEngine>() { |
| | | @Override |
| | | public void completed(final SSLEngine result) { |
| | |
| | | final Result errorResult = |
| | | Responses.newResult( |
| | | ResultCode.CLIENT_SIDE_LOCAL_ERROR) |
| | | .setCause(throwable) |
| | | .setDiagnosticMessage( |
| | | .setCause(throwable).setDiagnosticMessage( |
| | | "SSL handshake failed"); |
| | | conn.setBindOrStartTLSInProgress(false); |
| | | conn.close(null, false, errorResult); |
| | |
| | | return; |
| | | } catch (final IOException e) { |
| | | final Result errorResult = |
| | | Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR) |
| | | .setCause(e).setDiagnosticMessage(e.getMessage()); |
| | | Responses.newResult(ResultCode.CLIENT_SIDE_LOCAL_ERROR).setCause(e) |
| | | .setDiagnosticMessage(e.getMessage()); |
| | | future.adaptErrorResult(errorResult); |
| | | conn.close(null, false, errorResult); |
| | | return; |
| | |
| | | return ctx.getInvokeAction(); |
| | | } |
| | | |
| | | |
| | | @Override |
| | | protected final void handleReadException(FilterChainContext ctx, IOException e) { |
| | | final GrizzlyLDAPConnection ldapConnection = LDAP_CONNECTION_ATTR.get(ctx.getConnection()); |
| | |
| | | Connection<?> connection = ctx.getConnection(); |
| | | ClientResponseHandler handler = RESPONSE_HANDLER_ATTR.get(connection); |
| | | if (handler == null) { |
| | | LDAPReader<ASN1BufferReader> reader = GrizzlyUtils.createReader(decodeOptions, |
| | | maxASN1ElementSize, connection.getTransport().getMemoryManager()); |
| | | LDAPReader<ASN1BufferReader> reader = |
| | | GrizzlyUtils.createReader(decodeOptions, maxASN1ElementSize, connection |
| | | .getTransport().getMemoryManager()); |
| | | handler = new ClientResponseHandler(reader); |
| | | RESPONSE_HANDLER_ATTR.set(connection, handler); |
| | | } |
| | |
| | | * @param ldapConnection |
| | | * LDAP connection |
| | | */ |
| | | void registerConnection(final Connection<?> connection, final GrizzlyLDAPConnection ldapConnection) { |
| | | void registerConnection(final Connection<?> connection, |
| | | final GrizzlyLDAPConnection ldapConnection) { |
| | | LDAP_CONNECTION_ATTR.set(connection, ldapConnection); |
| | | } |
| | | } |
| | |
| | | |
| | | package com.forgerock.opendj.grizzly; |
| | | |
| | | import static com.forgerock.opendj.ldap.LDAPConstants.OID_NOTICE_OF_DISCONNECTION; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.InetSocketAddress; |
| | | import java.security.GeneralSecurityException; |
| | |
| | | import javax.net.ssl.SSLEngine; |
| | | import javax.net.ssl.SSLSession; |
| | | |
| | | import org.forgerock.opendj.io.AbstractLDAPMessageHandler; |
| | | import org.forgerock.opendj.io.LDAP; |
| | | import org.forgerock.opendj.io.LDAPReader; |
| | | import org.forgerock.opendj.io.LDAPWriter; |
| | | import org.forgerock.opendj.ldap.ByteString; |
| | |
| | | import org.forgerock.opendj.ldap.responses.Result; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultEntry; |
| | | import org.forgerock.opendj.ldap.responses.SearchResultReference; |
| | | import org.forgerock.opendj.ldap.spi.AbstractLDAPMessageHandler; |
| | | import org.forgerock.opendj.ldap.spi.UnexpectedRequestException; |
| | | import org.forgerock.opendj.ldap.spi.UnsupportedMessageException; |
| | | import org.glassfish.grizzly.Connection; |
| | | import org.glassfish.grizzly.Grizzly; |
| | | import org.glassfish.grizzly.attributes.Attribute; |
| | |
| | | * Provides an arbitrary write operation on a LDAP writer. |
| | | */ |
| | | private interface LDAPWrite<T> { |
| | | void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, T message) throws IOException; |
| | | void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, T message) |
| | | throws IOException; |
| | | } |
| | | |
| | | /** |
| | | * Write operation for intermediate responses. |
| | | */ |
| | | private static final LDAPWrite<IntermediateResponse> INTERMEDIATE = new LDAPWrite<IntermediateResponse>() { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, IntermediateResponse resp) |
| | | throws IOException { |
| | | writer.writeIntermediateResponse(messageID, resp); |
| | | } |
| | | }; |
| | | private static final LDAPWrite<IntermediateResponse> INTERMEDIATE = |
| | | new LDAPWrite<IntermediateResponse>() { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, |
| | | IntermediateResponse resp) throws IOException { |
| | | writer.writeIntermediateResponse(messageID, resp); |
| | | } |
| | | }; |
| | | |
| | | private static abstract class AbstractHandler<R extends Result> implements |
| | | IntermediateResponseHandler, ResultHandler<R> { |
| | | protected final ClientContextImpl context; |
| | | protected final int messageID; |
| | | |
| | | |
| | | protected AbstractHandler(final ClientContextImpl context, final int messageID) { |
| | | this.messageID = messageID; |
| | | this.context = context; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Default implementation of result handling, that delegate |
| | | * the actual write operation to {@code writeResult} method. |
| | | * Default implementation of result handling, that delegate the actual |
| | | * write operation to {@code writeResult} method. |
| | | */ |
| | | private void defaultHandleResult(final R result) { |
| | | writeMessage(new LDAPWrite<R>() { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, R res) throws IOException { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, R res) |
| | | throws IOException { |
| | | writeResult(writer, res); |
| | | } |
| | | }, result); |
| | |
| | | * @throws IOException |
| | | * if an error occurs during writing |
| | | */ |
| | | abstract protected void writeResult(final LDAPWriter<ASN1BufferWriter> ldapWriter, final R result) |
| | | throws IOException; |
| | | abstract protected void writeResult(final LDAPWriter<ASN1BufferWriter> ldapWriter, |
| | | final R result) throws IOException; |
| | | |
| | | /** |
| | | * Write a message on LDAP writer. |
| | |
| | | Validator.ensureNotNull(resultCode); |
| | | final GenericExtendedResult notification = |
| | | Responses.newGenericExtendedResult(resultCode).setOID( |
| | | OID_NOTICE_OF_DISCONNECTION).setDiagnosticMessage(message); |
| | | LDAP.OID_NOTICE_OF_DISCONNECTION).setDiagnosticMessage(message); |
| | | sendUnsolicitedNotification(notification); |
| | | disconnect0(resultCode, message); |
| | | } |
| | |
| | | @Override |
| | | public void handleResult(final ExtendedResult result) { |
| | | writeMessage(new LDAPWrite<ExtendedResult>() { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, ExtendedResult message) |
| | | throws IOException { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, |
| | | ExtendedResult message) throws IOException { |
| | | writer.writeExtendedResult(messageID, message); |
| | | } |
| | | }, result); |
| | | } |
| | | |
| | | @Override |
| | | protected void writeResult(LDAPWriter<ASN1BufferWriter> ldapWriter, R result) throws IOException { |
| | | protected void writeResult(LDAPWriter<ASN1BufferWriter> ldapWriter, R result) |
| | | throws IOException { |
| | | // never called because handleResult(result) method is overriden in this class |
| | | } |
| | | } |
| | |
| | | @Override |
| | | public boolean handleEntry(final SearchResultEntry entry) { |
| | | writeMessage(new LDAPWrite<SearchResultEntry>() { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, SearchResultEntry sre) |
| | | throws IOException { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, |
| | | SearchResultEntry sre) throws IOException { |
| | | writer.writeSearchResultEntry(messageID, sre); |
| | | } |
| | | }, entry); |
| | |
| | | @Override |
| | | public boolean handleReference(final SearchResultReference reference) { |
| | | writeMessage(new LDAPWrite<SearchResultReference>() { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, SearchResultReference ref) |
| | | throws IOException { |
| | | public void perform(LDAPWriter<ASN1BufferWriter> writer, int messageID, |
| | | SearchResultReference ref) throws IOException { |
| | | writer.writeSearchResultReference(messageID, ref); |
| | | } |
| | | }, reference); |
| | |
| | | |
| | | private final GrizzlyLDAPListener listener; |
| | | |
| | | private static final class ServerRequestHandler |
| | | extends AbstractLDAPMessageHandler implements LDAPBaseHandler { |
| | | private static final class ServerRequestHandler extends AbstractLDAPMessageHandler implements |
| | | LDAPBaseHandler { |
| | | |
| | | private final Connection<?> connection; |
| | | private final LDAPReader<ASN1BufferReader> reader; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void abandonRequest(final int messageID, final AbandonRequest request) |
| | | throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public void abandonRequest(final int messageID, final AbandonRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | conn.handleAbandon(messageID, request); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void addRequest(final int messageID, final AddRequest request) throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public void addRequest(final int messageID, final AddRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final AddHandler handler = new AddHandler(clientContext, messageID); |
| | |
| | | |
| | | @Override |
| | | public void bindRequest(final int messageID, final int version, |
| | | final GenericBindRequest request) |
| | | throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | final GenericBindRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final AbstractHandler<BindResult> handler = new BindHandler(clientContext, messageID); |
| | | final AbstractHandler<BindResult> handler = |
| | | new BindHandler(clientContext, messageID); |
| | | conn.handleBind(messageID, version, request, handler, handler); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void compareRequest(final int messageID, final CompareRequest request) |
| | | throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public void compareRequest(final int messageID, final CompareRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final CompareHandler handler = new CompareHandler(clientContext, messageID); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void deleteRequest(final int messageID, final DeleteRequest request) |
| | | throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public void deleteRequest(final int messageID, final DeleteRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final DeleteHandler handler = new DeleteHandler(clientContext, messageID); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public <R extends ExtendedResult> void extendedRequest( |
| | | final int messageID, |
| | | final ExtendedRequest<R> request) throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public <R extends ExtendedResult> void extendedRequest(final int messageID, |
| | | final ExtendedRequest<R> request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final ExtendedHandler<R> handler = new ExtendedHandler<R>(clientContext, messageID); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void modifyDNRequest(final int messageID, final ModifyDNRequest request) |
| | | throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public void modifyDNRequest(final int messageID, final ModifyDNRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final ModifyDNHandler handler = new ModifyDNHandler(clientContext, messageID); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void modifyRequest(final int messageID, final ModifyRequest request) |
| | | throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public void modifyRequest(final int messageID, final ModifyRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final ModifyHandler handler = new ModifyHandler(clientContext, messageID); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void searchRequest(final int messageID, final SearchRequest request) |
| | | throws UnexpectedRequestException { |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.get(connection); |
| | | public void searchRequest(final int messageID, final SearchRequest request) { |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.get(connection); |
| | | if (clientContext != null) { |
| | | final ServerConnection<Integer> conn = clientContext.getServerConnection(); |
| | | final SearchHandler handler = new SearchHandler(clientContext, messageID); |
| | |
| | | public void unbindRequest(final int messageID, final UnbindRequest request) { |
| | | // Remove the client context causing any subsequent LDAP |
| | | // traffic to be ignored. |
| | | final ClientContextImpl clientContext = |
| | | LDAP_CONNECTION_ATTR.remove(connection); |
| | | final ClientContextImpl clientContext = LDAP_CONNECTION_ATTR.remove(connection); |
| | | if (clientContext != null) { |
| | | clientContext.handleClose(messageID, request); |
| | | } |
| | |
| | | @Override |
| | | public void unrecognizedMessage(final int messageID, final byte messageTag, |
| | | final ByteString messageBytes) { |
| | | exceptionOccurred(connection, new UnsupportedMessageException(messageID, messageTag, |
| | | exceptionOccurred(connection, newUnsupportedMessageException(messageID, messageTag, |
| | | messageBytes)); |
| | | } |
| | | } |
| | |
| | | Connection<?> connection = ctx.getConnection(); |
| | | ServerRequestHandler handler = REQUEST_HANDLER_ATTR.get(connection); |
| | | if (handler == null) { |
| | | LDAPReader<ASN1BufferReader> reader = GrizzlyUtils.createReader(decodeOptions, |
| | | maxASN1ElementSize, connection.getTransport().getMemoryManager()); |
| | | LDAPReader<ASN1BufferReader> reader = |
| | | GrizzlyUtils.createReader(decodeOptions, maxASN1ElementSize, connection |
| | | .getTransport().getMemoryManager()); |
| | | handler = new ServerRequestHandler(connection, reader); |
| | | REQUEST_HANDLER_ATTR.set(connection, handler); |
| | | } |
| | |
| | | /** |
| | | * Tests the LDAPListener class. |
| | | */ |
| | | @SuppressWarnings("javadoc") |
| | | public class GrizzlyLDAPListenerTestCase extends SdkTestCase { |
| | | |
| | | private static class MockServerConnection implements ServerConnection<Integer> { |
| | |
| | | /** |
| | | * Test creation of LDAP listener with unknown transport provider. |
| | | */ |
| | | @SuppressWarnings({ "unused", "resource", "unchecked" }) |
| | | @SuppressWarnings({ "unchecked" }) |
| | | @Test(expectedExceptions = { ProviderNotFoundException.class }, |
| | | expectedExceptionsMessageRegExp = "^The requested provider 'unknown' .*") |
| | | public void testCreateLDAPListenerFailureProviderNotFound() throws Exception { |
| New file |
| | |
| | | |
| | | @echo off |
| | | rem CDDL HEADER START |
| | | rem |
| | | rem The contents of this file are subject to the terms of the |
| | | rem Common Development and Distribution License, Version 1.0 only |
| | | rem (the "License"). You may not use this file except in compliance |
| | | rem with the License. |
| | | rem |
| | | rem You can obtain a copy of the license at |
| | | rem legal-notices/CDDLv1_0.txt |
| | | rem or http://forgerock.org/license/CDDLv1.0.html. |
| | | rem See the License for the specific language governing permissions |
| | | rem and limitations under the License. |
| | | rem |
| | | rem When distributing Covered Code, include this CDDL HEADER in each |
| | | rem file and include the License file at legal-notices/CDDLv1_0.txt. |
| | | rem legal-notices/CDDLv1_0.txt. If applicable, |
| | | rem add the following below this CDDL HEADER, with the fields enclosed |
| | | rem by brackets "[]" replaced with your own identifying information: |
| | | rem Portions Copyright [yyyy] [name of copyright owner] |
| | | rem |
| | | rem CDDL HEADER END |
| | | rem |
| | | rem |
| | | rem Copyright 2013 ForgeRock AS. |
| | | |
| | | setlocal |
| | | |
| | | set OPENDJ_INVOKE_CLASS="com.forgerock.opendj.ldap.tools.MakeLDIF" |
| | | set SCRIPT_NAME=makeldif |
| | | for %%i in (%~sf0) do call "%%~dPsi\..\lib\_client-script.bat" %* |
| New file |
| | |
| | | #!/bin/sh |
| | | # |
| | | # CDDL HEADER START |
| | | # |
| | | # The contents of this file are subject to the terms of the |
| | | # Common Development and Distribution License, Version 1.0 only |
| | | # (the "License"). You may not use this file except in compliance |
| | | # with the License. |
| | | # |
| | | # You can obtain a copy of the license at |
| | | # trunk/opendj3/legal-notices/CDDLv1_0.txt |
| | | # or http://forgerock.org/license/CDDLv1.0.html. |
| | | # See the License for the specific language governing permissions |
| | | # and limitations under the License. |
| | | # |
| | | # When distributing Covered Code, include this CDDL HEADER in each |
| | | # file and include the License file at |
| | | # trunk/opendj3/legal-notices/CDDLv1_0.txt. If applicable, |
| | | # add the following below this CDDL HEADER, with the fields enclosed |
| | | # by brackets "[]" replaced with your own identifying information: |
| | | # Portions Copyright [yyyy] [name of copyright owner] |
| | | # |
| | | # CDDL HEADER END |
| | | # |
| | | # |
| | | # Copyright 2013 ForgeRock AS. |
| | | |
| | | |
| | | # This script may be used to perform LDAP add, delete, modify, and modify DN |
| | | # operations against an LDIF file. |
| | | OPENDJ_INVOKE_CLASS="com.forgerock.opendj.ldap.tools.MakeLDIF" |
| | | export OPENDJ_INVOKE_CLASS |
| | | |
| | | SCRIPT_NAME="makeldif" |
| | | export SCRIPT_NAME |
| | | |
| | | SCRIPT_DIR=`dirname "${0}"` |
| | | "${SCRIPT_DIR}/../lib/_client-script.sh" "${@}" |
| | |
| | | return EXIT_CODE_FAILURE; |
| | | } |
| | | |
| | | if (generator.hasWarning()) { |
| | | if (generator.hasWarnings()) { |
| | | for (LocalizableMessage warn : generator.getWarnings()) { |
| | | println(warn); |
| | | } |
| | |
| | | <dt>ldifmodify</dt><dd>perform LDAP modify, add, delete, mod DN operations against entries contained in an LDIF file</dd> |
| | | <dt>ldifsearch</dt><dd>perform search operations against entries contained in an LDIF file</dd> |
| | | <dt>ldifdiff</dt><dd>compare two LDIF files and report the differences in LDIF format</dd> |
| | | <dt>makeldif</dt><dd>generate LDIF content from and LDIF template</dd> |
| | | <dt>modrate</dt><dd>measure modification throughput and response time</dd> |
| | | <dt>searchrate</dt><dd>measure search throughput and response time</dd> |
| | | </dl> |
| | |
| | | import static org.forgerock.json.fluent.JsonValue.object; |
| | | import static org.forgerock.json.resource.PatchOperation.add; |
| | | import static org.forgerock.json.resource.PatchOperation.increment; |
| | | import static org.forgerock.json.resource.PatchOperation.operation; |
| | | import static org.forgerock.json.resource.PatchOperation.remove; |
| | | import static org.forgerock.json.resource.PatchOperation.replace; |
| | | import static org.forgerock.json.resource.Requests.newDeleteRequest; |
| | |
| | | connection.patch(ctx(), newPatchRequest("/test1", add("/dummy", "junk"))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NotSupportedException.class) |
| | | public void testPatchUnknownOperation() throws Exception { |
| | | final Connection connection = newConnection(); |
| | | connection.patch(ctx(), newPatchRequest("/test1", operation("dummy", "/description", |
| | | asList("one", "two")))); |
| | | } |
| | | |
| | | @Test(expectedExceptions = BadRequestException.class) |
| | | public void testPatchUnknownSubAttribute() throws Exception { |
| | | final Connection connection = newConnection(); |
| | |
| | | <module>opendj-server2x-adapter</module> |
| | | </modules> |
| | | <properties> |
| | | <forgerockBuildToolsVersion>1.0.2</forgerockBuildToolsVersion> |
| | | <currentSDKversion>${project.version}</currentSDKversion> |
| | | <stableSDKversion>version.not.defined</stableSDKversion> |
| | | <currentServerVersion>2.5.0-SNAPSHOT</currentServerVersion> |