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

io.pkts.packet.sip.header.AddressParametersHeader Maven / Gradle / Ivy

/**
 * 
 */
package io.pkts.packet.sip.header;

import io.pkts.buffer.Buffer;
import io.pkts.buffer.Buffers;
import io.pkts.packet.sip.SipParseException;
import io.pkts.packet.sip.address.Address;
import io.pkts.packet.sip.address.SipURI;
import io.pkts.packet.sip.header.impl.AddressParametersHeaderImpl;
import io.pkts.packet.sip.header.impl.ParametersSupport;
import io.pkts.packet.sip.impl.SipParser;

import java.io.IOException;
import java.util.UUID;

import static io.pkts.packet.sip.impl.PreConditions.assertNotEmpty;
import static io.pkts.packet.sip.impl.PreConditions.assertNotNull;

/**
 * @author [email protected]
 */
public interface AddressParametersHeader extends SipHeader, HeaderAddress, Parameters{

    /**
     * Frame the value as a {@link AddressParametersHeaderImpl}. This method assumes that you have
     * already parsed out the actual header name, e.g. "To: ". Also, this method assumes that a
     * message framer (or similar) has framed the buffer that is being passed in to us to only
     * contain this header and nothing else.
     * 
     * Note, as with all the frame-methods on all headers/messages/whatever, they do not do any
     * validation that the information is actually correct. This method will simply only try and
     * validate just enough to get the framing done.
     * 
     * @param value
     * @return an array where the first object is a {@link Address} object and the second is a
     *         {@link Buffer} with all the parameters.
     * @throws SipParseException in case anything goes wrong while parsing.
     */
    static Object[] frame(final Buffer buffer) throws SipParseException {
        try {
            final Address address = Address.frame(buffer);
            // we assume that the passed in buffer ONLY contains
            // this header and nothing else. Therefore, there are only
            // header parameters left after we have consumed the address
            // portion.
            Buffer params = null;
            if (buffer.hasReadableBytes()) {
                params = buffer.slice();
            }
            return new Object[] {address, params};
        } catch (final IndexOutOfBoundsException e) {
            throw new SipParseException(buffer.getReaderIndex(),
                    "Unable to process the value due to a IndexOutOfBoundsException", e);
        } catch (final IOException e) {
            throw new SipParseException(buffer.getReaderIndex(),
                    "Unable to process the To-header to due an IOException");
        }
    }

    static  Builder with(final Buffer headerName)
            throws SipParseException {
        assertNotEmpty(headerName, "The name of the header cannot be null or the empty buffer");
        return new Builder(headerName);
    }

    @Override
    Builder copy();

    default boolean isAddressParametersHeader() {
        return true;
    }

    default AddressParametersHeader toAddressParametersHeader() throws ClassCastException {
        return this;
    }

    class Builder implements SipHeader.Builder {

        private final Buffer name;

        private Address.Builder addressBuilder;

        private Buffer value;

        /**
         * Note these are the header parameters and are not to be confused with any URI parameters
         * that are "attached" to the URI within the address object.
         */
        private ParametersSupport paramSupport;

        protected Builder(final Buffer name) {
            this(name, new ParametersSupport(null));
        }

        protected Builder(final Buffer name, final ParametersSupport params) {
            this.name = name;
            this.paramSupport = params;
        }


        public final Builder withValue(final Buffer buffer) {
            throw new RuntimeException("Not implemented yet");
            // Address.frame(buffer).copy();
            // return this;
        }

        public final Builder withPort(final int port) {
            ensureBuilder().withPort(port);
            return this;
        }

        /**
         * Set the user portion of the {@link ToHeader}. Since the user portion may in fact be null
         * (or empty), any value is accepted but of course, a value of null or empty will lead to no
         * user portion of the SIP-URI within the header.
         * 
         * @param user
         * @return
         */
        public final Builder withUser(final Buffer user) {
            ensureBuilder().withUser(user);
            return this;
        }

