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      @Override
80      public SynchronizationInfoEnum getType()
81      {
82          return type;
83      }
84  
85  
86      /**
87       * {@inheritDoc}
88       */
89      @Override
90      public void setType( SynchronizationInfoEnum type )
91      {
92          this.type = type;
93      }
94  
95  
96      /**
97       * {@inheritDoc}
98       */
99      @Override
100     public byte[] getCookie()
101     {
102         return cookie;
103     }
104 
105 
106     /**
107      * {@inheritDoc}
108      */
109     @Override
110     public void setCookie( byte[] cookie )
111     {
112         this.cookie = cookie;
113     }
114 
115 
116     /**
117      * {@inheritDoc}
118      */
119     @Override
120     public boolean isRefreshDone()
121     {
122         return refreshDone;
123     }
124 
125 
126     /**
127      * {@inheritDoc}
128      */
129     @Override
130     public void setRefreshDone( boolean refreshDone )
131     {
132         this.refreshDone = refreshDone;
133     }
134 
135 
136     /**
137      * {@inheritDoc}
138      */
139     @Override
140     public boolean isRefreshDeletes()
141     {
142         return refreshDeletes;
143     }
144 
145 
146     /**
147      * {@inheritDoc}
148      */
149     @Override
150     public void setRefreshDeletes( boolean refreshDeletes )
151     {
152         this.refreshDeletes = refreshDeletes;
153     }
154 
155 
156     /**
157      * {@inheritDoc}
158      */
159     @Override
160     public List<byte[]> getSyncUUIDs()
161     {
162         return syncUUIDs;
163     }
164 
165 
166     /**
167      * {@inheritDoc}
168      */
169     @Override
170     public void setSyncUUIDs( List<byte[]> syncUUIDs )
171     {
172         this.syncUUIDs = syncUUIDs;
173     }
174 
175 
176     /**
177      * {@inheritDoc}
178      */
179     @Override
180     public void addSyncUUID( byte[] syncUUID )
181     {
182         if ( syncUUIDs == null )
183         {
184             syncUUIDs = new ArrayList<>();
185         }
186 
187         syncUUIDs.add( syncUUID );
188     }
189 
190 
191     /**
192      * @see Object#hashCode()
193      */
194     @Override
195     public int hashCode()
196     {
197         int h = 37;
198 
199         h = h * 17 + super.hashCode();
200         h = h * 17 + type.getValue();
201         h = h * 17 + ( refreshDone ? 1 : 0 );
202         h = h * 17 + ( refreshDeletes ? 1 : 0 );
203 
204         if ( cookie != null )
205         {
206             for ( byte b : cookie )
207             {
208                 h = h * 17 + b;
209             }
210         }
211 
212         if ( syncUUIDs != null )
213         {
214             for ( byte[] bytes : syncUUIDs )
215             {
216                 if ( bytes != null )
217                 {
218                     for ( byte b : bytes )
219                     {
220                         h = h * 17 + b;
221                     }
222                 }
223             }
224         }
225 
226         return h;
227     }
228 
229 
230     /**
231      * @see Object#equals(Object)
232      */
233     @Override
234     public boolean equals( Object o )
235     {
236         if ( this == o )
237         {
238             return true;
239         }
240 
241         if ( !( o instanceof SyncInfoValue ) )
242         {
243             return false;
244         }
245 
246         SyncInfoValue otherControl = ( SyncInfoValue ) o;
247 
248         if ( syncUUIDs != null )
249         {
250             if ( otherControl.getSyncUUIDs() == null )
251             {
252                 return false;
253             }
254 
255             // @TODO : this is extremely heavy... We have to find a better way to
256             // compare the lists of suncUuids, but atm, it's enough.
257             for ( byte[] syncUuid : syncUUIDs )
258             {
259                 boolean found = false;
260 
261                 for ( byte[] otherSyncUuid : otherControl.getSyncUUIDs() )
262                 {
263                     if ( Arrays.equals( syncUuid, otherSyncUuid ) )
264                     {
265                         found = true;
266                         break;
267                     }
268                 }
269 
270                 if ( !found )
271                 {
272                     return false;
273                 }
274             }
275         }
276         else
277         {
278             if ( otherControl.getSyncUUIDs() != null )
279             {
280                 return false;
281             }
282         }
283 
284         return ( refreshDeletes == otherControl.isRefreshDeletes() )
285             && ( refreshDone == otherControl.isRefreshDone() )
286             && ( type == otherControl.getType() )
287             && ( Arrays.equals( cookie, otherControl.getCookie() ) ) 
288             && ( isCritical() == otherControl.isCritical() );
289     }
290 
291 
292     /**
293      * @see Object#toString()
294      */
295     @Override
296     public String toString()
297     {
298         StringBuilder sb = new StringBuilder();
299 
300         sb.append( "    SyncInfoValue control :\n" );
301         sb.append( "        oid : " ).append( getOid() ).append( '\n' );
302         sb.append( "        critical : " ).append( isCritical() ).append( '\n' );
303 
304         switch ( getType() )
305         {
306             case NEW_COOKIE:
307                 sb.append( "        newCookie : '" ).
308                     append( Strings.utf8ToString( getCookie() ) ).append( "'\n" );
309                 break;
310 
311             case REFRESH_DELETE:
312                 sb.append( "        refreshDelete : \n" );
313 
314                 if ( getCookie() != null )
315                 {
316                     sb.append( "            cookie : '" ).
317                         append( Strings.dumpBytes( getCookie() ) ).append( "'\n" );
318                 }
319 
320                 sb.append( "            refreshDone : " ).append( isRefreshDone() ).append( '\n' );
321                 break;
322 
323             case REFRESH_PRESENT:
324                 sb.append( "        refreshPresent : \n" );
325 
326                 if ( getCookie() != null )
327                 {
328                     sb.append( "            cookie : '" ).
329                         append( Strings.dumpBytes( getCookie() ) ).append( "'\n" );
330                 }
331 
332                 sb.append( "            refreshDone : " ).append( isRefreshDone() ).append( '\n' );
333                 break;
334 
335             case SYNC_ID_SET:
336                 sb.append( "        syncIdSet : \n" );
337 
338                 if ( getCookie() != null )
339                 {
340                     sb.append( "            cookie : '" ).
341                         append( Strings.dumpBytes( getCookie() ) ).append( "'\n" );
342                 }
343 
344                 sb.append( "            refreshDeletes : " ).append( isRefreshDeletes() ).append( '\n' );
345                 sb.append( "            syncUUIDS : " );
346 
347                 if ( !getSyncUUIDs().isEmpty() )
348                 {
349                     boolean isFirst = true;
350 
351                     for ( byte[] syncUUID : getSyncUUIDs() )
352                     {
353                         if ( isFirst )
354                         {
355                             isFirst = false;
356                         }
357                         else
358                         {
359                             sb.append( ", " );
360                         }
361 
362                         sb.append( Arrays.toString( syncUUID ) );
363                     }
364 
365                     sb.append( '\n' );
366                 }
367                 else
368                 {
369                     sb.append( "empty\n" );
370                 }
371 
372                 break;
373 
374             default:
375                 throw new IllegalArgumentException( "Unexpected SynchronizationInfo: " + getType() );
376         }
377 
378         return sb.toString();
379     }
380 }