AcrobatCommunicationServer.java

00001 package edu.stanford.hci.r3.tools.design.acrobat;
00002 
00003 import java.io.BufferedReader;
00004 import java.io.File;
00005 import java.io.FileNotFoundException;
00006 import java.io.FileOutputStream;
00007 import java.io.FileWriter;
00008 import java.io.IOException;
00009 import java.io.InputStreamReader;
00010 import java.io.PrintWriter;
00011 import java.net.ServerSocket;
00012 import java.net.Socket;
00013 import java.net.SocketException;
00014 import java.util.ArrayList;
00015 import java.util.List;
00016 
00017 import edu.stanford.hci.r3.PaperToolkit;
00018 import edu.stanford.hci.r3.config.Constants;
00019 import edu.stanford.hci.r3.util.DebugUtils;
00020 import edu.stanford.hci.r3.util.files.FileUtils;
00021 
00045 public class AcrobatCommunicationServer {
00046 
00050         private static final StringBuilder CONFIRMATION = FileUtils.readFileIntoStringBuffer(
00051                         PaperToolkit.getResourceFile("/designer/Confirmation.html"), false /* no new lines */);
00052 
00053         private static AcrobatCommunicationServer server;
00054 
00058         public static void main(String[] args) {
00059                 startServer();
00060         }
00061 
00065         protected static void startServer() {
00066                 if (server != null) {
00067                         DebugUtils.println("Acrobat Communication Server has already started...");
00068                         return;
00069                 }
00070                 try {
00071                         server = new AcrobatCommunicationServer(Constants.Ports.ACROBAT_SERVER, new FileOutputStream(new File(
00072                                         "AcrobatCommunicationServer.log")));
00073 
00074                 } catch (FileNotFoundException e) {
00075                         e.printStackTrace();
00076                 }
00077         }
00078 
00079         private boolean alreadyClosed = false;
00080 
00084         private List<Socket> clientConnections = new ArrayList<Socket>();
00085 
00089         private PrintWriter logOutput;
00090 
00091         private File outputFile;
00092 
00093         private int serverPort;
00094 
00098         private ServerSocket serverSocket;
00099 
00105         public AcrobatCommunicationServer(int port, FileOutputStream log) {
00106                 serverPort = port;
00107                 logOutput = new PrintWriter(log, true /* autoflush */);
00108                 getCommandRelayThread().start();
00109         }
00110 
00114         public void closeSockets() {
00115                 if (!alreadyClosed) {
00116                         alreadyClosed = true;
00117                         try {
00118                                 System.out.println("Cleaning up AcrobatCommServer on port "
00119                                                 + serverSocket.getLocalPort());
00120                                 serverSocket.close();
00121                                 for (Socket clientConnection : clientConnections) {
00122                                         if (clientConnection != null) {
00123                                                 clientConnection.close();
00124                                         }
00125                                 }
00126                         } catch (IOException e) {
00127                                 e.printStackTrace();
00128                         }
00129                 }
00130         }
00131 
00135         private Thread getCommandRelayThread() {
00136                 return new Thread(new Runnable() {
00137                         public void run() {
00138                                 try {
00139                                         serverSocket = new ServerSocket(serverPort);
00140                                 } catch (IOException e1) {
00141                                         e1.printStackTrace();
00142                                         logOutput.println("Could not connect to server port " + serverPort);
00143                                 }
00144 
00145                                 int clientIDs = 0;
00146 
00147                                 while (true) {
00148                                         if (alreadyClosed) {
00149                                                 break;
00150                                         }
00151 
00152                                         try {
00153                                                 final String connectMsg = "AcrobatCommServer::Waiting for a plain text connection on port "
00154                                                                 + serverSocket.getLocalPort();
00155 
00156                                                 logToConsoleAndFile(connectMsg);
00157 
00158                                                 final Socket clientConnection = serverSocket.accept();
00159                                                 clientConnections.add(clientConnection);
00160 
00161                                                 // we got a connection with the client
00162                                                 final String connectedMsg = "AcrobatCommServer::Got a connection on port "
00163                                                                 + serverSocket.getLocalPort();
00164                                                 final String newClientMsg = "AcrobatCommServer::New Client: "
00165                                                                 + clientConnection.getInetAddress();
00166 
00167                                                 logToConsoleAndFile(connectedMsg);
00168                                                 logToConsoleAndFile(newClientMsg);
00169 
00170                                                 getCommunicationsThread(clientConnection, clientIDs++).start();
00171 
00172                                         } catch (SocketException e) {
00173                                         } catch (IOException e) {
00174                                         }
00175                                 }
00176 
00177                         }
00178                 });
00179         }
00180 
00185         private Thread getCommunicationsThread(final Socket clientConn, final int id) {
00186                 return new Thread(new Runnable() {
00187                         public void run() {
00188                                 BufferedReader in = null;
00189                                 PrintWriter out = null;
00190                                 try {
00191                                         in = new BufferedReader(new InputStreamReader(clientConn.getInputStream()));
00192                                         out = new PrintWriter(clientConn.getOutputStream(), true);
00193                                 } catch (IOException e) {
00194                                         logOutput.println("Failed creating an in/out connection with the client.");
00195                                 }
00196 
00197                                 final StringBuilder sb = new StringBuilder();
00198 
00199                                 String inputLine = null;
00200 
00201                                 boolean trimmed = false;
00202 
00203                                 try {
00204                                         while (((inputLine = in.readLine()) != null)) {
00205                                                 sb.append(inputLine);
00206 
00207                                                 // System.out.println(inputLine);
00208                                                 if (!trimmed) { // remove the cruft up front
00209                                                         final int xmlStart = sb.indexOf("<?xml");
00210                                                         if (xmlStart != -1) {
00211                                                                 sb.delete(0, xmlStart);
00212                                                                 trimmed = true;
00213                                                         }
00214                                                 }
00215 
00216                                                 // seems like adobe acrobat has a bug here!
00217                                                 // where is the final closing character??? =D
00218                                                 if (sb.indexOf("</xfdf") != -1) {
00219                                                         // we're done!
00220                                                         break;
00221                                                 }
00222                                         }
00223 
00224                                         logToConsoleAndFile("[Client " + id + "]");
00225                                         // include the final character that adobe didn't send us
00226 
00227                                         processXML(sb.toString() + ">");
00228 
00229                                         final File parentDir = outputFile.getParentFile();
00230                                         // fill in the correct URI of the parent directory
00231                                         String confirmation = CONFIRMATION.toString().replace("__PARENTURI__",
00232                                                         parentDir.toURI().toString());
00233                                         confirmation = confirmation.replace("__FOLDERNAME__", parentDir.getName());
00234                                         confirmation = confirmation.replace("__FILEURI__", outputFile.toURI().toString());
00235                                         confirmation = confirmation.replace("__FILENAME__", outputFile.getName());
00236 
00237                                         // tell the client to go away now
00238                                         // provide a valid web server response so that the Acrobat web browser
00239                                         // will not hang
00240                                         out.println("HTTP/1.1 200 OK");
00241                                         out.println("Content-Length: " + confirmation.length());
00242                                         out.println("Connection: close");
00243                                         out.println("Content-Type: text/html; charset=UTF-8");
00244                                         out.println();
00245                                         out.println(confirmation);
00246                                         clientConn.close();
00247                                 } catch (IOException e) {
00248                                         logOutput.println("Failed reading a line from the client.");
00249                                         logOutput.println("Perhaps client " + id + " is closed?");
00250                                 }
00251                         }
00252 
00253                 });
00254         }
00255 
00259         private void logToConsoleAndFile(String msg) {
00260                 System.out.println(msg);
00261                 logOutput.println(msg);
00262         }
00263 
00269         private void processXML(String xml) {
00270                 logToConsoleAndFile(xml);
00271                 final File xmlFile = PaperToolkit.getResourceFile("/designer/TemporaryXML.xml");
00272                 FileWriter fw;
00273                 try {
00274                         fw = new FileWriter(xmlFile);
00275                         fw.append(xml);
00276                         fw.close();
00277                 } catch (IOException e) {
00278                         e.printStackTrace();
00279                 }
00280 
00281                 final RegionConfigurationWriter writer = new RegionConfigurationWriter(xmlFile);
00282                 writer.processXML();
00283                 outputFile = writer.getOutputFile();
00284         }
00285 
00286 }

Generated on Sat Apr 14 18:21:32 2007 for R3 Paper Toolkit by  doxygen 1.4.7