All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ldaptive.AbstractMessage Maven / Gradle / Ivy

The newest version!
/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.ldaptive.asn1.AbstractParseHandler;
import org.ldaptive.asn1.BooleanType;
import org.ldaptive.asn1.DERBuffer;
import org.ldaptive.asn1.DERParser;
import org.ldaptive.asn1.DERPath;
import org.ldaptive.asn1.IntegerType;
import org.ldaptive.asn1.OctetStringType;
import org.ldaptive.control.ControlFactory;
import org.ldaptive.control.ResponseControl;

/**
 * LDAP message envelope defined as:
 *
 * 
   LDAPMessage ::= SEQUENCE {
     messageID       MessageID,
     protocolOp      CHOICE {
       ...,
     controls       [0] Controls OPTIONAL }

   Control ::= SEQUENCE {
     controlType             LDAPOID,
     criticality             BOOLEAN DEFAULT FALSE,
     controlValue            OCTET STRING OPTIONAL }
 * 
* * @author Middleware Services */ public abstract class AbstractMessage implements Message { /** Protocol message ID. */ private int messageID; /** LDAP controls. */ private List controls = new ArrayList<>(); @Override public int getMessageID() { return messageID; } public void setMessageID(final int id) { messageID = id; } @Override public ResponseControl[] getControls() { return controls != null ? controls.toArray(new ResponseControl[0]) : null; } /** * Adds the supplied controls to this message. * * @param cntrls to add */ public void addControls(final ResponseControl... cntrls) { Collections.addAll(controls, cntrls); } /** * Copies the property values from the supplied message to this message. * * @param type of message * @param message to copy from */ protected void copyValues(final T message) { setMessageID(message.getMessageID()); addControls(message.getControls()); } // CheckStyle:EqualsHashCode OFF @Override public boolean equals(final Object o) { if (o == this) { return true; } if (o instanceof AbstractMessage) { final AbstractMessage v = (AbstractMessage) o; return LdapUtils.areEqual(getMessageID(), v.getMessageID()) && LdapUtils.areEqual(getControls(), v.getControls()); } return false; } // CheckStyle:EqualsHashCode ON /** * Returns the hash code for this object. * * @return hash code */ @Override public abstract int hashCode(); @Override public String toString() { return getClass().getName() + "@" + hashCode() + "::" + "messageID=" + messageID + ", " + "controls=" + controls; } /** Parse handler implementation for the message ID. */ protected static class MessageIDHandler extends AbstractParseHandler { /** DER path to message id. */ public static final DERPath PATH = new DERPath("/SEQ/INT[0]"); /** * Creates a new message ID handler. * * @param response to configure */ public MessageIDHandler(final AbstractMessage response) { super(response); } @Override public void handle(final DERParser parser, final DERBuffer encoded) { getObject().setMessageID(IntegerType.decodeUnsignedPrimitive(encoded)); } } /** Parse handler implementation for the message controls. */ protected static class ControlsHandler extends AbstractParseHandler { /** DER path to controls. */ public static final DERPath PATH = new DERPath("/SEQ/CTX(0)/SEQ"); /** * Creates a new controls handler. * * @param response to configure */ public ControlsHandler(final AbstractMessage response) { super(response); } @Override public void handle(final DERParser parser, final DERBuffer encoded) { final ControlParser p = new ControlParser(); p.parse(encoded); if (p.getOid().isEmpty()) { throw new IllegalArgumentException("Cannot parse response control without OID"); } getObject().addControls( ControlFactory.createResponseControl( p.getOid().get(), p.getCritical().isPresent() ? p.getCritical().get() : false, p.getValue().isPresent() ? p.getValue().get() : null)); } } /** * Parses a buffer containing an LDAP control. */ protected static class ControlParser { /** DER path to criticality. */ private static final DERPath CRITICAL_PATH = new DERPath("/BOOL[1]"); /** DER path to OID. */ private static final DERPath OID_PATH = new DERPath("/OCTSTR[0]"); /** DER path to value. */ private static final DERPath VALUE_PATH = new DERPath("/OCTSTR[1]"); /** DER path to alternate value. */ private static final DERPath ALT_VALUE_PATH = new DERPath("/OCTSTR[2]"); /** Parser for decoding LDAP controls. */ private final DERParser parser = new DERParser(); /** Control criticality. */ private Boolean critical; /** Control oid. */ private String oid; /** Control value. */ private DERBuffer value; /** * Creates a new control parser. */ public ControlParser() { parser.registerHandler(CRITICAL_PATH, (p, e) -> critical = BooleanType.decode(e)); parser.registerHandler(OID_PATH, (p, e) -> oid = OctetStringType.decode(e)); parser.registerHandler(VALUE_PATH, (p, e) -> value = e.slice()); parser.registerHandler(ALT_VALUE_PATH, (p, e) -> { if (value == null) { value = e.slice(); } }); } /** * Examines the supplied buffer and parses an LDAP control if one is found. * * @param buffer to parse */ public void parse(final DERBuffer buffer) { parser.parse(buffer); } /** * Returns the control criticality. * * @return criticality or empty */ public Optional getCritical() { return Optional.ofNullable(critical); } /** * Returns the control oid. * * @return control oid or empty */ public Optional getOid() { return Optional.ofNullable(oid); } /** * Returns the control value. * * @return control value or empty */ public Optional getValue() { return Optional.ofNullable(value); } } // CheckStyle:OFF protected abstract static class AbstractBuilder { protected final T object; protected AbstractBuilder(final T t) { object = t; } protected abstract B self(); public B messageID(final int id) { object.setMessageID(id); return self(); } public B controls(final ResponseControl... controls) { object.addControls(controls); return self(); } public T build() { return object; } } // CheckStyle:ON }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy