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.server.core.api.event;
021
022
023import java.util.ArrayList;
024
025
026/**
027 * The different kinds of events a {@link DirectoryListener} may register for 
028 * notification on using the {@link EventService}.  Sometimes an entry is 
029 * moved and renamed at the same time.  These notifications are sent when 
030 * either RENAME or MOVE notifications are enabled.
031 *
032 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
033 */
034public enum EventType
035{
036    ADD(1), 
037    DELETE(2), 
038    MODIFY(4), 
039    RENAME(8), 
040    MOVE(16),
041    MOVE_AND_RENAME(24); // MOVE | RENAME
042    
043    public static final int ALL_EVENT_TYPES_MASK = ADD.mask | DELETE.mask | MODIFY.mask | RENAME.mask | MOVE.mask;
044    public static final int MOVE_AND_RENAME_MASK = MOVE.mask | RENAME.mask;
045    private static final EventType[] EMPTY_EVENT_ARRAY = new EventType[0];
046
047    // The internal value
048    private int mask;
049
050
051    EventType( int mask )
052    {
053        this.mask = mask;
054    }
055
056
057    public int getMask()
058    {
059        return mask;
060    }
061
062
063    /**
064     * Gets an array of EventTypes from the PSearchControl changeTypes 
065     * parameter value.  According to the documentation of the changeTypes 
066     * field of the Persistent Search Control:
067     * 
068     * <code>
069     * The changeTypes field is the logical OR of one or more of these values:
070     * add (1), delete (2), modify (4), modDN (8). By default this is set to 1 |
071     * 2 | 4 | 8 which is the integer value 0x0F or 15.
072     * </code>
073     * 
074     * NOTE: When the changeTypes mask includes a modDN(8) we include both the 
075     * RENAME and MOVE EventType objects in the array.
076     * 
077     * @param psearchChangeTypes the value of the changeTypes parameter
078     * @return array of EventType objects
079     */
080    public static EventType[] getEventTypes( int psearchChangeTypes )
081    {
082        ArrayList<EventType> types = new ArrayList<>();
083
084        if ( isAdd( psearchChangeTypes ) )
085        {
086            types.add( ADD );
087        }
088
089        if ( isDelete( psearchChangeTypes ) )
090        {
091            types.add( DELETE );
092        }
093
094        if ( isModify( psearchChangeTypes ) )
095        {
096            types.add( MODIFY );
097        }
098
099        if ( ( psearchChangeTypes & 8 ) > 0 )
100        {
101            types.add( MOVE );
102            types.add( RENAME );
103        }
104
105        return types.toArray( EMPTY_EVENT_ARRAY );
106    }
107
108
109    /**
110     * Tells if the EventType is an ADD
111     * 
112     * @param mask The EventType to check
113     * @return <tt>true</tt> if the EventType is a ADD
114     */
115    public static boolean isAdd( int mask )
116    {
117        return ( ( mask & ADD.mask ) != 0 );
118    }
119
120
121    /**
122     * Tells if the EventType is a DELETE
123     * 
124     * @param mask The EventType to check
125     * @return <tt>true</tt> if the EventType is a DELETE
126     */
127    public static boolean isDelete( int mask )
128    {
129        return ( ( mask & DELETE.mask ) != 0 );
130    }
131
132
133    /**
134     * Tells if the EventType is a MODIFY
135     * 
136     * @param mask The EventType to check
137     * @return <tt>true</tt> if the EventType is a MODIFY
138     */
139    public static boolean isModify( int mask )
140    {
141        return ( ( mask & MODIFY.mask ) != 0 );
142    }
143
144
145    /**
146     * Tells if the EventType is a MOVE
147     * 
148     * @param mask The EventType to check
149     * @return <tt>true</tt> if the EventType is a MOVE
150     */
151    public static boolean isMove( int mask )
152    {
153        return ( ( mask & MOVE.mask ) != 0 );
154    }
155
156
157    /**
158     * Tells if the EventType is a RENAME
159     * 
160     * @param mask The EventType to check
161     * @return <tt>true</tt> if the EventType is a RENAME
162     */
163    public static boolean isRename( int mask )
164    {
165        return ( ( mask & RENAME.mask ) != 0 );
166    }
167
168
169    /**
170     * Tells if the EventType is a MOVE and RENAME
171     * 
172     * @param mask The EventType to check
173     * @return <tt>true</tt> if the EventType is a MOVE_AND_RENAME
174     */
175    public static boolean isMoveAndRename( int mask )
176    {
177        return ( ( mask & MOVE_AND_RENAME_MASK ) != 0 );
178    }
179
180
181    /**
182     * Compute the mask associated with the given eventTypes
183     * 
184     * @param eventTypes The eventTypes 
185     * @return The associated mask
186     */
187    public static int getMask( EventType... eventTypes )
188    {
189        int mask = 0;
190
191        for ( EventType type : eventTypes )
192        {
193            mask |= type.getMask();
194        }
195
196        return mask;
197    }
198
199
200    /**
201     * checks if the given mask value matches with any of the defined
202     * standard EventTypes 
203     *
204     * @param mask the mask value of the EventType
205     * @return EventType matching the mask value of the standard event types defined, else throws IllegalArgumentException 
206     */
207    public static EventType getType( int mask )
208    {
209        switch ( mask )
210        {
211            case 1:
212                return ADD;
213
214            case 2:
215                return DELETE;
216
217            case 4:
218                return MODIFY;
219
220            case 8:
221                return RENAME;
222
223            case 16:
224                return MOVE;
225
226            default:
227                throw new IllegalArgumentException( "unknown mask value " + mask );
228        }
229    }
230
231
232    /**
233     * Print the flags
234     * 
235     * @param mask the flags value to print
236     * @return A textual version of the mask
237     */
238    public static String toString( int mask )
239    {
240        switch ( mask )
241        {
242            case 0:
243                return "no event";
244
245            case 1:
246                return "ADD";
247
248            case 2:
249                return "DELETE";
250
251            case 4:
252                return "MODIFY";
253
254            case 8:
255                return "RENAME";
256
257            case 16:
258                return "MOVE";
259
260            case 24:
261                return "MOVE_AND_RENAME";
262
263            case 31:
264                return "ALL EVENTS";
265
266            default:
267                return "Unknown";
268        }
269    }
270}