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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 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 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.controls; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.HashSet; 033 import java.util.Iterator; 034 import java.util.Set; 035 036 import org.opends.server.protocols.ldap.LDAPResultCode; 037 import org.opends.server.types.LDAPException; 038 039 import static org.opends.messages.ProtocolMessages.*; 040 041 042 043 /** 044 * This enumeration defines the set of possible change types that may be used in 045 * conjunction with the persistent search control, as defined in 046 * draft-ietf-ldapext-psearch. 047 */ 048 public enum PersistentSearchChangeType 049 { 050 /** 051 * The change type that will be used for add operations. 052 */ 053 ADD(1), 054 055 056 057 /** 058 * The change type that will be used for delete operations. 059 */ 060 DELETE(2), 061 062 063 064 /** 065 * The change type that will be used for modify operations. 066 */ 067 MODIFY(4), 068 069 070 071 /** 072 * The change type that will be used for modify DN operations. 073 */ 074 MODIFY_DN(8); 075 076 077 078 // The integer value associated with this change type. 079 private int intValue; 080 081 082 083 /** 084 * Creates a new instance of a persistent search change type with the provided 085 * integer value. 086 * 087 * @param intValue The integer value associated with this change type. 088 */ 089 private PersistentSearchChangeType(int intValue) 090 { 091 this.intValue = intValue; 092 } 093 094 095 096 /** 097 * Retrieves the integer value associated with this change type. 098 * 099 * @return The integer value associated with this change type. 100 */ 101 public int intValue() 102 { 103 return intValue; 104 } 105 106 107 108 /** 109 * Retrieves a string representation of this persistent search change type. 110 * 111 * @return A string representation of this persistent search change type, or 112 * "unknown" if it has an unknown type. 113 */ 114 public String toString() 115 { 116 switch (intValue) 117 { 118 case 1: 119 return "add"; 120 case 2: 121 return "delete"; 122 case 4: 123 return "modify"; 124 case 8: 125 return "modDN"; 126 default: 127 return "unknown"; 128 } 129 } 130 131 132 133 /** 134 * Retrieves the change type associated with the provided integer value. 135 * 136 * @param intValue The integer value to decode as a change type. 137 * 138 * @return The change type corresponding to the provided integer value. 139 * 140 * @throws LDAPException If the provided integer value is not associated 141 * with a valid change type. 142 */ 143 public static PersistentSearchChangeType valueOf(int intValue) 144 throws LDAPException 145 { 146 switch (intValue) 147 { 148 case 1: 149 return ADD; 150 case 2: 151 return DELETE; 152 case 4: 153 return MODIFY; 154 case 8: 155 return MODIFY_DN; 156 default: 157 Message message = ERR_PSEARCH_CHANGETYPES_INVALID_TYPE.get(intValue); 158 throw new LDAPException(LDAPResultCode.CONSTRAINT_VIOLATION, message); 159 } 160 } 161 162 163 164 /** 165 * Decodes the provided int value into a set of change types as per the 166 * specification in draft-ietf-ldapext-psearch. 167 * 168 * @param intValue The integer value representing the encoded change types. 169 * 170 * @return The set of change types decoded from the provided integer value. 171 * 172 * @throws LDAPException If the provided integer value does not represent a 173 * valid encoded set of change types. 174 */ 175 public static Set<PersistentSearchChangeType> intToTypes(int intValue) 176 throws LDAPException 177 { 178 HashSet<PersistentSearchChangeType> changeTypes = 179 new HashSet<PersistentSearchChangeType>(4); 180 181 switch (intValue) 182 { 183 case 0: 184 // No change types are included. This won't be allowed because it 185 // doesn't make any sense. 186 Message message = ERR_PSEARCH_CHANGETYPES_NO_TYPES.get(); 187 throw new LDAPException(LDAPResultCode.CONSTRAINT_VIOLATION, message); 188 case 1: 189 changeTypes.add(ADD); 190 break; 191 case 2: 192 changeTypes.add(DELETE); 193 break; 194 case 3: 195 changeTypes.add(ADD); 196 changeTypes.add(DELETE); 197 break; 198 case 4: 199 changeTypes.add(MODIFY); 200 break; 201 case 5: 202 changeTypes.add(ADD); 203 changeTypes.add(MODIFY); 204 break; 205 case 6: 206 changeTypes.add(DELETE); 207 changeTypes.add(MODIFY); 208 break; 209 case 7: 210 changeTypes.add(ADD); 211 changeTypes.add(DELETE); 212 changeTypes.add(MODIFY); 213 break; 214 case 8: 215 changeTypes.add(MODIFY_DN); 216 break; 217 case 9: 218 changeTypes.add(ADD); 219 changeTypes.add(MODIFY_DN); 220 break; 221 case 10: 222 changeTypes.add(DELETE); 223 changeTypes.add(MODIFY_DN); 224 break; 225 case 11: 226 changeTypes.add(ADD); 227 changeTypes.add(DELETE); 228 changeTypes.add(MODIFY_DN); 229 break; 230 case 12: 231 changeTypes.add(MODIFY); 232 changeTypes.add(MODIFY_DN); 233 break; 234 case 13: 235 changeTypes.add(ADD); 236 changeTypes.add(MODIFY); 237 changeTypes.add(MODIFY_DN); 238 break; 239 case 14: 240 changeTypes.add(DELETE); 241 changeTypes.add(MODIFY); 242 changeTypes.add(MODIFY_DN); 243 break; 244 case 15: 245 changeTypes.add(ADD); 246 changeTypes.add(DELETE); 247 changeTypes.add(MODIFY); 248 changeTypes.add(MODIFY_DN); 249 break; 250 default: 251 message = ERR_PSEARCH_CHANGETYPES_INVALID_TYPES.get(intValue); 252 throw new LDAPException(LDAPResultCode.CONSTRAINT_VIOLATION, message); 253 } 254 255 return changeTypes; 256 } 257 258 259 260 /** 261 * Retrieves the integer representation of the provided set of change types. 262 * 263 * @param changeTypes The set of change types to be encoded. 264 * 265 * @return The integer representation of the provided set of change types. 266 */ 267 public static int changeTypesToInt(Set<PersistentSearchChangeType> 268 changeTypes) 269 { 270 int intValue = 0; 271 272 if (changeTypes.contains(ADD)) 273 { 274 intValue |= 1; 275 } 276 277 if (changeTypes.contains(DELETE)) 278 { 279 intValue |= 2; 280 } 281 282 if (changeTypes.contains(MODIFY)) 283 { 284 intValue |= 4; 285 } 286 287 if (changeTypes.contains(MODIFY_DN)) 288 { 289 intValue |= 8; 290 } 291 292 return intValue; 293 } 294 295 296 297 /** 298 * Retrieves a string representation of the provided set of change types. 299 * 300 * @param changeTypes The set of change types to encode. 301 * 302 * @return A string representation of the provided set of change types. 303 */ 304 public static String changeTypesToString(Set<PersistentSearchChangeType> 305 changeTypes) 306 { 307 StringBuilder buffer = new StringBuilder(); 308 changeTypesToString(changeTypes, buffer); 309 return buffer.toString(); 310 } 311 312 313 314 /** 315 * Appends a string representation of the specified set of change types to the 316 * provided buffer. 317 * 318 * @param changeTypes The set of change types to encode. 319 * @param buffer The buffer to which the information should be written. 320 */ 321 public static void changeTypesToString(Set<PersistentSearchChangeType> 322 changeTypes, 323 StringBuilder buffer) 324 { 325 Iterator<PersistentSearchChangeType> iterator = changeTypes.iterator(); 326 if (iterator.hasNext()) 327 { 328 buffer.append(iterator.next().toString()); 329 330 while (iterator.hasNext()) 331 { 332 buffer.append("|"); 333 buffer.append(iterator.next().toString()); 334 } 335 } 336 } 337 } 338