001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.jndi.provider.ldap.mock;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.io.OutputStream;
023: import java.net.ServerSocket;
024: import java.net.Socket;
025: import java.util.LinkedList;
026:
027: import org.apache.harmony.jndi.provider.ldap.LdapMessage;
028: import org.apache.harmony.security.asn1.ASN1Integer;
029:
030: /**
031: * This class is a mock ldap server which only support one connection.
032: *
033: * NOTE: before client send request to the mock server, must set expected
034: * response message sequence using <code>etResponseSeq(LdapMessage[])</code>
035: * method, so the server will send response messages in order of parameter
036: * <code>LdapMessage[]</code>.
037: */
038: public class MockLdapServer implements Runnable {
039:
040: private ServerSocket server;
041:
042: private Socket socket;
043:
044: private LinkedList<LdapMessage> responses = new LinkedList<LdapMessage>();
045:
046: private int port;
047:
048: private Object lock = new Object();
049:
050: private boolean isStopped;
051:
052: private static int DEFAULT_PORT = 1024;
053:
054: public void start() {
055: port = DEFAULT_PORT;
056: while (true) {
057: try {
058: server = new ServerSocket(port);
059: break;
060: } catch (IOException e) {
061: ++port;
062: }
063: }
064:
065: isStopped = false;
066: new Thread(this ).start();
067: }
068:
069: public void stop() {
070: isStopped = true;
071:
072: synchronized (lock) {
073: lock.notify();
074: }
075:
076: if (server != null) {
077: try {
078: server.close();
079: } catch (IOException e) {
080: // ignore
081: }
082: }
083:
084: if (socket != null) {
085: try {
086: socket.close();
087: } catch (IOException e) {
088: // ignore
089: }
090: }
091: }
092:
093: public int getPort() {
094: return port;
095: }
096:
097: public void setResponseSeq(LdapMessage[] msges) {
098: synchronized (responses) {
099: for (LdapMessage message : msges) {
100: responses.addLast(message);
101: }
102: }
103:
104: synchronized (lock) {
105: lock.notify();
106: }
107: }
108:
109: public void run() {
110: InputStream in = null;
111: OutputStream out = null;
112: try {
113: socket = server.accept();
114: in = socket.getInputStream();
115: out = socket.getOutputStream();
116: while (!isStopped) {
117: if (responses.size() == 0) {
118: try {
119: synchronized (lock) {
120: lock.wait();
121: }
122: } catch (InterruptedException e) {
123: // ignore
124: }
125: } else {
126:
127: while (true) {
128: LdapMessage temp = null;
129: synchronized (responses) {
130: if (responses.size() == 0) {
131: break;
132: }
133: temp = responses.removeFirst();
134: }
135:
136: final MockLdapMessage response = new MockLdapMessage(
137: temp);
138: LdapMessage request = new LdapMessage(null) {
139: public void decodeValues(Object[] values) {
140: response.setMessageId(ASN1Integer
141: .toIntValue(values[0]));
142: }
143: };
144: request.decode(in);
145: try {
146: Thread.sleep(10);
147: } catch (InterruptedException e) {
148: //ignore
149: }
150: out.write(response.encode());
151: }
152: }
153: }
154: } catch (IOException e) {
155: // FIXME deal with the exception
156: } finally {
157: try {
158: if (socket != null) {
159: socket.close();
160: }
161:
162: if (in != null) {
163: in.close();
164: }
165:
166: if (out != null) {
167: out.close();
168: }
169: } catch (IOException e) {
170: // ignore
171: }
172: }
173: }
174:
175: public String getURL() {
176: return "ldap://localhost:" + port;
177: }
178: }
|