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 021package org.apache.directory.ldap.client.api; 022 023 024import org.apache.directory.shared.i18n.I18n; 025import org.apache.directory.shared.ldap.model.cursor.AbstractCursor; 026import org.apache.directory.shared.ldap.model.cursor.EntryCursor; 027import org.apache.directory.shared.ldap.model.cursor.InvalidCursorPositionException; 028import org.apache.directory.shared.ldap.model.cursor.SearchCursor; 029import org.apache.directory.shared.ldap.model.entry.Entry; 030import org.apache.directory.shared.ldap.model.exception.LdapException; 031import org.apache.directory.shared.ldap.model.message.Response; 032import org.apache.directory.shared.ldap.model.message.SearchResultDone; 033import org.apache.directory.shared.ldap.model.message.SearchResultEntry; 034 035 036/** 037 * An implementation of Cursor based on the underlying SearchFuture instance. 038 * 039 * Note: This is a forward only cursor hence the only valid operations are next(), get() and close() 040 * 041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 042 */ 043public class EntryCursorImpl extends AbstractCursor<Entry> implements EntryCursor 044{ 045 /** a reference to hold the retrieved SearchResponse object from SearchFuture */ 046 private Response response; 047 048 /** The encapsulated search cursor */ 049 private SearchCursor searchCursor; 050 051 /** The underlying messageId */ 052 private int messageId; 053 054 /** 055 * Instantiates a new search cursor, embedding a SearchCursor. 056 * 057 * @param searchCursor the embedded SearchResponse cursor 058 */ 059 public EntryCursorImpl( SearchCursor searchCursor ) 060 { 061 this.searchCursor = searchCursor; 062 messageId = -1; 063 } 064 065 066 /** 067 * {@inheritDoc} 068 */ 069 public boolean next() throws Exception 070 { 071 if ( !searchCursor.next() ) 072 { 073 return false; 074 } 075 076 try 077 { 078 079 do 080 { 081 response = searchCursor.get(); 082 083 if ( response == null ) 084 { 085 throw new LdapException( LdapNetworkConnection.TIME_OUT_ERROR ); 086 } 087 088 messageId = response.getMessageId(); 089 090 if ( response instanceof SearchResultEntry ) 091 { 092 return true; 093 } 094 } 095 while ( !( response instanceof SearchResultDone ) ); 096 097 return false; 098 } 099 catch ( Exception e ) 100 { 101 LdapException ldapException = new LdapException( LdapNetworkConnection.NO_RESPONSE_ERROR ); 102 ldapException.initCause( e ); 103 104 // close the cursor 105 close( ldapException ); 106 107 throw ldapException; 108 } 109 } 110 111 112 /** 113 * {@inheritDoc} 114 */ 115 public Entry get() throws Exception 116 { 117 if ( !searchCursor.available() ) 118 { 119 throw new InvalidCursorPositionException(); 120 } 121 122 do 123 { 124 if ( response instanceof SearchResultEntry ) 125 { 126 return ((SearchResultEntry)response).getEntry(); 127 } 128 } 129 while ( next() && !( response instanceof SearchResultDone ) ); 130 131 return null; 132 } 133 134 135 /** 136 * {@inheritDoc} 137 */ 138 public SearchResultDone getSearchResultDone() 139 { 140 return searchCursor.getSearchResultDone(); 141 } 142 143 144 /** 145 * {@inheritDoc} 146 */ 147 public boolean available() 148 { 149 return searchCursor.available(); 150 } 151 152 153 /** 154 * {@inheritDoc} 155 */ 156 @Override 157 public void close() throws Exception 158 { 159 searchCursor.close(); 160 } 161 162 163 /** 164 * {@inheritDoc} 165 */ 166 @Override 167 public void close( Exception cause ) throws Exception 168 { 169 searchCursor.close( cause ); 170 } 171 172 173 // rest of all operations will throw UnsupportedOperationException 174 175 /** 176 * This operation is not supported in SearchCursor. 177 * {@inheritDoc} 178 */ 179 public void after( Entry element ) throws Exception 180 { 181 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName() 182 .concat( "." ).concat( "after( Response element )" ) ) ); 183 } 184 185 186 /** 187 * This operation is not supported in SearchCursor. 188 * {@inheritDoc} 189 */ 190 public void afterLast() throws Exception 191 { 192 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName() 193 .concat( "." ).concat( "afterLast()" ) ) ); 194 } 195 196 197 /** 198 * This operation is not supported in SearchCursor. 199 * {@inheritDoc} 200 */ 201 public void before( Entry element ) throws Exception 202 { 203 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName() 204 .concat( "." ).concat( "before( Response element )" ) ) ); 205 } 206 207 208 /** 209 * This operation is not supported in SearchCursor. 210 * {@inheritDoc} 211 */ 212 public void beforeFirst() throws Exception 213 { 214 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName() 215 .concat( "." ).concat( "beforeFirst()" ) ) ); 216 } 217 218 219 /** 220 * This operation is not supported in SearchCursor. 221 * {@inheritDoc} 222 */ 223 public boolean first() throws Exception 224 { 225 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName() 226 .concat( "." ).concat( "first()" ) ) ); 227 } 228 229 230 /** 231 * This operation is not supported in SearchCursor. 232 * {@inheritDoc} 233 */ 234 public boolean last() throws Exception 235 { 236 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName() 237 .concat( "." ).concat( "last()" ) ) ); 238 } 239 240 241 /** 242 * This operation is not supported in SearchCursor. 243 * {@inheritDoc} 244 */ 245 public boolean previous() throws Exception 246 { 247 throw new UnsupportedOperationException( I18n.err( I18n.ERR_02014_UNSUPPORTED_OPERATION, getClass().getName() 248 .concat( "." ).concat( "previous()" ) ) ); 249 } 250 251 252 /** 253 * {@inheritDoc} 254 */ 255 public int getMessageId() 256 { 257 return messageId; 258 } 259}