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            for ( Dn dn : this.names )
214            {
215                result = result * 17 + dn.hashCode();
216            }
217
218            return result;
219        }
220
221
222        /**
223         * {@inheritDoc}
224         */
225        public String toString()
226        {
227            StringBuilder buffer = new StringBuilder();
228
229            boolean isFirst = true;
230            buffer.append( "{ " );
231
232            for ( Dn name : names )
233            {
234                if ( isFirst )
235                {
236                    isFirst = false;
237                }
238                else
239                {
240                    buffer.append( ", " );
241                }
242
243                buffer.append( '"' );
244                buffer.append( name.toString() );
245                buffer.append( '"' );
246            }
247
248            buffer.append( " }" );
249
250            return buffer.toString();
251        }
252    }
253    
254
255    /**
256     * The user with the specified distinguished name.
257     */
258    public static class Name extends NamedUserClass
259    {
260        /**
261         * Creates a new instance.
262         * 
263         * @param usernames the set of user DNs.
264         */
265        public Name( Set<Dn> usernames )
266        {
267            super( usernames );
268        }
269
270
271        /**
272         * {@inheritDoc}
273         */
274        @Override
275        public String toString()
276        {
277            return "name " + super.toString();
278        }
279    }
280    
281
282    /**
283     * The set of users who are members of the groupOfUniqueNames entry,
284     * identified by the specified distinguished name. Members of a group of
285     * unique names are treated as individual object names, and not as the names
286     * of other groups of unique names.
287     */
288    public static class UserGroup extends NamedUserClass
289    {
290        /**
291         * Creates a new instance.
292         * 
293         * @param groupNames the set of group DNs.
294         */
295        public UserGroup( Set<Dn> groupNames )
296        {
297            super( groupNames );
298        }
299
300
301        /**
302         * {@inheritDoc}
303         */
304        @Override
305        public String toString()
306        {
307            return "userGroup " + super.toString();
308        }
309    }
310    
311
312    /**
313     * The set of users whose distinguished names fall within the definition of
314     * the (unrefined) subtree.
315     */
316    public static class Subtree extends UserClass
317    {
318        /** The subtree specifications. */
319        protected final Set<SubtreeSpecification> subtreeSpecifications;
320
321
322        /**
323         * Creates a new instance.
324         * 
325         * @param subtreeSpecs the collection of unrefined {@link SubtreeSpecification}s.
326         */
327        public Subtree( Set<SubtreeSpecification> subtreeSpecs )
328        {
329            subtreeSpecifications = Collections.unmodifiableSet( subtreeSpecs );
330        }
331
332
333        /**
334         * Returns the collection of unrefined {@link SubtreeSpecification}s.
335         *
336         * @return the subtree specifications
337         */
338        public Set<SubtreeSpecification> getSubtreeSpecifications()
339        {
340            return subtreeSpecifications;
341        }
342
343
344        /**
345         * {@inheritDoc}
346         */
347        @Override
348        public int hashCode()
349        {
350            int hash = 37;
351            hash = hash * 17 + subtreeSpecifications.hashCode();
352
353            return hash;
354        }
355
356
357        /**
358         * {@inheritDoc}
359         */
360        @Override
361        public boolean equals( Object o )
362        {
363            if ( this == o )
364            {
365                return true;
366            }
367
368            if ( o instanceof Subtree )
369            {
370                Subtree that = ( Subtree ) o;
371                
372                return subtreeSpecifications.equals( that.subtreeSpecifications );
373            }
374
375            return false;
376        }
377
378
379        /**
380         * {@inheritDoc}
381         */
382        @Override
383        public String toString()
384        {
385            StringBuilder buffer = new StringBuilder();
386
387            boolean isFirst = true;
388            buffer.append( "subtree { " );
389
390            for ( SubtreeSpecification ss : subtreeSpecifications )
391            {
392                if ( isFirst )
393                {
394                    isFirst = false;
395                }
396                else
397                {
398                    buffer.append( ", " );
399                }
400
401                ss.toString( buffer );
402            }
403
404            buffer.append( " }" );
405
406            return buffer.toString();
407        }
408    }
409}