View Javadoc
1   /*
2    * #%L
3    * MongoTimestampElement.java - mongodb-async-driver - Allanbank Consulting, Inc.
4    * %%
5    * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * 
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package com.allanbank.mongodb.bson.element;
21  
22  import com.allanbank.mongodb.bson.Element;
23  import com.allanbank.mongodb.bson.ElementType;
24  import com.allanbank.mongodb.bson.Visitor;
25  import com.allanbank.mongodb.bson.io.StringEncoder;
26  
27  /**
28   * A wrapper for a BSON (signed 64-bit) Mongo timestamp as 4 byte increment and
29   * 4 byte timestamp.
30   * 
31   * @api.yes This class is part of the driver's API. Public and protected members
32   *          will be deprecated for at least 1 non-bugfix release (version
33   *          numbers are <major>.<minor>.<bugfix>) before being
34   *          removed or modified.
35   * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
36   */
37  public class MongoTimestampElement extends AbstractElement {
38  
39      /** The BSON type for a long. */
40      public static final ElementType TYPE = ElementType.MONGO_TIMESTAMP;
41  
42      /** Serialization version for the class. */
43      private static final long serialVersionUID = -402083578422199042L;
44  
45      /**
46       * Computes and returns the number of bytes that are used to encode the
47       * element.
48       * 
49       * @param name
50       *            The name for the element.
51       * @return The size of the element when encoded in bytes.
52       */
53      private static long computeSize(final String name) {
54          long result = 10; // type (1) + name null byte (1) + value (8).
55          result += StringEncoder.utf8Size(name);
56  
57          return result;
58      }
59  
60      /** The BSON timestamp value as 4 byte increment and 4 byte timestamp. */
61      private final long myTimestamp;
62  
63      /**
64       * Constructs a new {@link MongoTimestampElement}.
65       * 
66       * @param name
67       *            The name for the BSON long.
68       * @param value
69       *            The BSON timestamp value as 4 byte increment and 4 byte
70       *            timestamp.
71       * @throws IllegalArgumentException
72       *             If the {@code name} is <code>null</code>.
73       */
74      public MongoTimestampElement(final String name, final long value) {
75          this(name, value, computeSize(name));
76      }
77  
78      /**
79       * Constructs a new {@link MongoTimestampElement}.
80       * 
81       * @param name
82       *            The name for the BSON long.
83       * @param value
84       *            The BSON timestamp value as 4 byte increment and 4 byte
85       *            timestamp.
86       * @param size
87       *            The size of the element when encoded in bytes. If not known
88       *            then use the
89       *            {@link MongoTimestampElement#MongoTimestampElement(String, long)}
90       *            constructor instead.
91       * @throws IllegalArgumentException
92       *             If the {@code name} is <code>null</code>.
93       */
94      public MongoTimestampElement(final String name, final long value,
95              final long size) {
96          super(name, size);
97  
98          myTimestamp = value;
99      }
100 
101     /**
102      * Accepts the visitor and calls the {@link Visitor#visitMongoTimestamp}
103      * method.
104      * 
105      * @see Element#accept(Visitor)
106      */
107     @Override
108     public void accept(final Visitor visitor) {
109         visitor.visitMongoTimestamp(getName(), getTime());
110     }
111 
112     /**
113      * {@inheritDoc}
114      * <p>
115      * Overridden to compare the times if the base class comparison is equals.
116      * </p>
117      * <p>
118      * Note that for MongoDB {@link MongoTimestampElement} and
119      * {@link TimestampElement} will return equal based on the type. Care is
120      * taken here to make sure that the values return the same value regardless
121      * of comparison order.
122      * </p>
123      */
124     @Override
125     public int compareTo(final Element otherElement) {
126         int result = super.compareTo(otherElement);
127 
128         if (result == 0) {
129             // Might be a MongoTimestampElement or TimestampElement.
130             final ElementType otherType = otherElement.getType();
131 
132             if (otherType == ElementType.MONGO_TIMESTAMP) {
133                 result = compare(getTime(),
134                         ((MongoTimestampElement) otherElement).getTime());
135             }
136             else {
137                 result = compare(getTime(),
138                         ((TimestampElement) otherElement).getTime());
139             }
140         }
141 
142         return result;
143     }
144 
145     /**
146      * Determines if the passed object is of this same type as this object and
147      * if so that its fields are equal.
148      * 
149      * @param object
150      *            The object to compare to.
151      * 
152      * @see java.lang.Object#equals(java.lang.Object)
153      */
154     @Override
155     public boolean equals(final Object object) {
156         boolean result = false;
157         if (this == object) {
158             result = true;
159         }
160         else if ((object != null) && (getClass() == object.getClass())) {
161             final MongoTimestampElement other = (MongoTimestampElement) object;
162 
163             result = super.equals(object) && (myTimestamp == other.myTimestamp);
164         }
165         return result;
166     }
167 
168     /**
169      * Returns the BSON Mongo timestamp value as 4 byte increment and 4 byte
170      * timestamp.
171      * 
172      * @return The BSON Mongo timestamp value as 4 byte increment and 4 byte
173      *         timestamp.
174      */
175     public long getTime() {
176         return myTimestamp;
177     }
178 
179     /**
180      * {@inheritDoc}
181      */
182     @Override
183     public ElementType getType() {
184         return TYPE;
185     }
186 
187     /**
188      * {@inheritDoc}
189      * <p>
190      * Returns a {@link Long} with the value of the timestamp.
191      * </p>
192      * <p>
193      * <b>Note:</b> This value will not be recreated is a Object-->Element
194      * conversion. Long with the value of the timestamp is created instead.
195      * </p>
196      */
197     @Override
198     public Long getValueAsObject() {
199         return Long.valueOf(myTimestamp);
200     }
201 
202     /**
203      * Computes a reasonable hash code.
204      * 
205      * @return The hash code value.
206      */
207     @Override
208     public int hashCode() {
209         int result = 1;
210         result = (31 * result) + super.hashCode();
211         result = (31 * result) + (int) ((myTimestamp >> 32) & 0xFFFFFFFF);
212         result = (31 * result) + (int) (myTimestamp & 0xFFFFFFFF);
213         return result;
214     }
215 
216     /**
217      * {@inheritDoc}
218      * <p>
219      * Returns a new {@link MongoTimestampElement}.
220      * </p>
221      */
222     @Override
223     public MongoTimestampElement withName(final String name) {
224         if (getName().equals(name)) {
225             return this;
226         }
227         return new MongoTimestampElement(name, myTimestamp);
228     }
229 }