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.pSearch.PSearchControlCodec;
026 import org.slf4j.Logger;
027 import org.slf4j.LoggerFactory;
028
029
030 /**
031 * The control for a persistent search operation, as defined in
032 * http://www.ietf.org/proceedings/01mar/I-D/ldapext-psearch-03.txt.
033 *
034 * The data structure is defined by the following ASN.1 description :
035 *
036 * PersistentSearch ::= SEQUENCE {
037 * changeTypes INTEGER,
038 * changesOnly BOOLEAN,
039 * returnECs BOOLEAN
040 * }
041 *
042 * The associated OID is : "2.16.840.1.113730.3.4.3"
043 *
044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
045 * @version $Rev: 764131 $
046 */
047 public class PersistentSearchControl extends InternalAbstractControl
048 {
049 /** As this class is serializable, defined its serialVersionUID */
050 private static final long serialVersionUID = -2356861450876343999L;
051
052 /** The Logger for this class */
053 private static final Logger LOG = LoggerFactory.getLogger( PersistentSearchControl.class );
054
055 /** This control OID */
056 public static final String CONTROL_OID = "2.16.840.1.113730.3.4.3";
057
058 /** A combinaison of all the possible changes. Resolves to 0x0F */
059 public static final int ALL_CHANGES = 1 | 2 | 4 | 8;
060
061 /**
062 * If changesOnly is TRUE, the server MUST NOT return any existing entries
063 * that match the search criteria. Entries are only returned when they are
064 * changed (added, modified, deleted, or subject to a modifyDN operation).
065 * By default this is set to true.
066 */
067 private boolean changesOnly = true;
068
069 /**
070 * If returnECs is TRUE, the server MUST return an Entry Change Notification
071 * control with each entry returned as the result of changes. By default
072 * this is set to false.
073 */
074 private boolean returnECs = false;
075
076 /**
077 * As changes are made to the server, the effected entries MUST be returned
078 * to the client if they match the standard search criteria and if the
079 * operation that caused the change is included in the changeTypes field.
080 * The changeTypes field is the logical OR of one or more of these values:
081 * <ul>
082 * <li>add (1)</li>
083 * <li>delete (2)</li>
084 * <li>modify (4)</li>
085 * <li>modDN (8)</li>
086 * </ul>
087 * <br>
088 * By default this is set to 1 | 2 | 4 | 8 which is the int value 0x0F or 15.
089 */
090 private int changeTypes = ALL_CHANGES;
091
092
093 public PersistentSearchControl()
094 {
095 super();
096 setID( CONTROL_OID );
097 }
098
099
100 public void setChangesOnly( boolean changesOnly )
101 {
102 this.changesOnly = changesOnly;
103 }
104
105
106 public boolean isChangesOnly()
107 {
108 return changesOnly;
109 }
110
111
112 public void setReturnECs( boolean returnECs )
113 {
114 this.returnECs = returnECs;
115 }
116
117
118 public boolean isReturnECs()
119 {
120 return returnECs;
121 }
122
123
124 public void setChangeTypes( int changeTypes )
125 {
126 this.changeTypes = changeTypes;
127 }
128
129
130 public int getChangeTypes()
131 {
132 return changeTypes;
133 }
134
135
136 public boolean isNotificationEnabled( ChangeType changeType )
137 {
138 return ( changeType.getValue() & changeTypes ) > 0;
139 }
140
141
142 public void enableNotification( ChangeType changeType )
143 {
144 changeTypes |= changeType.getValue();
145 }
146
147
148 /**
149 * @return The encoded byte[] for this persistentSearch control
150 *
151 */
152 public byte[] getEncodedValue()
153 {
154 PSearchControlCodec psearchCtlCodec = new PSearchControlCodec();
155 psearchCtlCodec.setChangesOnly( changesOnly );
156 psearchCtlCodec.setChangeTypes( changeTypes );
157 psearchCtlCodec.setReturnECs( returnECs );
158
159 try
160 {
161 return psearchCtlCodec.encode( null ).array();
162 }
163 catch ( EncoderException e )
164 {
165 LOG.error( "Failed to encode psearch control", e );
166 throw new IllegalStateException( "Failed to encode control with encoder.", e );
167 }
168 }
169 }