Clover coverage report - DrJava Test Coverage (drjava-20120304-r5456)
Coverage timestamp: Sun Mar 4 2012 03:13:23 CST
file stats: LOC: 185   Methods: 6
NCLOC: 82   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
RemoteControlServer.java 30% 58.5% 83.3% 56.1%
coverage coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.drjava;
 38   
 39    import edu.rice.cs.drjava.ui.MainFrame;
 40    import edu.rice.cs.util.FileOpenSelector;
 41    import edu.rice.cs.util.OperationCanceledException;
 42    import edu.rice.cs.drjava.config.OptionConstants;
 43   
 44    import java.io.*;
 45    import java.net.*;
 46   
 47    /** This class contains a server that monitors incoming datagrams on port 4444
 48    * (default; can be changed in OptionConstants.REMOTE_CONTROL_PORT).
 49    * These datagrams can contain commands to open additional files.
 50    *
 51    * A client can query whether a server is running by sending QUERY_PREFIX.
 52    * If a server is running, it will respond with RESPONSE_PREFIX.
 53    *
 54    * A client can tell a server to open a file by sending QUERY_PREFIX + " " + absoluteFileName.
 55    * The server will respond with RESPONSE_PREFIX, or RESPONSE_PREFIX + " " + error if an error occurred.
 56    *
 57    * A client can tell a server to open a file and jump to a certain line number by sending QUERY_PREFIX + " " +
 58    * absoluteFileName + File.pathSeparator + lineNumber.
 59    * The server will respond with RESPONSE_PREFIX, or RESPONSE_PREFIX + " " + error if an error occurred.
 60    *
 61    * This class is declared final because it cannot be robustly subclassed because the constructor starts a thread.
 62    */
 63    public final class RemoteControlServer {
 64    /** Prefix of a legitimate query by a client. */
 65    public static final String QUERY_PREFIX = "DrJava Remote Control?";
 66   
 67    /** Prefix of a legitimate response by this server. */
 68    public static final String RESPONSE_PREFIX = "DrJava Remote Control ";
 69   
 70    /** Prefix of a legitimate response by this server, including the user name. */
 71    public static final String RESPONSE_PREFIX_WITH_USER = RESPONSE_PREFIX+System.getProperty("user.name") + "!";
 72   
 73    /** Create a new remote control server, running in its own daemon thread.
 74    * @param frame main frame
 75    */
 76  11 public RemoteControlServer(MainFrame frame) throws IOException {
 77  11 RCServerThread rcsThread = new RCServerThread(frame);
 78  6 rcsThread.setDaemon(true);
 79  6 rcsThread.start();
 80    }
 81   
 82    /** Thread class for the server. */
 83    public static class RCServerThread extends Thread {
 84    /** Main frame access so the server can open files, etc. */
 85    protected MainFrame _frame;
 86   
 87    /** Socket used. */
 88    protected DatagramSocket socket = null;
 89   
 90    /** Create a new server thread.
 91    * @param frame main frame
 92    */
 93  6 public RCServerThread(MainFrame frame) throws IOException {
 94  6 this("RCServerThread", frame);
 95    }
 96   
 97    /**
 98    * Create a new server thread with a specified name.
 99    * @param name thread name
 100    * @param frame main frame
 101    */
 102  11 public RCServerThread(String name, MainFrame frame) throws IOException {
 103  11 super(name);
 104  11 _frame = frame;
 105  11 socket = new DatagramSocket(DrJava.getConfig().getSetting(OptionConstants.REMOTE_CONTROL_PORT));
 106    }
 107   
 108    /**
 109    * Main method of the thread. It loops indefinitely, waiting for queries.
 110    * Since this is a daemon thread, it will get shut down at the end.
 111    */
 112  6 public void run() {
 113  6 while (true) {
 114  11 try {
 115  11 byte[] buf = new byte[256];
 116   
 117    // receive request
 118  11 DatagramPacket packet = new DatagramPacket(buf, buf.length);
 119  11 socket.receive(packet);
 120   
 121  5 String request = new String(packet.getData(), 0, packet.getLength());
 122   
 123    // check if it was a legitimate query
 124  5 if (request.startsWith(QUERY_PREFIX)) {
 125    // construct response
 126  5 String dString = RESPONSE_PREFIX_WITH_USER;
 127  5 request = request.substring(QUERY_PREFIX.length());
 128   
 129    // check if a file was specified
 130  5 if ((request.length() > 0) && (request.charAt(0) == ' ')) {
 131  0 request = request.substring(1);
 132   
 133    // check if the request contained a line number
 134  0 int lineNo = -1;
 135  0 int pathSepIndex = request.indexOf(File.pathSeparatorChar);
 136  0 if (pathSepIndex >= 0) {
 137  0 try {
 138  0 lineNo = Integer.valueOf(request.substring(pathSepIndex+1));
 139    }
 140    catch(NumberFormatException nfe) {
 141  0 lineNo = -1;
 142    }
 143  0 request = request.substring(0,pathSepIndex);
 144    }
 145   
 146  0 final File f = new File(request);
 147  0 if (f.exists()) {
 148  0 DrJavaRoot.handleRemoteOpenFile(f, lineNo);
 149    }
 150    }
 151    else {
 152  5 dString = dString + " Cannot open file!";
 153    }
 154   
 155  5 buf = dString.getBytes();
 156   
 157    // send the response to the client at "address" and "port"
 158  5 InetAddress address = packet.getAddress();
 159  5 int port = packet.getPort();
 160  5 packet = new DatagramPacket(buf, buf.length, address, port);
 161   
 162  5 socket.send(packet);
 163    }
 164    }
 165    catch (SocketTimeoutException e) {
 166    // ignore
 167    }
 168  0 catch (IOException e) { e.printStackTrace(); }
 169    }
 170    }
 171   
 172  0 protected void finalize() { if (socket != null) socket.close(); }
 173    }
 174   
 175    /** Main method for test purposes. */
 176  0 public static void main(String[] args) {
 177  0 try {
 178  0 (new RCServerThread(null)).start();
 179    }
 180    catch(IOException ioe) {
 181  0 System.out.println(ioe);
 182  0 ioe.printStackTrace();
 183    }
 184    }
 185    }