1 19 20 package org.apache.james.experimental.imapserver; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.OutputStream ; 25 import java.nio.ByteBuffer ; 26 import java.nio.CharBuffer ; 27 import java.nio.charset.Charset ; 28 import java.nio.charset.CharsetEncoder ; 29 import java.util.ArrayList ; 30 import java.util.Collection ; 31 import java.util.HashSet ; 32 import java.util.Iterator ; 33 import java.util.Set ; 34 35 import org.apache.james.api.imap.process.ImapProcessor; 36 import org.apache.james.imapserver.codec.decode.ImapDecoder; 37 import org.apache.james.imapserver.codec.encode.ImapEncoder; 38 import org.apache.james.services.User; 39 import org.apache.james.services.UsersRepository; 40 import org.apache.james.test.functional.imap.HostSystem; 41 import org.apache.james.test.functional.imap.HostSystem.Continuation; 42 import org.apache.james.test.mock.avalon.MockLogger; 43 44 public class ExperimentalHostSystem implements HostSystem, UsersRepository { 45 46 private ImapDecoder decoder; 47 private ImapEncoder encoder; 48 private ImapProcessor processor; 49 private Resetable dataReset; 50 private boolean isReadLast = true; 51 private final Set users; 52 53 public ExperimentalHostSystem() { 54 super(); 55 users = new HashSet (); 56 } 57 58 public void configure(final ImapDecoder decoder, final ImapEncoder encoder, 59 final ImapProcessor processor, final Resetable dataReset) { 60 this.decoder = decoder; 61 this.encoder = encoder; 62 this.processor = processor; 63 this.dataReset = dataReset; 64 } 65 66 public boolean addUser(String username, String password) { 67 User user = new MockUser(username, password); 68 users.add(user); 69 return true; 70 71 } 72 73 public HostSystem.Session newSession(Continuation continuation) throws Exception { 74 return new Session(continuation); 75 } 76 77 public void reset() throws Exception { 78 users.clear(); 79 dataReset.reset(); 80 } 81 82 public String getHelloName() { 83 return "JAMES"; 84 } 85 86 public ImapDecoder getImapDecoder() { 87 return decoder; 88 } 89 90 public ImapEncoder getImapEncoder() { 91 return encoder; 92 } 93 94 public ImapProcessor getImapProcessor() { 95 return processor; 96 } 97 98 public int getResetLength() { 99 return Integer.MAX_VALUE; 100 } 101 102 public boolean addUser(User user) { 103 users.add(user); 104 return true; 105 } 106 107 public void addUser(String name, Object attributes) { 108 User user = new MockUser(name, "SHA"); 109 users.add(user); 110 } 111 112 public boolean contains(String name) { 113 boolean result = false; 114 if (name != null) 115 { 116 for (Iterator it=users.iterator();it.hasNext();) 117 { 118 User user = (User) it.next(); 119 if (name.equals(user.getUserName())){ 120 result = true; 121 break; 122 } 123 } 124 } 125 return result; 126 } 127 128 public boolean containsCaseInsensitive(String name) { 129 boolean result = false; 130 if (name != null) 131 { 132 for (Iterator it=users.iterator();it.hasNext();) 133 { 134 User user = (User) it.next(); 135 if (name.equalsIgnoreCase(user.getUserName())){ 136 result = true; 137 break; 138 } 139 } 140 } 141 return result; 142 } 143 144 public int countUsers() { 145 return users.size(); 146 } 147 148 public String getRealName(String name) { 149 return name; 150 } 151 152 public User getUserByName(String name) { 153 User result = null; 154 if (name != null) 155 { 156 for (Iterator it=users.iterator();it.hasNext();) 157 { 158 User user = (User) it.next(); 159 if (name.equals(user.getUserName())){ 160 result = user; 161 break; 162 } 163 } 164 } 165 return result; 166 } 167 168 public User getUserByNameCaseInsensitive(String name) { 169 User result = null; 170 if (name != null) 171 { 172 for (Iterator it=users.iterator();it.hasNext();) 173 { 174 User user = (User) it.next(); 175 if (name.equalsIgnoreCase(user.getUserName())){ 176 result = user; 177 break; 178 } 179 } 180 } 181 return result; 182 } 183 184 public Iterator list() { 185 Collection results = new ArrayList (); 186 for (Iterator it=users.iterator();it.hasNext();) 187 { 188 User user = (User) it.next(); 189 results.add(user.getUserName()); 190 } 191 192 return results.iterator(); 193 } 194 195 public void removeUser(String name) { 196 if (name != null) 197 { 198 for (Iterator it=users.iterator();it.hasNext();) 199 { 200 User user = (User) it.next(); 201 if (name.equals(user.getUserName())){ 202 it.remove(); 203 break; 204 } 205 } 206 } 207 } 208 209 public boolean test(String name, String password) { 210 boolean result = false; 211 if (name != null) 212 { 213 for (Iterator it=users.iterator();it.hasNext();) 214 { 215 User user = (User) it.next(); 216 if (name.equals(user.getUserName())){ 217 result = user.verifyPassword(password); 218 break; 219 } 220 } 221 } 222 return result; 223 } 224 225 public boolean updateUser(User user) { 226 users.add(user); 227 return true; 228 } 229 230 class Session implements HostSystem.Session, ImapHandlerInterface 231 { 232 ByteBufferOutputStream out; 233 ByteBufferInputStream in; 234 ImapRequestHandler handler; 235 ImapSessionImpl session; 236 237 238 public Session(Continuation continuation) { 239 out = new ByteBufferOutputStream(continuation); 240 in = new ByteBufferInputStream(); 241 handler = new ImapRequestHandler(decoder, processor, encoder); 242 handler.enableLogging(new MockLogger()); 243 session = new ImapSessionImpl(this, "localhost", "127.0.0.1"); 244 } 245 246 public String readLine() throws Exception { 247 if (!isReadLast) { 248 handler.handleRequest(in, out, session); 249 isReadLast = true; 250 } 251 final String result = out.nextLine(); 252 return result; 253 } 254 255 public void start() throws Exception { 256 out.write("* OK IMAP4rev1 Server ready\r\n"); 258 } 259 260 public void stop() throws Exception { 261 262 } 263 264 public void writeLine(String line) throws Exception { 265 isReadLast = false; 266 in.nextLine(line); 267 } 268 269 public void forceConnectionClose(String byeMessage) { 270 try { 271 out.write(byeMessage); 272 } catch (IOException e) { 273 throw new RuntimeException (e); 274 } 275 } 276 } 277 278 static class ByteBufferInputStream extends InputStream { 279 280 ByteBuffer buffer = ByteBuffer.allocate(8192); 281 CharsetEncoder encoder = Charset.forName("ASCII").newEncoder(); 282 boolean readLast = true; 283 284 public int read() throws IOException { 285 if (!readLast) { 286 readLast = true; 287 buffer.flip(); 288 } 289 int result = -1; 290 if (buffer.hasRemaining()) { 291 result = buffer.get(); 292 } 293 return result; 294 } 295 296 public void nextLine(String line) { 297 if (buffer.position() > 0 && readLast) { 298 buffer.compact(); 299 } 300 encoder.encode(CharBuffer.wrap(line), buffer, true); 301 buffer.put((byte)'\r'); 302 buffer.put((byte)'\n'); 303 readLast = false; 304 } 305 } 306 307 static class ByteBufferOutputStream extends OutputStream { 308 ByteBuffer buffer = ByteBuffer.allocate(8192); 309 Charset ascii = Charset.forName("ASCII"); 310 Continuation continuation; 311 boolean matchPlus = false; 312 boolean matchCR = false; 313 boolean matchLF = false; 314 315 public ByteBufferOutputStream(Continuation continuation) { 316 this.continuation = continuation; 317 } 318 319 public void write(String message) throws IOException { 320 ascii.newEncoder().encode(CharBuffer.wrap(message), buffer, true); 321 } 322 323 public void write(int b) throws IOException { 324 buffer.put((byte) b); 325 if (b == '\n' && matchPlus && matchCR && matchLF) { 326 matchPlus = false; 327 matchCR = false; 328 matchLF = false; 329 continuation.doContinue(); 330 } else if (b == '\n') { 331 matchLF = true; 332 matchPlus = false; 333 matchCR = false; 334 } else if (b == '+' && matchLF) { 335 matchPlus = true; 336 matchCR = false; 337 } else if (b == '\r' && matchPlus && matchLF) { 338 matchCR = true; 339 } else { 340 matchPlus = false; 341 matchCR = false; 342 matchLF = false; 343 } 344 } 345 346 public String nextLine() throws Exception { 347 buffer.flip(); 348 byte last = 0; 349 while (buffer.hasRemaining()) { 350 byte next = buffer.get(); 351 if (last == '\r' && next == '\n') { 352 break; 353 } 354 last = next; 355 } 356 final ByteBuffer readOnlyBuffer = buffer.asReadOnlyBuffer(); 357 readOnlyBuffer.flip(); 358 int limit = readOnlyBuffer.limit() - 2; 359 if (limit < 0) { 360 limit = 0; 361 } 362 readOnlyBuffer.limit(limit); 363 String result = ascii.decode(readOnlyBuffer).toString(); 364 buffer.compact(); 365 return result; 366 } 367 } 368 369 static class MockUser implements User { 370 371 private final String user; 372 private String password; 373 374 375 376 public MockUser(final String user, final String password) { 377 super(); 378 this.user = user; 379 this.password = password; 380 } 381 382 public String getUserName() { 383 return user; 384 } 385 386 public boolean setPassword(String newPass) { 387 this.password = newPass; 388 return true; 389 } 390 391 public boolean verifyPassword(String pass) { 392 return password.equals(pass); 393 } 394 395 public int hashCode() { 396 final int PRIME = 31; 397 int result = 1; 398 result = PRIME * result + ((user == null) ? 0 : user.hashCode()); 399 return result; 400 } 401 402 public boolean equals(Object obj) { 403 if (this == obj) 404 return true; 405 if (obj == null) 406 return false; 407 if (getClass() != obj.getClass()) 408 return false; 409 final MockUser other = (MockUser) obj; 410 if (user == null) { 411 if (other.user != null) 412 return false; 413 } else if (!user.equals(other.user)) 414 return false; 415 return true; 416 } 417 } 418 419 public interface Resetable { 420 public void reset() throws Exception ; 421 } 422 } 423 | Popular Tags |