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     * Every directory user (with possible requirements for
066     * authenticationLevel).
067     */
068    public static final class AllUsers extends UserClass
069    {
070        private AllUsers()
071        {
072        }
073
074
075        /**
076         * {@inheritDoc}
077         */
078        @Override
079        public String toString()
080        {
081            return "allUsers";
082        }
083    }
084
085    /**
086     * The user with the same distinguished name as the entry being accessed, or
087     * if the entry is a member of a family, then additionally the user with the
088     * distinguished name of the ancestor.
089     */
090    public static final class ThisEntry extends UserClass
091    {
092        private ThisEntry()
093        {
094        }
095
096
097        /**
098         * {@inheritDoc}
099         */
100        @Override
101        public String toString()
102        {
103            return "thisEntry";
104        }
105    }
106
107    /**
108     * The user as parent (ancestor) of accessed entry.
109     */
110    public static final class ParentOfEntry extends UserClass
111    {
112        private ParentOfEntry()
113        {
114        }
115
116
117        /**
118         * {@inheritDoc}
119         */
120        @Override
121        public String toString()
122        {
123            return "parentOfEntry";
124        }
125
126    }
127
128    /**
129     * A base class for all user classes which has a set of DNs.
130     */
131    private abstract static class NamedUserClass extends UserClass
132    {
133        /** The names. */
134        protected final Set<Dn> names;
135
136
137        /**
138         * Creates a new instance.
139         * 
140         * @param names a set of names
141         */
142        protected NamedUserClass( Set<Dn> names )
143        {
144            if ( names == null )
145            {
146                this.names = Collections.unmodifiableSet( new HashSet<Dn>() );
147            }
148            else
149            {
150                this.names = Collections.unmodifiableSet( new HashSet<Dn>( names ) );
151            }
152        }
153
154
155        /**
156         * Returns the set of all names.
157         */
158        public Set<Dn> getNames()
159        {
160            return names;
161        }
162
163
164        /**
165         * {@inheritDoc}
166         */
167        @Override
168        public boolean equals( Object o )
169        {
170            if ( this == o )
171            {
172                return true;
173            }
174
175            if ( o == null )
176            {
177                return false;
178            }
179
180            if ( getClass().isAssignableFrom( o.getClass() ) )
181            {
182                Name that = ( Name ) o;
183                return this.names.equals( that.names );
184            }
185
186            return false;
187        }
188
189
190        /**
191         * {@inheritDoc}
192         */
193        @Override
194        public int hashCode()
195        {
196            int result = 37;
197
198            for ( Dn dn : this.names )
199            {
200                result = result * 17 + dn.hashCode();
201            }
202
203            return result;
204        }
205
206
207        public String toString()
208        {
209            StringBuilder buffer = new StringBuilder();
210
211            boolean isFirst = true;
212            buffer.append( "{ " );
213
214            for ( Dn name : names )
215            {
216                if ( isFirst )
217                {
218                    isFirst = false;
219                }
220                else
221                {
222                    buffer.append( ", " );
223                }
224
225                buffer.append( '"' );
226                buffer.append( name.toString() );
227                buffer.append( '"' );
228            }
229
230            buffer.append( " }" );
231
232            return buffer.toString();
233        }
234    }
235
236    /**
237     * The user with the specified distinguished name.
238     */
239    public static class Name extends NamedUserClass
240    {
241        /**
242         * Creates a new instance.
243         * 
244         * @param usernames
245         *            the set of user DNs.
246         */
247        public Name( Set<Dn> usernames )
248        {
249            super( usernames );
250        }
251
252
253        /**
254         * {@inheritDoc}
255         */
256        @Override
257        public String toString()
258        {
259            return "name " + super.toString();
260        }
261    }
262
263    /**
264     * The set of users who are members of the groupOfUniqueNames entry,
265     * identified by the specified distinguished name. Members of a group of
266     * unique names are treated as individual object names, and not as the names
267     * of other groups of unique names.
268     */
269    public static class UserGroup extends NamedUserClass
270    {
271        /**
272         * Creates a new instance.
273         * 
274         * @param groupNames
275         *            the set of group DNs.
276         */
277        public UserGroup( Set<Dn> groupNames )
278        {
279            super( groupNames );
280        }
281
282
283        /**
284         * {@inheritDoc}
285         */
286        @Override
287        public String toString()
288        {
289            return "userGroup " + super.toString();
290        }
291    }
292
293    /**
294     * The set of users whose distinguished names fall within the definition of
295     * the (unrefined) subtree.
296     */
297    public static class Subtree extends UserClass
298    {
299        /** The subtree specifications. */
300        protected final Set<SubtreeSpecification> subtreeSpecifications;
301
302
303        /**
304         * Creates a new instance.
305         * 
306         * @param subtreeSpecs
307         *            the collection of unrefined {@link SubtreeSpecification}s.
308         */
309        public Subtree( Set<SubtreeSpecification> subtreeSpecs )
310        {
311            this.subtreeSpecifications = Collections.unmodifiableSet( subtreeSpecs );
312        }
313
314
315        /**
316         * Returns the collection of unrefined {@link SubtreeSpecification}s.
317         *
318         * @return the subtree specifications
319         */
320        public Set<SubtreeSpecification> getSubtreeSpecifications()
321        {
322            return subtreeSpecifications;
323        }
324
325
326        /**
327         * {@inheritDoc}
328         */
329        @Override
330        public int hashCode()
331        {
332            int hash = 37;
333            hash = hash * 17 + subtreeSpecifications.hashCode();
334
335            return hash;
336        }
337
338
339        /**
340         * {@inheritDoc}
341         */
342        @Override
343        public boolean equals( Object o )
344        {
345            if ( this == o )
346            {
347                return true;
348            }
349
350            if ( o instanceof Subtree )
351            {
352                Subtree that = ( Subtree ) o;
353                return this.subtreeSpecifications.equals( that.subtreeSpecifications );
354            }
355
356            return false;
357        }
358
359
360        /**
361         * {@inheritDoc}
362         */
363        @Override
364        public String toString()
365        {
366            StringBuilder buffer = new StringBuilder();
367
368            boolean isFirst = true;
369            buffer.append( "subtree { " );
370
371            for ( SubtreeSpecification ss : subtreeSpecifications )
372            {
373                if ( isFirst )
374                {
375                    isFirst = false;
376                }
377                else
378                {
379                    buffer.append( ", " );
380                }
381
382                ss.toString( buffer );
383            }
384
385            buffer.append( " }" );
386
387            return buffer.toString();
388        }
389    }
390}