001    /*
002     * Copyright (c) 1998-2014 ChemAxon Ltd. All Rights Reserved.
003     *
004     * This software is the confidential and proprietary information of
005     * ChemAxon. You shall not disclose such Confidential Information
006     * and shall use it only in accordance with the terms of the agreements
007     * you entered into with ChemAxon.
008     *
009     */
010    package com.chemaxon.descriptors.vectors.binary;
011    
012    import com.chemaxon.apidiscovery.annotations.BuilderClass;
013    import com.chemaxon.apidiscovery.annotations.Description;
014    import com.chemaxon.apidiscovery.annotations.Parameter;
015    import com.chemaxon.apidiscovery.interfaces.ParameterBuilder;
016    import com.chemaxon.apidiscovery.util.ServiceUtil;
017    import com.chemaxon.common.annotations.PublicAPI;
018    import com.chemaxon.descriptors.common.BinaryVectors;
019    import com.chemaxon.descriptors.common.DescriptorParameters;
020    import com.google.common.annotations.Beta;
021    import com.google.common.base.Preconditions;
022    import java.io.Serializable;
023    
024    /**
025     * Parameters for generic binary vector descriptor.
026     *
027     * @author Gabor Imre
028     */
029    @BuilderClass(builderClass = BvParameters.Builder.class)
030    @Beta
031    @PublicAPI
032    public final class BvParameters implements DescriptorParameters, Serializable {
033    
034        /**
035         * Serial version.
036         */
037        private static final long serialVersionUID = 0;
038    
039        /**
040         * Fingerprint textual representation.
041         */
042        public enum StringFormat {
043    
044            /**
045             * String representation containing only '0' and '1' characters without separation.
046             *
047             * <p>
048             * First character of the string corresponds to the lowest bit index. The binary string format can be created
049             * from the packed numeric formats by concatenating their reversed binary representation.</p>
050             */
051            STRICT_BINARY_STRING,
052            /**
053             * Represented as sequence of signed 32 bit integers, separated by tabs.
054             */
055            PACKED_INT_TABSEP,
056            /**
057             * Represented as sequence of signed 64 bit longs, separated by tabs.
058             */
059            PACKED_LONG_TABSEP;
060        }
061    
062        // DEFAULTS ========================================================================================================
063    
064        /**
065         * Default length (bit count).
066         */
067        public static final int DEFAULT_LENGTH = 1024;
068    
069        /**
070         * Default String format.
071         */
072        public static final StringFormat DEFAULT_STRING_FORMAT = StringFormat.STRICT_BINARY_STRING;
073    
074        /**
075         * Default endianness of packing operations.
076         */
077        public static final BinaryVectors.Endianness DEFAULT_ENDIANNESS = BinaryVectors.Endianness.BIG_ENDIAN;
078    
079        // PARAMETERS ======================================================================================================
080        /**
081         * Fingerprint length (bit count).
082         */
083        private final int length;
084    
085        /**
086         * String format to use.
087         */
088        private final StringFormat stringFormat;
089    
090        /**
091         * Endianness of long-int-byte-binary packing operations.
092         */
093        private final BinaryVectors.Endianness endianness;
094    
095        /**
096         * Constructor based on a builder.
097         *
098         * @param builder Builder which current state will be represented.
099         */
100        public BvParameters(Builder builder) {
101            this.length = builder.length;
102            this.stringFormat = builder.stringFormat;
103            this.endianness = builder.endianness;
104        }
105    
106        /**
107         * Construct with default values.
108         */
109        public BvParameters() {
110            this(new Builder());
111        }
112    
113        @Override
114        public BvGenerator getDescriptorGenerator() {
115            final ConstructBvGenerator c = ServiceUtil.loadService(ConstructBvGenerator.class, true);
116            return c.constructBvGenerator(this);
117        }
118    
119        @Override
120        public String toString() {
121            return "length: " + this.length + " bits,"
122                    + " string format: " + this.stringFormat + ","
123                    + " endianness " + this.endianness;
124        }
125    
126        /**
127         * Construct a builder for this parameter class, initialized to default.
128         *
129         * @return Builder initialized to default settings
130         */
131        public static Builder createNewBuilder() {
132            return new Builder();
133        }
134    
135        // GETTERS =========================================================================================================
136        /**
137         * Returns represented fingerprint length (bit count) setting.
138         *
139         * <p>
140         * Note that length is positive and multiply of 64 (bitcount of long).</p>
141         *
142         * @return Fingerprint length
143         */
144        public int getLength() {
145            return this.length;
146        }
147    
148        /**
149         * Returns represented string format.
150         *
151         * @return String format used when converting descriptors to/from strings
152         */
153        public StringFormat getStringFormat() {
154            return this.stringFormat;
155        }
156    
157        /**
158         * Endianness of packing operations.
159         *
160         * <p>
161         * Binary vectors (fingerprints) represent a fixed number of bits identified by bit indices. The same fingerprint
162         * can be represented as a binary string, int, long or byte array. The first bit (having index 0), always maps to
163         * the first element from each of the packed array representations. Further mapping is determined by the endianness
164         * parameter.</p>
165         *
166         * @return Endianness of packing operations.
167         */
168        public BinaryVectors.Endianness getEndianness() {
169            return this.endianness;
170        }
171    
172    
173        // HELPER INTERFACE FOR DI =========================================================================================
174        /**
175         * Interface representing BvGenerator implementation constructor
176         */
177        protected interface ConstructBvGenerator {
178    
179            /**
180             * Construct new instance
181             *
182             * @param parameters Generator parameter
183             * @return New generator implementation instance
184             */
185            BvGenerator constructBvGenerator(BvParameters parameters);
186        }
187    
188        // BUILDER CLASS ===================================================================================================
189        /**
190         * Builder for BvParameters.
191         */
192        public static class Builder implements ParameterBuilder<BvParameters> {
193    
194            /**
195             * Fingerprint length in bits.
196             */
197            @Parameter(order = 1)
198            @Description(
199                    shortName = "Length",
200                    name = "Fingerprint length",
201                    description = "The number ot bits used in the bit string representation (multiply of 64).")
202            private int length;
203    
204            /**
205             * String format used in io.
206             */
207            private StringFormat stringFormat;
208    
209            /**
210             * Endianness of packing between long-int-byte-binary representations.
211             */
212            private BinaryVectors.Endianness endianness;
213    
214            /**
215             * Constructor with default settings.
216             */
217            public Builder() {
218                this.length = DEFAULT_LENGTH;
219                this.stringFormat = DEFAULT_STRING_FORMAT;
220                this.endianness = DEFAULT_ENDIANNESS;
221            }
222    
223            /**
224             * Construct to represent the state of a parameter object instance.
225             *
226             * @param parameters Parameter object
227             */
228            public Builder(BvParameters parameters) {
229                this.length = parameters.getLength();
230                this.stringFormat = parameters.getStringFormat();
231                this.endianness = parameters.getEndianness();
232            }
233    
234            /**
235             * Set fingerprint length.
236             *
237             * @param length Fingerprint length (number of bits)
238             * @return Reference to this builder
239             * @throws IllegalArgumentException when the set length is not a positive number, or not multiply of 64
240             */
241            public Builder length(int length) {
242                if (length <= 0) {
243                    throw new IllegalArgumentException("Length should be positive: " + length);
244                }
245                if (length % Long.SIZE != 0) {
246                    throw new IllegalArgumentException("Length should be multiple of 64: " + length);
247                }
248                this.length = length;
249                return this;
250            }
251    
252            /**
253             * Set String format.
254             *
255             * @param stringFormat String format to use
256             * @return Reference to this builder
257             */
258            public Builder stringFormat(StringFormat stringFormat) {
259                Preconditions.checkNotNull(stringFormat);
260                this.stringFormat = stringFormat;
261                return this;
262            }
263    
264            /**
265             * Set endianness of packing operations.
266             *
267             * @param endianness Endianness of the packing operations
268             * @return Reference to this builder
269             */
270            public Builder endianness(BinaryVectors.Endianness endianness) {
271                Preconditions.checkNotNull(endianness);
272                this.endianness = endianness;
273                return this;
274            }
275    
276            @Override
277            public BvParameters build() {
278                return new BvParameters(this);
279            }
280    
281        }
282    
283    }