001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.ldap.aci; 021 022 023import java.util.Collections; 024import java.util.HashSet; 025import java.util.Set; 026 027import org.apache.directory.api.ldap.model.name.Dn; 028import org.apache.directory.api.ldap.model.subtree.SubtreeSpecification; 029 030 031/** 032 * Defines a set of zero or more users the permissions apply to. 033 * 034 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 035 */ 036public abstract class UserClass 037{ 038 /** 039 * Every directory user (with possible requirements for 040 * authenticationLevel). 041 */ 042 public static final AllUsers ALL_USERS = new AllUsers(); 043 044 /** 045 * The user with the same distinguished name as the entry being accessed, or 046 * if the entry is a member of a family, then additionally the user with the 047 * distinguished name of the ancestor. 048 */ 049 public static final ThisEntry THIS_ENTRY = new ThisEntry(); 050 051 /** 052 * The user as parent (ancestor) of accessed entry. 053 */ 054 public static final ParentOfEntry PARENT_OF_ENTRY = new ParentOfEntry(); 055 056 057 /** 058 * Creates a new instance. 059 */ 060 protected UserClass() 061 { 062 } 063 064 065 /** 066 * Every directory user (with possible requirements for 067 * authenticationLevel). 068 */ 069 public static final class AllUsers extends UserClass 070 { 071 /** 072 * Creates a new instance of AllUsers. 073 */ 074 private AllUsers() 075 { 076 } 077 078 079 /** 080 * {@inheritDoc} 081 */ 082 @Override 083 public String toString() 084 { 085 return "allUsers"; 086 } 087 } 088 089 090 /** 091 * The user with the same distinguished name as the entry being accessed, or 092 * if the entry is a member of a family, then additionally the user with the 093 * distinguished name of the ancestor. 094 */ 095 public static final class ThisEntry extends UserClass 096 { 097 /** 098 * Creates a new instance of ThisEntry. 099 */ 100 private ThisEntry() 101 { 102 } 103 104 105 /** 106 * {@inheritDoc} 107 */ 108 @Override 109 public String toString() 110 { 111 return "thisEntry"; 112 } 113 } 114 115 116 /** 117 * The user as parent (ancestor) of accessed entry. 118 */ 119 public static final class ParentOfEntry extends UserClass 120 { 121 /** 122 * Creates a new instance of ParentOfEntry. 123 */ 124 private ParentOfEntry() 125 { 126 } 127 128 129 /** 130 * {@inheritDoc} 131 */ 132 @Override 133 public String toString() 134 { 135 return "parentOfEntry"; 136 } 137 } 138 139 140 /** 141 * A base class for all user classes which has a set of DNs. 142 */ 143 private abstract static class NamedUserClass extends UserClass 144 { 145 /** The names. */ 146 protected final Set<Dn> names; 147 148 149 /** 150 * Creates a new instance. 151 * 152 * @param names a set of names 153 */ 154 protected NamedUserClass( Set<Dn> names ) 155 { 156 if ( names == null ) 157 { 158 this.names = Collections.unmodifiableSet( new HashSet<Dn>() ); 159 } 160 else 161 { 162 this.names = Collections.unmodifiableSet( new HashSet<Dn>( names ) ); 163 } 164 } 165 166 167 /** 168 * Returns the set of all names. 169 * 170 * @return The set of all names 171 */ 172 public Set<Dn> getNames() 173 { 174 return names; 175 } 176 177 178 /** 179 * {@inheritDoc} 180 */ 181 @Override 182 public boolean equals( Object o ) 183 { 184 if ( this == o ) 185 { 186 return true; 187 } 188 189 if ( o == null ) 190 { 191 return false; 192 } 193 194 if ( getClass().isAssignableFrom( o.getClass() ) ) 195 { 196 Name that = ( Name ) o; 197 198 return names.equals( that.names ); 199 } 200 201 return false; 202 } 203 204 205 /** 206 * {@inheritDoc} 207 */ 208 @Override 209 public int hashCode() 210 { 211 int result = 37; 212 213 // Use a slightly different hashcode here : we multiple 214 // each DN in the set with the result to have a result that 215 // is not dependent on the DN order in the Set. 216 // In order to avoid result of 0 if one of the DN hashcode, 217 // we discard them. 218 for ( Dn dn : this.names ) 219 { 220 int h = dn.hashCode(); 221 222 if ( h != 0 ) 223 { 224 result = result * h; 225 } 226 } 227 228 return result; 229 } 230 231 232 /** 233 * {@inheritDoc} 234 */ 235 @Override 236 public String toString() 237 { 238 StringBuilder buffer = new StringBuilder(); 239 240 boolean isFirst = true; 241 buffer.append( "{ " ); 242 243 for ( Dn name : names ) 244 { 245 if ( isFirst ) 246 { 247 isFirst = false; 248 } 249 else 250 { 251 buffer.append( ", " ); 252 } 253 254 buffer.append( '"' ); 255 buffer.append( name.toString() ); 256 buffer.append( '"' ); 257 } 258 259 buffer.append( " }" ); 260 261 return buffer.toString(); 262 } 263 } 264 265 266 /** 267 * The user with the specified distinguished name. 268 */ 269 public static class Name extends NamedUserClass 270 { 271 /** 272 * Creates a new instance. 273 * 274 * @param usernames the set of user DNs. 275 */ 276 public Name( Set<Dn> usernames ) 277 { 278 super( usernames ); 279 } 280 281 282 /** 283 * {@inheritDoc} 284 */ 285 @Override 286 public String toString() 287 { 288 return "name " + super.toString(); 289 } 290 } 291 292 293 /** 294 * The set of users who are members of the groupOfUniqueNames entry, 295 * identified by the specified distinguished name. Members of a group of 296 * unique names are treated as individual object names, and not as the names 297 * of other groups of unique names. 298 */ 299 public static class UserGroup extends NamedUserClass 300 { 301 /** 302 * Creates a new instance. 303 * 304 * @param groupNames the set of group DNs. 305 */ 306 public UserGroup( Set<Dn> groupNames ) 307 { 308 super( groupNames ); 309 } 310 311 312 /** 313 * {@inheritDoc} 314 */ 315 @Override 316 public String toString() 317 { 318 return "userGroup " + super.toString(); 319 } 320 } 321 322 323 /** 324 * The set of users whose distinguished names fall within the definition of 325 * the (unrefined) subtree. 326 */ 327 public static class Subtree extends UserClass 328 { 329 /** The subtree specifications. */ 330 protected final Set<SubtreeSpecification> subtreeSpecifications; 331 332 333 /** 334 * Creates a new instance. 335 * 336 * @param subtreeSpecs the collection of unrefined {@link SubtreeSpecification}s. 337 */ 338 public Subtree( Set<SubtreeSpecification> subtreeSpecs ) 339 { 340 subtreeSpecifications = Collections.unmodifiableSet( subtreeSpecs ); 341 } 342 343 344 /** 345 * Returns the collection of unrefined {@link SubtreeSpecification}s. 346 * 347 * @return the subtree specifications 348 */ 349 public Set<SubtreeSpecification> getSubtreeSpecifications() 350 { 351 return subtreeSpecifications; 352 } 353 354 355 /** 356 * {@inheritDoc} 357 */ 358 @Override 359 public int hashCode() 360 { 361 int hash = 37; 362 hash = hash * 17 + subtreeSpecifications.hashCode(); 363 364 return hash; 365 } 366 367 368 /** 369 * {@inheritDoc} 370 */ 371 @Override 372 public boolean equals( Object o ) 373 { 374 if ( this == o ) 375 { 376 return true; 377 } 378 379 if ( o instanceof Subtree ) 380 { 381 Subtree that = ( Subtree ) o; 382 383 return subtreeSpecifications.equals( that.subtreeSpecifications ); 384 } 385 386 return false; 387 } 388 389 390 /** 391 * {@inheritDoc} 392 */ 393 @Override 394 public String toString() 395 { 396 StringBuilder buffer = new StringBuilder(); 397 398 boolean isFirst = true; 399 buffer.append( "subtree { " ); 400 401 for ( SubtreeSpecification ss : subtreeSpecifications ) 402 { 403 if ( isFirst ) 404 { 405 isFirst = false; 406 } 407 else 408 { 409 buffer.append( ", " ); 410 } 411 412 ss.toString( buffer ); 413 } 414 415 buffer.append( " }" ); 416 417 return buffer.toString(); 418 } 419 } 420}