package cn.edu.zju.acm.onlinejudge.judgeservice; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import cn.edu.zju.acm.onlinejudge.bean.enumeration.JudgeReply; public class MockClient { public static final String[] NO_SUCH_PROBLEM = new String[] { "" + "" }; public static final String[] SAVE_INTERNAL_ERROR = new String[] { "" + JudgeReply.JUDGE_INTERNAL_ERROR.getId() }; public static final String[] SAVE_SERVER_ERROR = new String[] { "" + "", "" + "" }; public static final String[] SAVE_SUCCESS = new String[] { "" + "", "" + "" }; public static final String[] JUDGE_INTERNAL_ERROR = new String[] { "" + "", "" + JudgeReply.JUDGE_INTERNAL_ERROR.getId() }; public static final String[] COMPILATION_SERVER_ERROR = SAVE_SERVER_ERROR; public static final String[] COMPILATION_ERROR = new String[] { "" + "", "" + JudgeReply.COMPILATION_ERROR.getId(), "compilation error" }; public static final String[] RUNNING_SERVER_ERROR = new String[] { "" + "", "" + JudgeReply.RUNNING.getId(), "0 0", "-1 -1", "" + "" }; public static final String[] RUNTIME_ERROR = new String[] { "" + "", "" + JudgeReply.RUNNING.getId(), "1.1 2", "-1 -1", "" + JudgeReply.RUNTIME_ERROR.getId() }; public static final String[] JUDGE_SERVER_ERROR = new String[] { "" + "", "" + JudgeReply.RUNNING, "1.1 2", "-1 -1", "" + JudgeReply.JUDGING.getId(), "" + "" }; public static final String[] ACCEPTED = new String[] { "" + "", "" + JudgeReply.RUNNING.getId(), "1.1 2", "-1 -1", "" + JudgeReply.JUDGING.getId(), "" + JudgeReply.ACCEPTED.getId() }; private ServerSocket serverSocket; private List<String[]> replies = Collections.synchronizedList(new LinkedList<String[]>()); private byte[] file; private String[] command; private Thread thread; private Set<Socket> sockets = new HashSet<Socket>(); public MockClient() throws Exception { this(false); } public MockClient(final boolean concurrent) throws Exception { serverSocket = new ServerSocket(0); thread = new Thread() { public synchronized void run() { while (!isInterrupted()) { final Socket socket; try { socket = serverSocket.accept(); } catch (IOException e) { break; } if (concurrent) { new Thread() { public void run() { process(socket); } }.start(); } else { process(socket); } } } private void process(Socket socket) { synchronized (sockets) { sockets.add(socket); } try { InputStream in = socket.getInputStream(); PrintWriter out = new PrintWriter(socket.getOutputStream()); String s = ""; for (int i = 0; i < 64; i++) { int next = in.read(); s += (char) next; } command = s.trim().split(" "); String[] reply = null; if (replies != null && replies.size() > 0) { reply = replies.remove(0); } if (reply == null) { reply = new String[0]; } if (reply.length > 0) { out.println(reply[0]); out.flush(); } ArrayList<Byte> bytes = new ArrayList<Byte>(); for (;;) { int next = in.read(); if (next < 0) { break; } bytes.add((byte) next); } file = new byte[bytes.size()]; for (int i = 0; i < bytes.size(); i++) { file[i] = bytes.get(i); } for (int i = 1; i < reply.length; i++) { out.println(reply[i]); } out.flush(); } catch (Throwable e) { } finally { synchronized (sockets) { sockets.remove(socket); } try { socket.close(); } catch (IOException e) { } } } }; thread.start(); } public int getPort() { return serverSocket.getLocalPort(); } public void stop() throws IOException { thread.interrupt(); serverSocket.close(); synchronized (sockets) { for (Socket socket : sockets) { if (socket != null && !socket.isClosed()) { try { socket.close(); } catch (IOException e) { } } } } } public void addReply(String[] replies) { this.replies.add(replies); } public List<String[]> getReplies() { return this.replies; } public byte[] getFile() { return file; } public String[] getCommand() { return command; } }