001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * docs/licenses/cddl.txt
011     * or http://www.opensource.org/licenses/cddl1.php.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * docs/licenses/cddl.txt.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2010-2012 UnboundID Corp.
026     */
027    package com.unboundid.directory.sdk.sync.types;
028    
029    import java.io.Serializable;
030    import java.util.Date;
031    
032    /**
033     * Used to identify how to set the starting point for synchronization (beginning
034     * of changelog, end of changelog, based on a change sequence number, etc).
035     * Different startpoint types require different supporting values; for example
036     * if the type is RESUME_AT_CHANGE_NUMBER, the value must be a <code>long</code>
037     * that represents a change number to start at. Some of the startpoint types
038     * require a server name to be specified as well.
039     * <p>
040     * These objects will be constructed by the <code>realtime-sync</code> CLI and
041     * passed down into the SetStartpointTask, which will then delegate to the
042     * specific Sync Pipe and finally the Sync Source implementation for that pipe.
043     * Not all Sync Source implementations will support all the startpoint types. If
044     * an unsupported type is specified, the underlying implementation is free to
045     * throw a {@link RuntimeException} stating that the startpoint type is
046     * unsupported.
047     */
048    public final class SetStartpointOptions
049    {
050    
051      /**
052       * The possible startpoint types.
053       */
054      public static enum StartpointType
055      {
056        /**
057         * Set the startpoint to a specific change sequence number in the change
058         * log.
059         * Note: This type is specific to directory servers.
060         */
061        RESUME_AT_CSN,
062        /**
063         * Set the startpoint to a specific change number in the change log.
064         */
065        RESUME_AT_CHANGE_NUMBER,
066        /**
067         * Set the startpoint to a specific time in the past.
068         */
069        RESUME_AT_CHANGE_TIME,
070        /**
071         * Set the startpoint using a user-defined Serializable object.
072         */
073        RESUME_AT_SERIALIZABLE,
074        /**
075         * Set the startpoint to the very beginning of the change log.
076         */
077        BEGINNING_OF_CHANGELOG,
078        /**
079         * Set the startpoint to the very end of the change log.
080         */
081        END_OF_CHANGELOG;
082      }
083    
084      // the startpoint type
085      private final StartpointType startpointType;
086    
087      // the possible startpoint values
088      private String csnValue;
089      private long changeNumber;
090      private Date changeTime;
091      private Serializable serializableValue;
092    
093      // the external server name, if one is required (change number, and change
094      // time)
095      private String serverName;
096    
097      /**
098       * Constructor.
099       * @param startpointType
100       *          indicates the startpoint type (beginning of changelog, change
101       *          time, etc)
102       */
103      private SetStartpointOptions(final StartpointType startpointType)
104      {
105        if(startpointType == null)
106        {
107          throw new NullPointerException(
108                  "The startpointType parameter cannot be null.");
109        }
110        this.startpointType = startpointType;
111      }
112    
113      /**
114       * Creates a SetStartpointOptions instance with the
115       * <code>BEGINNING_OF_CHANGELOG</code> startpoint type.
116       * @return a immutable instance of this class with only the startpoint type
117       *         populated
118       */
119      public static SetStartpointOptions createBeginningOfChangelogOptions()
120      {
121        SetStartpointOptions options =
122                new SetStartpointOptions(StartpointType.BEGINNING_OF_CHANGELOG);
123        return options;
124      }
125    
126      /**
127       * Creates a SetStartpointOptions instance with the
128       * <code>END_OF_CHANGELOG</code> startpoint type.
129       * @return a immutable instance of this class with only the startpoint type
130       *         populated
131       */
132      public static SetStartpointOptions createEndOfChangelogOptions()
133      {
134        SetStartpointOptions options =
135                new SetStartpointOptions(StartpointType.END_OF_CHANGELOG);
136        return options;
137      }
138    
139      /**
140       * Creates a SetStartpointOptions instance with the <code>RESUME_AT_CSN</code>
141       * startpoint type.
142       * @param csn
143       *          the change sequence number of the first change to synchronize
144       * @return a immutable instance of this class with the CSN value populated
145       */
146      public static SetStartpointOptions createResumeAtCSNOptions(final String csn)
147      {
148        if(csn == null)
149        {
150          throw new NullPointerException("The CSN parameter cannot be null");
151        }
152        SetStartpointOptions options =
153                new SetStartpointOptions(StartpointType.RESUME_AT_CSN);
154        options.csnValue = csn;
155        return options;
156      }
157    
158      /**
159       * Creates a SetStartpointOptions instance with the
160       * <code>RESUME_AT_CHANGE_NUMBER</code> startpoint type.
161       * @param changeNumber
162       *          the change number of the first change to synchronize
163       * @param serverName
164       *          the name of the External Server to which the change number
165       *          applies. The CLI
166       *          requires this parameter to be non-null, because a given change
167       *          number may
168       *          correspond to different changes on different replicas.
169       * @return a immutable instance of this class with the change number and
170       *         server name populated
171       */
172      public static SetStartpointOptions createResumeAtChangeNumberOptions(
173              final long changeNumber, final String serverName)
174      {
175        if(serverName == null)
176        {
177          throw new NullPointerException("The serverName parameter cannot be null");
178        }
179        SetStartpointOptions options =
180                new SetStartpointOptions(StartpointType.RESUME_AT_CHANGE_NUMBER);
181        options.changeNumber = changeNumber;
182        options.serverName = serverName;
183        return options;
184      }
185    
186      /**
187       * Creates a SetStartpointOptions instance with the
188       * <code>RESUME_AT_CHANGE_TIME</code> startpoint type. Changes
189       * made prior to the specified change time will be ignored.
190       * @param changeTime
191       *          the cut-off time at which synchronization will resume
192       * @param serverName
193       *          the name of the External Server to which the change time applies.
194       *          The CLI allows
195       *          this parameter to be null, but some underlying sync source
196       *          implementations
197       *          may require it (such as DSEESyncSource).
198       * @return a immutable instance of this class with the change time and server
199       *         name populated
200       */
201      public static SetStartpointOptions createResumeAtChangeTimeOptions(
202              final Date changeTime, final String serverName)
203      {
204        if(changeTime == null)
205        {
206          throw new NullPointerException("The changeTime parameter cannot be null");
207        }
208        SetStartpointOptions options =
209                new SetStartpointOptions(StartpointType.RESUME_AT_CHANGE_TIME);
210        options.changeTime = changeTime;
211        options.serverName = serverName;
212        return options;
213      }
214    
215      /**
216       * Creates a SetStartpointOptions instance with the
217       * <code>RESUME_AT_SERIALIZABLE</code> startpoint type. Changes made prior to
218       * the specified state will be ignored.
219       * @param startpointValue
220       *          a Serializable object which can be passed to the sync source as a
221       *          valid
222       *          indicator of where to start synchronization
223       * @return a immutable instance of this class with the generic startpoint
224       *         value populated
225       */
226      public static SetStartpointOptions createResumeAtSerializableOptions(
227              final Serializable startpointValue)
228      {
229        SetStartpointOptions options =
230                new SetStartpointOptions(StartpointType.RESUME_AT_SERIALIZABLE);
231        options.serializableValue = startpointValue;
232        return options;
233      }
234    
235      /**
236       * Gets the startpointType (i.e. RESUME_AT_CHANGE_NUMBER, END_OF_CHANGELOG,
237       * etc)
238       * @return a {@link StartpointType} instance
239       */
240      public StartpointType getStartpointType()
241      {
242        return this.startpointType;
243      }
244    
245      /**
246       * Gets the CSN value if one was specified.
247       * @return a change sequence number, or null if the startpoint type is not
248       *         <code>RESUME_AT_CSN</code>
249       */
250      public String getCSN()
251      {
252        return this.csnValue;
253      }
254    
255      /**
256       * Gets the change number value if one was specified.
257       * @return a change number, or null if the startpoint type is not
258       *         <code>RESUME_AT_CHANGE_NUMBER</code>
259       */
260      public long getChangeNumber()
261      {
262        return this.changeNumber;
263      }
264    
265      /**
266       * Gets the change time value if one was specified.
267       * @return a {@link Date}, or null if the startpoint type is not
268       *         <code>RESUME_AT_CHANGE_TIME</code>
269       */
270      public Date getChangeTime()
271      {
272        return this.changeTime;
273      }
274    
275      /**
276       * Gets the generic (serializable) startpoint value if one was specified.
277       * @return a {@link Serializable} instance, or null if the startpoint type is
278       *         not <code>RESUME_AT_SERIALIZABLE</code>
279       */
280      public Serializable getSerializableValue()
281      {
282        return this.serializableValue;
283      }
284    
285      /**
286       * Gets the server name if one was specified, representing the External Server
287       * at which to
288       * set the start point.
289       * @return an External Server name, or null if one was not specified
290       */
291      public String getServerName()
292      {
293        return this.serverName;
294      }
295    }