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     */
020    package org.apache.directory.shared.ldap.message.control;
021    
022    
023    import org.apache.directory.shared.asn1.codec.EncoderException;
024    import org.apache.directory.shared.ldap.codec.search.controls.ChangeType;
025    import org.apache.directory.shared.ldap.codec.search.controls.entryChange.EntryChangeControlCodec;
026    import org.apache.directory.shared.ldap.name.LdapDN;
027    import org.slf4j.Logger;
028    import org.slf4j.LoggerFactory;
029    
030    
031    /**
032     * A response control that may be returned by Persistent Search entry responses.
033     * It contains addition change information to descrive the exact change that
034     * occured to an entry. The exact details of this control are covered in section
035     * 5 of this (yes) expired draft: <a
036     * href="http://www3.ietf.org/proceedings/01aug/I-D/draft-ietf-ldapext-psearch-03.txt">
037     * Persistent Search Draft v03</a> which is printed out below for convenience:
038     * 
039     * <pre>
040     *    5.  Entry Change Notification Control
041     *    
042     *    This control provides additional information about the change the caused
043     *    a particular entry to be returned as the result of a persistent search.
044     *    The controlType is &quot;2.16.840.1.113730.3.4.7&quot;.  If the client set the
045     *    returnECs boolean to TRUE in the PersistentSearch control, servers MUST
046     *    include an EntryChangeNotification control in the Controls portion of
047     *    each SearchResultEntry that is returned due to an entry being added,
048     *    deleted, or modified.
049     *    
050     *               EntryChangeNotification ::= SEQUENCE 
051     *               {
052     *                         changeType ENUMERATED 
053     *                         {
054     *                                 add             (1),
055     *                                 delete          (2),
056     *                                 modify          (4),
057     *                                 modDN           (8)
058     *                         },
059     *                         previousDN   LDAPDN OPTIONAL,     -- modifyDN ops. only
060     *                         changeNumber INTEGER OPTIONAL     -- if supported
061     *               }
062     *    
063     *    changeType indicates what LDAP operation caused the entry to be returned.
064     *    
065     *    previousDN is present only for modifyDN operations and gives the DN of
066     *    the entry before it was renamed and/or moved.  Servers MUST include this
067     *    optional field only when returning change notifications as a result of
068     *    modifyDN operations.
069     * 
070     *    changeNumber is the change number [CHANGELOG] assigned by a server for
071     *    the change.  If a server supports an LDAP Change Log it SHOULD include
072     *    this field.
073     * </pre>
074     * 
075     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
076     * @version $Rev: 764131 $
077     */
078    public class EntryChangeControl extends InternalAbstractControl
079    {
080        private static final long serialVersionUID = -2356861450876343999L;
081    
082        private static final Logger log = LoggerFactory.getLogger( EntryChangeControl.class );
083    
084        public static final String CONTROL_OID = "2.16.840.1.113730.3.4.7";
085    
086        public static final long UNDEFINED_CHANGE_NUMBER = EntryChangeControlCodec.UNDEFINED_CHANGE_NUMBER;
087    
088        private ChangeType changeType = ChangeType.ADD;
089    
090        private long changeNumber = UNDEFINED_CHANGE_NUMBER;
091    
092        private LdapDN previousDn = null;
093    
094    
095        public EntryChangeControl()
096        {
097            super();
098            setID( CONTROL_OID );
099        }
100    
101    
102        public ChangeType getChangeType()
103        {
104            return changeType;
105        }
106    
107    
108        public void setChangeType( ChangeType changeType )
109        {
110            this.changeType = changeType;
111        }
112    
113    
114        public LdapDN getPreviousDn()
115        {
116            return previousDn;
117        }
118    
119    
120        public void setPreviousDn( LdapDN previousDn )
121        {
122            this.previousDn = previousDn;
123        }
124    
125    
126        public long getChangeNumber()
127        {
128            return changeNumber;
129        }
130    
131    
132        public void setChangeNumber( long changeNumber )
133        {
134            this.changeNumber = changeNumber;
135        }
136    
137    
138        public byte[] getEncodedValue() 
139        {
140            // should call this codec or something
141            EntryChangeControlCodec ecc = new EntryChangeControlCodec();
142            ecc.setChangeNumber( changeNumber );
143            ecc.setChangeType( changeType );
144            ecc.setPreviousDn( previousDn );
145    
146            try
147            {
148                return ecc.encode( null ).array();
149            }
150            catch ( EncoderException e )
151            {
152                log.error( "Failed to encode psearch control", e );
153                throw new IllegalStateException( "Failed to encode control with encoder.", e );
154            }
155        }
156    }