View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue;
21  
22  
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.List;
26  
27  import org.apache.directory.api.ldap.model.message.controls.AbstractControl;
28  import org.apache.directory.api.util.Strings;
29  
30  
31  /**
32   * A simple {@link SyncInfoValue} implementation to store control properties.
33   *
34   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
35   * @version $Rev$, $Date$
36   */
37  public class SyncInfoValueImpl extends AbstractControl implements SyncInfoValue
38  {
39      /** The kind of syncInfoValue we are dealing with */
40      private SynchronizationInfoEnum type;
41  
42      /** The cookie */
43      private byte[] cookie;
44  
45      /** The refreshDone flag if we are dealing with refreshXXX syncInfo. Default to true */
46      private boolean refreshDone = true;
47  
48      /** The refreshDeletes flag if we are dealing with syncIdSet syncInfo. Defaults to false */
49      private boolean refreshDeletes = false;
50  
51      /** The list of UUIDs if we are dealing with syncIdSet syncInfo */
52      private List<byte[]> syncUUIDs;
53  
54  
55      /**
56       * Creates a new instance of SyncInfoValueImpl.
57       */
58      public SyncInfoValueImpl()
59      {
60          super( OID );
61      }
62  
63  
64      /**
65       *
66       * Creates a new instance of SyncInfoValueImpl.
67       *
68       * @param isCritical The critical flag
69       */
70      public SyncInfoValueImpl( boolean isCritical )
71      {
72          super( OID, isCritical );
73      }
74  
75  
76      /**
77       * {@inheritDoc}
78       */
79      public SynchronizationInfoEnum getType()
80      {
81          return type;
82      }
83  
84  
85      /**
86       * {@inheritDoc}
87       */
88      public void setType( SynchronizationInfoEnum type )
89      {
90          this.type = type;
91      }
92  
93  
94      /**
95       * {@inheritDoc}
96       */
97      public byte[] getCookie()
98      {
99          return cookie;
100     }
101 
102 
103     /**
104      * {@inheritDoc}
105      */
106     public void setCookie( byte[] cookie )
107     {
108         this.cookie = cookie;
109     }
110 
111 
112     /**
113      * {@inheritDoc}
114      */
115     public boolean isRefreshDone()
116     {
117         return refreshDone;
118     }
119 
120 
121     /**
122      * {@inheritDoc}
123      */
124     public void setRefreshDone( boolean refreshDone )
125     {
126         this.refreshDone = refreshDone;
127     }
128 
129 
130     /**
131      * {@inheritDoc}
132      */
133     public boolean isRefreshDeletes()
134     {
135         return refreshDeletes;
136     }
137 
138 
139     /**
140      * {@inheritDoc}
141      */
142     public void setRefreshDeletes( boolean refreshDeletes )
143     {
144         this.refreshDeletes = refreshDeletes;
145     }
146 
147 
148     /**
149      * {@inheritDoc}
150      */
151     public List<byte[]> getSyncUUIDs()
152     {
153         return syncUUIDs;
154     }
155 
156 
157     /**
158      * {@inheritDoc}
159      */
160     public void setSyncUUIDs( List<byte[]> syncUUIDs )
161     {
162         this.syncUUIDs = syncUUIDs;
163     }
164 
165 
166     /**
167      * {@inheritDoc}
168      */
169     public void addSyncUUID( byte[] syncUUID )
170     {
171         if ( syncUUIDs == null )
172         {
173             syncUUIDs = new ArrayList<byte[]>();
174         }
175 
176         syncUUIDs.add( syncUUID );
177     }
178 
179 
180     /**
181      * @see Object#hashCode()
182      */
183     @Override
184     public int hashCode()
185     {
186         int h = 37;
187 
188         h = h * 17 + super.hashCode();
189         h = h * 17 + type.getValue();
190         h = h * 17 + ( refreshDone ? 1 : 0 );
191         h = h * 17 + ( refreshDeletes ? 1 : 0 );
192 
193         if ( cookie != null )
194         {
195             for ( byte b : cookie )
196             {
197                 h = h * 17 + b;
198             }
199         }
200 
201         if ( syncUUIDs != null )
202         {
203             for ( byte[] bytes : syncUUIDs )
204             {
205                 if ( bytes != null )
206                 {
207                     for ( byte b : bytes )
208                     {
209                         h = h * 17 + b;
210                     }
211                 }
212             }
213         }
214 
215         return h;
216     }
217 
218 
219     /**
220      * @see Object#equals(Object)
221      */
222     @Override
223     public boolean equals( Object o )
224     {
225         if ( this == o )
226         {
227             return true;
228         }
229 
230         if ( !( o instanceof SyncInfoValue ) )
231         {
232             return false;
233         }
234 
235         SyncInfoValue otherControl = ( SyncInfoValue ) o;
236 
237         if ( syncUUIDs != null )
238         {
239             if ( otherControl.getSyncUUIDs() == null )
240             {
241                 return false;
242             }
243 
244             // @TODO : this is extremely heavy... We have to find a better way to
245             // compare the lists of suncUuids, but atm, it's enough.
246             for ( byte[] syncUuid : syncUUIDs )
247             {
248                 boolean found = false;
249 
250                 for ( byte[] otherSyncUuid : otherControl.getSyncUUIDs() )
251                 {
252                     if ( Arrays.equals( syncUuid, otherSyncUuid ) )
253                     {
254                         found = true;
255                         break;
256                     }
257                 }
258 
259                 if ( !found )
260                 {
261                     return false;
262                 }
263             }
264         }
265         else
266         {
267             if ( otherControl.getSyncUUIDs() != null )
268             {
269                 return false;
270             }
271         }
272 
273         return ( refreshDeletes == otherControl.isRefreshDeletes() ) &&
274             ( refreshDone == otherControl.isRefreshDone() ) &&
275             ( type == otherControl.getType() ) &&
276             ( Arrays.equals( cookie, otherControl.getCookie() ) &&
277             ( isCritical() == otherControl.isCritical() ) );
278     }
279 
280 
281     /**
282      * @see Object#toString()
283      */
284     @Override
285     public String toString()
286     {
287         StringBuilder sb = new StringBuilder();
288 
289         sb.append( "    SyncInfoValue control :\n" );
290         sb.append( "        oid : " ).append( getOid() ).append( '\n' );
291         sb.append( "        critical : " ).append( isCritical() ).append( '\n' );
292 
293         switch ( getType() )
294         {
295             case NEW_COOKIE:
296                 sb.append( "        newCookie : '" ).
297                     append( Strings.utf8ToString( getCookie() ) ).append( "'\n" );
298                 break;
299 
300             case REFRESH_DELETE:
301                 sb.append( "        refreshDelete : \n" );
302 
303                 if ( getCookie() != null )
304                 {
305                     sb.append( "            cookie : '" ).
306                         append( Strings.dumpBytes( getCookie() ) ).append( "'\n" );
307                 }
308 
309                 sb.append( "            refreshDone : " ).append( isRefreshDone() ).append( '\n' );
310                 break;
311 
312             case REFRESH_PRESENT:
313                 sb.append( "        refreshPresent : \n" );
314 
315                 if ( getCookie() != null )
316                 {
317                     sb.append( "            cookie : '" ).
318                         append( Strings.dumpBytes( getCookie() ) ).append( "'\n" );
319                 }
320 
321                 sb.append( "            refreshDone : " ).append( isRefreshDone() ).append( '\n' );
322                 break;
323 
324             case SYNC_ID_SET:
325                 sb.append( "        syncIdSet : \n" );
326 
327                 if ( getCookie() != null )
328                 {
329                     sb.append( "            cookie : '" ).
330                         append( Strings.dumpBytes( getCookie() ) ).append( "'\n" );
331                 }
332 
333                 sb.append( "            refreshDeletes : " ).append( isRefreshDeletes() ).append( '\n' );
334                 sb.append( "            syncUUIDS : " );
335 
336                 if ( getSyncUUIDs().size() != 0 )
337                 {
338                     boolean isFirst = true;
339 
340                     for ( byte[] syncUUID : getSyncUUIDs() )
341                     {
342                         if ( isFirst )
343                         {
344                             isFirst = false;
345                         }
346                         else
347                         {
348                             sb.append( ", " );
349                         }
350 
351                         sb.append( Arrays.toString( syncUUID ) );
352                     }
353 
354                     sb.append( '\n' );
355                 }
356                 else
357                 {
358                     sb.append( "empty\n" );
359                 }
360 
361                 break;
362         }
363 
364         return sb.toString();
365     }
366 }