        public final Builder withUser(final String user) {
            ensureBuilder().withUser(user);
            return this;
        }

        public final Builder withDisplayName(final String displayName) {
            ensureBuilder().withDisplayName(displayName);
            return this;
        }

        public final Builder withDisplayName(final Buffer displayName) {
            ensureBuilder().withDisplayName(displayName);
            return this;
        }

        /**
         * Use this host for the ToHeader.
         * 
         * NOTE: you can only specify either an address or a host and user but not both. If you do,
         * an exception will occur at the time you try and {@link #build()} the header.
         * 
         * @param host
         * @return
         */
        public final Builder withHost(final Buffer host) {
            ensureBuilder().withHost(host);
            return this;
        }

        public final Builder withHost(final String host) {
            ensureBuilder().withHost(host);
            return this;
        }

        /**
         * Convenience method for removing the tag paramter.
         *
         * @return
         * @throws SipParseException
         * @throws IllegalArgumentException
         */
        public Builder withNoTag() throws SipParseException,
                IllegalArgumentException {
            this.paramSupport.removeParameter(SipParser.TAG);
            return this;
        }

        /**
         * Convenience method for setting the tag parameter.
         *
         * @param value
         * @return
         * @throws SipParseException
         * @throws IllegalArgumentException
         */
        public Builder withTag(final Buffer value) throws SipParseException,
                IllegalArgumentException {
            assertNotEmpty(value, "The value of the tag parameter cannot be null or the empty buffer");
            this.paramSupport.setParameter(SipParser.TAG, value);
            return this;
        }

        /**
         * Convenience method for setting the tag parameter.
         *
         * @param value
         * @return
         * @throws SipParseException
         * @throws IllegalArgumentException
         */
        public Builder withTag(final String value) throws SipParseException,
                IllegalArgumentException {
            assertNotEmpty(value, "The value of the tag parameter cannot be null or the empty string");
            this.paramSupport.setParameter(SipParser.TAG, Buffers.wrap(value));
            return this;
        }

        /**
         * Convenience method for setting the value of the tag parameter to a default
         * generated value.
         *
         * @return
         * @throws SipParseException
         * @throws IllegalArgumentException
         */
        public Builder withDefaultTag() throws SipParseException,
                IllegalArgumentException {
            this.paramSupport.setParameter(SipParser.TAG, Buffers.wrap(UUID.randomUUID().toString()));
            return this;
        }

        /**
         * Set a parameter on the header.
         * 
         * NOTE: if you want to set a parameter on the URI you need to use the method
         * {@link #withUriParameter(Buffer, Buffer)}.
         * 
         * @param name
         * @param value
         * @return
         * @throws SipParseException
         * @throws IllegalArgumentException
         */
        public Builder withParameter(final Buffer name, final Buffer value) throws SipParseException,
        IllegalArgumentException {
            this.paramSupport.setParameter(name, value);
            return this;
        }

        public Builder withParameter(final String name, final String value) throws SipParseException,
        IllegalArgumentException {
            this.paramSupport.setParameter(name, value);
            return this;
        }

        /**
         * Set a bunch of parameters at the same time.
         *
         * WARNING! This one will wipe out any previously set parameters so be sure to call
         * this one FIRST before any other calls to withParameter...
         *
         * @param params
         * @return
         */
        public Builder withParameters(final Buffer params) {
            this.paramSupport = new ParametersSupport(params);
            return this;
        }

        /**
         * Remove all header parameters.
         *
         * @return
         */
        public Builder withNoParameters() {
            this.paramSupport = new ParametersSupport();
            return this;
        }

        /**
         * Set a parameter on the underlying {@link SipURI}.
         * 
         * @param name
         * @param value
         * @return
         * @throws SipParseException
         * @throws IllegalArgumentException
         */
        public Builder withUriParameter(final Buffer name, final Buffer value) throws SipParseException,
        IllegalArgumentException {
            ensureBuilder().withURIParameter(name, value);
            return this;
        }

