Package org.scale7.cassandra.pelops.types

Source Code of org.scale7.cassandra.pelops.types.CompositeType$Builder

package org.scale7.cassandra.pelops.types;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import org.scale7.cassandra.pelops.Bytes;
import org.scale7.cassandra.pelops.Bytes.BufferHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* CompositeType utility class
*
* @author Ali Serghini
*/
public class CompositeType {

    private static final byte COMPONENT_END = (byte) 0;
    private static final Logger LOGGER = LoggerFactory.getLogger(CompositeType.class);

    //Utility class
    private CompositeType() {
    }

    /**
     * A Builder class that creates a CompositeType.
     */
    public static class Builder {

        private List<ByteBuffer> parts = null;

        private Builder(int count) {
            parts = new ArrayList<ByteBuffer>(count);
        }

        /**
         * Creates a new builder
         *
         * @param partsCount - CompositeType parts count. Should be 2 or more.
         * @return CompositeType builder
         */
        public static Builder newBuilder(int partsCount) {
            if (partsCount < 1) throw new IllegalArgumentException("Invalid parts count. Should be 2 or more.");
            return new Builder(partsCount);
        }

        /**
         * Creates a new builder. Assumes that there will be 2 elements in the composite type
         *
         * @return CompositeType builder
         */
        public static Builder newBuilder() {
            return new Builder(2);
        }

        public Builder addByteBuffer(ByteBuffer value) {
            parts.add(value);
            return this;
        }

        public Builder addBytes(Bytes value) {
            return addByteBuffer(value.getBytes());
        }

        public Builder addBoolean(boolean value) {
            return addByteBuffer(BufferHelper.fromBoolean(value));
        }

        public Builder addBoolean(Boolean value) {
            return addByteBuffer(BufferHelper.fromBoolean(value));
        }

        public Builder addByte(byte value) {
            return addByteBuffer(BufferHelper.fromByte(value));
        }

        public Builder addByte(Byte value) {
            return addByteBuffer(BufferHelper.fromByte(value));
        }

        public Builder addByteArray(byte[] value) {
            return addByteBuffer(BufferHelper.fromByteArray(value));
        }

        public Builder addChar(char value) {
            return addByteBuffer(BufferHelper.fromChar(value));
        }

        public Builder addChar(Character value) {
            return addByteBuffer(BufferHelper.fromChar(value));
        }

        public Builder addDouble(double value) {
            return addByteBuffer(BufferHelper.fromDouble(value));
        }

        public Builder addDouble(Double value) {
            return addByteBuffer(BufferHelper.fromDouble(value));
        }

        public Builder addFloat(float value) {
            return addByteBuffer(BufferHelper.fromFloat(value));
        }

        public Builder addFloat(Float value) {
            return addByteBuffer(BufferHelper.fromFloat(value));
        }

        public Builder addInt(int value) {
            return addByteBuffer(BufferHelper.fromInt(value));
        }

        public Builder addInt(Integer value) {
            return addByteBuffer(BufferHelper.fromInt(value));
        }

        public Builder addLong(long value) {
            return addByteBuffer(BufferHelper.fromLong(value));
        }

        public Builder addLong(Long value) {
            return addByteBuffer(BufferHelper.fromLong(value));
        }

        public Builder addShort(short value) {
            return addByteBuffer(BufferHelper.fromShort(value));
        }

        public Builder addShort(Short value) {
            return addByteBuffer(BufferHelper.fromShort(value));
        }

        public Builder addUTF8(String str) {
            return addByteBuffer(BufferHelper.fromUTF8(str));
        }

        public Builder addUuid(UUID value) {
            return addByteBuffer(BufferHelper.fromUuid(value));
        }

        public Builder addUuid(String value) {
            return addByteBuffer(BufferHelper.fromUuid(value));
        }

        public Builder addUuid(long msb, long lsb) {
            return addByteBuffer(BufferHelper.fromUuid(msb, lsb));
        }

        public Builder addTimeUuid(com.eaio.uuid.UUID value) {
            return addByteBuffer(BufferHelper.fromUuid(value.getTime(), value.getClockSeqAndNode()));
        }

        /**
         * Reset the builder
         */
        public void clear() {
            parts.clear();
        }

        /**
         * Build the CompositeType using the added parts.
         *
         * @return CompositeType as Bytes
         */
        public Bytes build() {
            if (parts == null || parts.isEmpty()) return null;

            final ByteArrayOutputStream bos = new ByteArrayOutputStream();
            for (ByteBuffer part : parts) {
                if (!part.hasArray())
                    throw new IllegalStateException("Connot build CompositeType. Invalid composite byte part encountered");

                bos.write((byte) ((part.array().length >> (7 + 1)) & 0xFF));
                bos.write((byte) (part.array().length & 0xFF));
                for (byte partByte : part.array()) {
                    bos.write(partByte & 0xFF);
                }

                bos.write(COMPONENT_END);
            }

            final Bytes bytes = Bytes.fromByteArray(bos.toByteArray());

            try {
                bos.close();
            } catch (IOException ex) {
                LOGGER.error("Failed to close the compostite type output stream", ex);
            }

            return bytes;
        }
    }

    /**
     * Parses the CompositeType
     *
     * @param compositeKey - composite key as Bytes
     * @return list of the composite key elements
     */
    public static List<byte[]> parse(Bytes compositeKey) {
        if (compositeKey == null) return null;
        return parse(compositeKey.toByteArray());
    }

    /**
     * Parses the CompositeType
     *
     * @param compositeKey - composite key as byte array
     * @return list of the composite key elements
     */
    public static List<byte[]> parse(byte[] compositeKey) {
        if (compositeKey == null) return null;

        //Validate the array length
        if (compositeKey.length < 2) throw new IllegalArgumentException("Invalid Composite type structure");

        final List<byte[]> list = new ArrayList<byte[]>(3);//Default to 3
        int ndx = 0;
        int componentStartNdx = 0;
        int componentEndNdx = 0;
        short componentLength = 0;
        while (compositeKey.length > (componentStartNdx = (ndx + 2))) {
            // Value length is a 2 bytes short
            componentLength = ByteBuffer.wrap(Arrays.copyOfRange(compositeKey, ndx, componentStartNdx)).getShort();
            componentEndNdx = componentStartNdx + componentLength;

            // Check if the component legth is valid
            if (compositeKey.length < componentEndNdx + 1) throw new IllegalStateException("Invalid Composite type structure");
            // If the value is not properly terminated throw an exception
            if (compositeKey[componentEndNdx] != COMPONENT_END)
                throw new IllegalStateException("Invalid Composite type structure: Not properly terminated, should be 0 byte terminated, found " + compositeKey[componentEndNdx]);

            // Get the value
            list.add(Arrays.copyOfRange(compositeKey, componentStartNdx, componentEndNdx));

            // Update the value of the index
            ndx = componentEndNdx + 1;
        }

        return list;
    }
}
TOP

Related Classes of org.scale7.cassandra.pelops.types.CompositeType$Builder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.