PenClient.java

00001 package edu.stanford.hci.r3.pen.streaming;
00002 
00003 import java.io.BufferedReader;
00004 import java.io.IOException;
00005 import java.io.InputStream;
00006 import java.io.InputStreamReader;
00007 import java.net.InetAddress;
00008 import java.net.Socket;
00009 import java.net.SocketException;
00010 import java.net.UnknownHostException;
00011 import java.util.ArrayList;
00012 import java.util.Collections;
00013 import java.util.List;
00014 
00015 import com.thoughtworks.xstream.XStream;
00016 
00017 import edu.stanford.hci.r3.pen.PenSample;
00018 import edu.stanford.hci.r3.pen.streaming.listeners.PenListener;
00019 import edu.stanford.hci.r3.util.DebugUtils;
00020 import edu.stanford.hci.r3.util.networking.ClientServerType;
00021 
00039 public class PenClient {
00040 
00041         private Socket clientSocket;
00042 
00043         private ClientServerType clientType;
00044 
00045         private boolean exitFlag = false;
00046 
00050         private List<PenListener> listeners = Collections
00051                         .synchronizedList(new ArrayList<PenListener>());
00052 
00056         private String machineName;
00057 
00058         private int portNumber;
00059 
00060         private Thread socketListenerThread;
00061 
00067         public PenClient(String serverName, int port, ClientServerType type) {
00068                 machineName = serverName;
00069                 portNumber = port;
00070                 clientType = type;
00071         }
00072 
00077         public synchronized boolean addPenListener(PenListener penListener) {
00078                 return listeners.add(penListener);
00079         }
00080 
00084         public void connect() {
00085                 socketListenerThread = getSocketListenerThreadBasedOnClientType();
00086                 socketListenerThread.start();
00087         }
00088 
00092         public synchronized void disconnect() {
00093                 exitFlag = true;
00094                 try {
00095                         if (clientSocket != null) {
00096                                 clientSocket.close();
00097                         }
00098                 } catch (IOException e) {
00099                         e.printStackTrace();
00100                 }
00101         }
00102 
00106         private Thread getSocketListenerThreadBasedOnClientType() {
00107 
00108                 if (clientType == ClientServerType.JAVA) {
00109                         return new Thread(new Runnable() {
00110 
00111                                 boolean penIsDown = false;
00112 
00113                                 public void run() {
00114                                         try {
00115                                                 final BufferedReader br = setupSocketAndReader();
00116                                                 String line = null;
00117 
00118                                                 final XStream xml = new XStream();
00119 
00120                                                 while ((line = br.readLine()) != null) {
00121                                                         // System.out.println(line);
00122 
00123                                                         // reconstruct the sample from xml
00124                                                         final PenSample sample = (PenSample) xml.fromXML(line);
00125                                                         final boolean penIsUp = sample.isPenUp();
00126 
00127                                                         // basically implements a state machine... =)
00128                                                         if (!penIsDown && !penIsUp) {
00129                                                                 penIsDown = true;
00130                                                                 notifyListenersOfPenDown(sample);
00131                                                         } else if (penIsUp) {
00132                                                                 penIsDown = false;
00133                                                                 notifyListenersOfPenUp(sample);
00134                                                         } else {
00135                                                                 // tell my listeners!
00136                                                                 // June 12, 2006 & Nov 2, 2006
00137                                                                 // the behavior here is the same as in pen connection
00138                                                                 // where a .sample event is NOT generated when penUp or penDown
00139                                                                 // happen
00140                                                                 // samples are only generated while the pen is down
00141                                                                 // (but not if it just came down)
00142                                                                 if (penIsDown) {
00143                                                                         notifyListenersOfPenSample(sample);
00144                                                                 }
00145                                                         }
00146 
00147                                                         if (exitFlag) {
00148                                                                 break;
00149                                                         }
00150                                                 }
00151                                         } catch (UnknownHostException e) {
00152                                                 e.printStackTrace();
00153                                         } catch (SocketException se) {
00154                                                 if (se.getMessage().contains("socket closed")) {
00155                                                         DebugUtils.println("Pen Client's Socket is now closed...");
00156                                                 }
00157                                         } catch (IOException e) {
00158                                                 e.printStackTrace();
00159                                         }
00160                                 }
00161 
00162                         });
00163                 } else { // PLAIN TEXT CLIENT
00164                         return new Thread(new Runnable() {
00165                                 public void run() {
00166                                         try {
00167                                                 final BufferedReader br = setupSocketAndReader();
00168                                                 String line = null;
00169                                                 while ((line = br.readLine()) != null) {
00170                                                         // System.out.println(line);
00171 
00172                                                         // reconstruct the sample
00173 
00174                                                         // tell my listeners!
00175                                                         System.out.println(line);
00176 
00177                                                         if (exitFlag) {
00178                                                                 break;
00179                                                         }
00180                                                 }
00181                                         } catch (UnknownHostException e) {
00182                                                 e.printStackTrace();
00183                                         } catch (IOException e) {
00184                                                 e.printStackTrace();
00185                                         }
00186                                 }
00187                         });
00188                 }
00189         }
00190 
00194         private synchronized void notifyListenersOfPenDown(final PenSample sample) {
00195                 for (PenListener pl : listeners) {
00196                         pl.penDown(sample);
00197                 }
00198         }
00199 
00203         private synchronized void notifyListenersOfPenSample(final PenSample sample) {
00204                 for (PenListener pl : listeners) {
00205                         pl.sample(sample);
00206                 }
00207         }
00208 
00212         private synchronized void notifyListenersOfPenUp(final PenSample sample) {
00213                 for (PenListener pl : listeners) {
00214                         pl.penUp(sample);
00215                 }
00216         }
00217 
00224         public synchronized boolean removePenListener(PenListener penListener) {
00225                 return listeners.remove(penListener);
00226         }
00227 
00235         private BufferedReader setupSocketAndReader() throws UnknownHostException, IOException {
00236                 DebugUtils.println("Trying to connect to " + machineName + ":" + portNumber);
00237                 final InetAddress addr = InetAddress.getByName(machineName);
00238                 final String hostName = addr.getCanonicalHostName();
00239                 DebugUtils.println("The resolved host name of this pen is: " + hostName);
00240 
00241                 clientSocket = new Socket(machineName, portNumber);
00242                 final InputStream inputStream = clientSocket.getInputStream();
00243                 final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
00244                 return br;
00245         }
00246 }

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