        /**
         * Set a parameter on the underlying {@link SipURI}.
         * 
         * @param name
         * @param value
         * @return
         * @throws SipParseException
         * @throws IllegalArgumentException
         */
        public Builder withUriParameter(final String name, final String value) throws SipParseException,
        IllegalArgumentException {
            ensureBuilder().withURIParameter(name, value);
            return this;
        }

        public Builder withTransport(final Buffer transport) throws SipParseException {
            ensureBuilder().withTransport(transport);
            return this;
        }

        public Builder withTransport(final String transport) throws SipParseException {
            ensureBuilder().withTransport(transport);
            return this;
        }

        /**
         * Set the transport parameter on the underlying {@link SipURI} to be "tcp".
         * 
         * @return
         * @throws SipParseException
         */
        public Builder withTransportTCP() throws SipParseException {
            ensureBuilder().withTransportTCP();
            return this;
        }

        /**
         * Set the transport parameter on the underlying {@link SipURI} to be "udp".
         * 
         * @return
         * @throws SipParseException
         */
        public Builder withTransportUDP() throws SipParseException {
            ensureBuilder().withTransportUDP();
            return this;
        }

        /**
         * Set the transport parameter on the underlying {@link SipURI} to be "tls".
         * 
         * @return
         * @throws SipParseException
         */
        public Builder withTransportTLS() throws SipParseException {
            ensureBuilder().withTransportTLS();
            return this;
        }

        /**
         * Set the transport parameter on the underlying {@link SipURI} to be "sctp".
         * 
         * @return
         * @throws SipParseException
         */
        public Builder withTransportSCTP() throws SipParseException {
            ensureBuilder().withTransportSCTP();
            return this;
        }

        /**
         * Set the transport parameter on the underlying {@link SipURI} to be "ws".
         * 
         * @return
         * @throws SipParseException
         */
        public Builder withTransportWS() throws SipParseException {
            ensureBuilder().withTransportWS();
            return this;
        }

        public Builder withTransportWSS() throws SipParseException {
            ensureBuilder().withTransportWSS();
            return this;
        }

        /**
         * Use this address for the ToHeader.
         *
         * Note, if you already have specified any part of the address, such as the host,
         * then this
         * 
         * @param address
         * @throws SipParseException in case an address already has been specified either by
         * a previous call to this method or by specifying parts of an address through e.g.
         * withHost etc.
         * @return
         */
        public final Builder withAddress(final Address address) throws SipParseException {
            assertNotNull(address, "Address cannot be null");
            this.addressBuilder = address.copy();
            return this;
        }

        /**
         * Build a new ToHeader.
         * 
         * @return
         * @throws SipParseException in case anything goes wrong while constructing the
         *         {@link ToHeader}.
         */
        public final T build() throws SipParseException {
            if (addressBuilder == null) {
                throw new SipParseException("You must specify an address of some sort.");
            }

            Address addressToUse = this.addressBuilder.build();
            final Buffer addressBuffer = addressToUse.toBuffer();
            final Buffer paramsBuffer = this.paramSupport.toBuffer();
            final Buffer headerValue = Buffers.createBuffer(addressBuffer.capacity() + paramsBuffer.capacity());
            addressBuffer.getBytes(0, headerValue);
            paramsBuffer.getBytes(0, headerValue);

            return internalBuild(headerValue, addressToUse, paramsBuffer);
        }

        @SuppressWarnings("unchecked")
        protected T internalBuild(final Buffer rawValue, final Address address, final Buffer params) {
            return (T) new AddressParametersHeaderImpl(name, rawValue, address, params);
        }

        private Address.Builder ensureBuilder() {
            if (addressBuilder == null) {
                this.addressBuilder = Address.builder();
            }
            return this.addressBuilder;
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy