aboutsummaryrefslogtreecommitdiff
path: root/src/IvyClient.java
diff options
context:
space:
mode:
authorjestin2011-07-22 16:49:57 +0000
committerjestin2011-07-22 16:49:57 +0000
commit750f33265d208df8218f85359e3f027900c58363 (patch)
tree105db356fc9b87fc04f1c09a4c2a567e93b37eed /src/IvyClient.java
parent90ac7a3566995cc244f9fdaff41e6c5122c7ca2e (diff)
downloadivy-java-750f33265d208df8218f85359e3f027900c58363.zip
ivy-java-750f33265d208df8218f85359e3f027900c58363.tar.gz
ivy-java-750f33265d208df8218f85359e3f027900c58363.tar.bz2
ivy-java-750f33265d208df8218f85359e3f027900c58363.tar.xz
Passage en 1.2.14
Diffstat (limited to 'src/IvyClient.java')
-rwxr-xr-xsrc/IvyClient.java178
1 files changed, 110 insertions, 68 deletions
diff --git a/src/IvyClient.java b/src/IvyClient.java
index b723433..8ed25f7 100755
--- a/src/IvyClient.java
+++ b/src/IvyClient.java
@@ -10,6 +10,18 @@
* created for each remote client.
*
* CHANGELOG:
+ * 1.2.14
+ * - use autoboxing for the creation of Integer (instead of
+ * new Integer(int). This alows caching, avoids object allocation, and the
+ * code will be faster
+ * - removed the synchronized on boxed primitive (Integer(0) for lock, which
+ * could be cached and reused elsewhere). Lock is now a new Object()
+ * - remove the Thread.start() from the constructor, to avoid mulithread issues
+ * see * http://findbugs.sourceforge.net/bugDescriptions.html#SC_START_IN_CTOR
+ * now ,we have to call IvyClient.start() after it has been created
+ * - add generic types to declarations
+ * - remove sendBye(), which is never called
+ * - switch from gnu regexp (deprecated) to the built in java regexp
* 1.2.12
* - Ping and Pong are back ...
* 1.2.8
@@ -78,9 +90,9 @@ import java.lang.Thread;
import java.net.*;
import java.io.*;
import java.util.*;
-import org.apache.regexp.*;
+import java.util.regex.*;
-public class IvyClient implements Runnable {
+public class IvyClient extends Thread {
/* the protocol magic numbers */
final static int Bye = 0; /* end of the peer */
@@ -105,11 +117,10 @@ public class IvyClient implements Runnable {
// private variables
private final static int MAXPONGCALLBACKS = 10;
private static int pingSerial = 0;
- private static Integer csMutex=new Integer(0);
+ private static final Object lock = new Object();
private static int clientSerial=0; /* an unique ID for each IvyClient */
- private Hashtable PingCallbacksTable = new Hashtable();
+ private Hashtable <Integer,PingCallbackHolder>PingCallbacksTable = new Hashtable<Integer,PingCallbackHolder>();
- private String messages_classes[] = null;
private Ivy bus;
private Socket socket;
private BufferedReader in;
@@ -122,8 +133,8 @@ public class IvyClient implements Runnable {
// protected variables
String appName="none";
- Hashtable regexps = new Hashtable();
- Hashtable regexpsText = new Hashtable();
+ Hashtable <Integer,Pattern>regexps = new Hashtable<Integer,Pattern>();
+ Hashtable <Integer,String>regexpsText = new Hashtable<Integer,String>();
static boolean debug = (System.getProperty("IVY_DEBUG")!=null) ;
// int protocol;
private boolean incoming;
@@ -131,7 +142,7 @@ public class IvyClient implements Runnable {
IvyClient() { }
IvyClient(Ivy bus, Socket socket,int remotePort,boolean incoming) throws IOException {
- synchronized(csMutex) { clientKey=new Integer(clientSerial++); }
+ synchronized(lock) { clientKey=clientSerial++; }
this.bus = bus;
this.remotePort = remotePort;
this.incoming = incoming;
@@ -149,6 +160,12 @@ public class IvyClient implements Runnable {
}
remoteHostname = socket.getInetAddress().getHostName();
clientThread = new Thread(this); // clientThread handles the incoming traffic
+ }
+
+ /* removed from the constructor, to avoid Mulithread correctnaess issuses
+ * see http://findbugs.sourceforge.net/bugDescriptions.html#SC_START_IN_CTOR
+ */
+ protected void doStart() {
clientThread.start();
}
@@ -157,24 +174,16 @@ public class IvyClient implements Runnable {
// information is in the socket itself, the port is not known if we
// initiate the connexion
private void sendSchizo() throws IOException {
- traceDebug("sending our service port "+bus.applicationPort);
- Hashtable tosend=bus.selfIvyClient.regexpsText;
- sendString(SchizoToken,bus.applicationPort,bus.appName);
- for (Enumeration e = tosend.keys(); e.hasMoreElements(); ) {
- Integer ikey = (Integer)e.nextElement();
- sendRegexp(ikey.intValue(),(String)tosend.get(ikey));
- }
+ traceDebug("sending our service port "+bus.getAppPort());
+ Hashtable<Integer,String> tosend=bus.getSelfIvyClient().regexpsText;
+ sendString(SchizoToken,bus.getAppPort(),bus.getAppName());
+ for (Integer ikey : tosend.keySet()) sendRegexp(ikey.intValue(),tosend.get(ikey));
sendString( EndRegexp,0,"");
}
- synchronized private void handShake() throws IvyException {
- synchronized(bus) {
- bus.removeHalf(this);
- bus.addClient(this);
- }
- }
+ public String toString() {
+ return "IC["+clientKey+","+bus.getSerial()+"] "+bus.getAppName()+":"+appName+":"+remotePort; }
- public String toString() { return "IC["+clientKey+","+bus.getSerial()+"] "+bus.appName+":"+appName+":"+remotePort; }
public String toStringExt() {
return "client socket:"+socket+", remoteport:" + remotePort;
}
@@ -197,9 +206,8 @@ public class IvyClient implements Runnable {
* allow the notification of regexp addition and deletion
* The content is not modifyable because String are not mutable, and cannot
* be modified once they are create.
- * @see IvyClient#getRegexpsArray() getRegexpsArray to get a String[] result
*/
- public Enumeration getRegexps() { return regexpsText.elements(); }
+ public Enumeration<String> getRegexps() { return regexpsText.elements(); }
/**
* allow an Ivy package class to access the list of regexps at a
@@ -209,8 +217,8 @@ public class IvyClient implements Runnable {
public String[] getRegexpsArray() {
String[] s = new String[regexpsText.size()];
int i=0;
- for (Enumeration e=getRegexps();e.hasMoreElements();)
- s[i++]=(String)e.nextElement();
+ for (Enumeration<String>e=getRegexps();e.hasMoreElements();)
+ s[i++]=e.nextElement();
return s;
}
@@ -265,15 +273,13 @@ public class IvyClient implements Runnable {
protected int sendMsg(String message) {
int count = 0;
- for (Enumeration e = regexps.keys();e.hasMoreElements();) {
- Integer key = (Integer)e.nextElement();
- RE regexp = (RE)regexps.get(key);
+ for (Integer key : regexps.keySet()) {
+ Pattern regexp = regexps.get(key);
synchronized (regexp) {
- // re.match fails sometimes when it is called concurrently ..
- // see 28412 on jakarta regexp bugzilla
- if (regexp.match(message)) {
+ Matcher m = regexp.matcher(message);
+ if (m.matches()) {
count++; // match
- sendResult(Msg,key,regexp);
+ sendResult(Msg,key,m);
}
}
}
@@ -298,13 +304,13 @@ public class IvyClient implements Runnable {
* compares two peers the id is the couple (host,service port).
* true if the peers are similar. This should not happen, it is bad
*/
- protected int compareTo(IvyClient clnt) {
+ protected int distanceTo(IvyClient clnt) {
// return clnt.clientKey.compareTo(clientKey); // Wrong. it's random...
return (clnt.socket.getPort()-socket.getLocalPort());
}
protected boolean equals(IvyClient clnt) {
- if (clnt==this) return false;
+ if (clnt==this) return true;
// TODO go beyond the port number ! add some host processing, cf:
// IvyWatcher ...
if (remotePort==clnt.remotePort) return true;
@@ -339,7 +345,7 @@ public class IvyClient implements Runnable {
break;
}
} else {
- traceDebug("readline null ! leaving the thead");
+ traceDebug("readline null ! leaving the thread");
break;
}
} catch (IvyException ie) {
@@ -355,7 +361,7 @@ public class IvyClient implements Runnable {
break;
}
}
- traceDebug("normally Disconnected from "+ appName);
+ traceDebug("normally Disconnected from "+ bus.getAppName());
bus.removeClient(this);
// invokes the disconnect applicationListeners
if (!discCallbackPerformed) bus.clientDisconnects(this);
@@ -363,6 +369,15 @@ public class IvyClient implements Runnable {
traceDebug("Thread stopped");
}
+ @Override public void interrupt(){
+ super.interrupt();
+ try {
+ if (socket!=null) socket.close();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
protected synchronized void sendBuffer( String buffer ) throws IvyException {
buffer += "\n";
try {
@@ -392,40 +407,52 @@ public class IvyClient implements Runnable {
}
}
- private void sendResult(int type,Integer id, RE regexp) {
+ private void sendResult(int type,Integer id, Matcher m) {
try {
- String buffer = type+" "+id+StartArg;
- for(int i=1;i<regexp.getParenCount();i++)
- buffer+=regexp.getParen(i)+EndArg;
- sendBuffer(buffer);
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(type);
+ buffer.append(" ");
+ buffer.append(id);
+ buffer.append(StartArg);
+ for(int i=1;i<=m.groupCount();i++){
+ buffer.append(m.group(i));
+ buffer.append(EndArg);
+ }
+ sendBuffer(buffer.toString());
} catch (IvyException ie ) {
System.err.println("received an exception: " + ie.getMessage());
ie.printStackTrace();
} catch (StringIndexOutOfBoundsException sioobe) {
- System.out.println("arg: "+regexp.getParenCount()+" "+regexp);
+ System.out.println("arg: "+m.groupCount()+" "+m);
sioobe.printStackTrace();
}
}
private String dumpHex(String s) {
byte[] b = s.getBytes();
- String outDump = "";
- String zu = "\t";
+ StringBuffer outDump = new StringBuffer();
+ StringBuffer zu = new StringBuffer("\t");
for (int i=0;i<b.length;i++) {
char c = s.charAt(i);
- outDump+=((int)c) + " ";
- zu+= ((c>15) ? c : 'X')+" ";
+ outDump.append(((int)c));
+ outDump.append(" ");
+ zu.append((c>15) ? c : 'X');
+ zu.append(" ");
}
- outDump += zu;
- return outDump;
+ outDump.append(zu);
+ return outDump.toString();
}
private String dumpMsg(String s) {
- String deb = " \""+s+"\" "+s.length()+" cars, ";
+ StringBuffer deb = new StringBuffer(" \""+s+"\" "+s.length()+" cars, ");
for (int i=0;i<s.length();i++) {
- deb+= "["+s.charAt(i) + "]:" + (int)s.charAt(i) +", ";
+ deb.append("[");
+ deb.append(s.charAt(i));
+ deb.append("]:");
+ deb.append(s.charAt(i));
+ deb.append(", ");
}
- return s;
+ return deb.toString();
}
protected boolean newParseMsg(String s) throws IvyException {
@@ -496,12 +523,12 @@ public class IvyClient implements Runnable {
break;
case AddRegexp:
String regexp=s.substring(from,b.length);
- if ( bus.CheckRegexp(regexp) ) {
+ if ( bus.checkRegexp(regexp) ) {
try {
- regexps.put(msgId,new RE(regexp));
+ regexps.put(msgId,Pattern.compile(regexp,Pattern.DOTALL));
regexpsText.put(msgId,regexp);
bus.regexpReceived(this,msgId.intValue(),regexp);
- } catch (RESyntaxException e) {
+ } catch (PatternSyntaxException e) {
// the remote client sent an invalid regexp !
traceDebug("invalid regexp sent by " +appName+" ("+regexp+"), I will ignore this regexp");
sendBuffer(Error+e.toString());
@@ -519,10 +546,11 @@ public class IvyClient implements Runnable {
break;
case EndRegexp:
bus.clientConnects(this);
- if (bus.ready_message!=null) sendMsg(bus.ready_message);
+ String srm = bus.getReadyMessage();
+ if (srm!=null) sendMsg(srm);
break;
case Msg:
- Vector v = new Vector();
+ Vector <String>v = new Vector<String>();
while (to<b.length) {
while ( (to<b.length) && (b[to]!=3) ) to++;
if (to<b.length) {
@@ -532,10 +560,11 @@ public class IvyClient implements Runnable {
}
}
String[] tab = new String[v.size()];
- for (int i=0;i<v.size();i++) tab[i]=(String)v.elementAt(i);
+ int i=0;
+ for (String st: v) tab[i++]=st;
// for developpemnt purposes
traceDebug(tab);
- bus.selfIvyClient.callCallback(this,msgId,tab);
+ bus.getSelfIvyClient().callCallback(this,msgId,tab);
break;
case Error:
String error=s.substring(from,b.length);
@@ -551,7 +580,7 @@ public class IvyClient implements Runnable {
try {
bus.addHalf(this);
sendSchizo();
- handShake();
+ bus.handShake(this);
} catch (IOException ioe) {
throw new IvyException(ioe.toString());
}
@@ -559,7 +588,7 @@ public class IvyClient implements Runnable {
} else {
// outgoing connexion
// I already have sent him a token
- handShake();
+ bus.handShake(this);
}
break;
case DirectMsg:
@@ -573,7 +602,7 @@ public class IvyClient implements Runnable {
return true;
}
- private void sendBye() {sendString(Bye,0,"");}
+ //private void sendBye() {sendString(Bye,0,"");}
private void sendBye(String message) {sendString(Bye,0,message);}
private void traceDebug(String s){
@@ -581,24 +610,30 @@ public class IvyClient implements Runnable {
int serial=0;
if (bus!=null) {
serial=bus.getSerial();
- app=bus.appName;
+ app=bus.getAppName();
}
if (debug) System.out.println("-->IvyClient["+clientKey+","+serial+"] "+app+" (remote "+appName+")<-- "+s);
}
private void traceDebug(String[] tab){
- String s = " string array " + tab.length + " elements: ";
- for (int i=0;i<tab.length;i++) s+="("+tab[i]+") ";
- traceDebug(s);
+ StringBuffer s = new StringBuffer(" string array ");
+ s.append(tab.length);
+ s.append(" elements: ");
+ for (String ss: tab) {
+ s.append("(");
+ s.append(ss);
+ s.append(") ");
+ }
+ traceDebug(s.toString());
}
void PCHadd(int serial,PingCallback pc) {
- PingCallbacksTable.put(new Integer(serial),new PingCallbackHolder(pc));
+ PingCallbacksTable.put(serial,new PingCallbackHolder(pc));
if (PingCallbacksTable.size()>MAXPONGCALLBACKS) {
// more than MAXPONGCALLBACKS callbacks, we ought to limit to prevent a
// memory leak
// TODO remove the first
- Integer smallest=(Integer)new TreeSet(PingCallbacksTable.keySet()).first();
+ Integer smallest=(Integer)new TreeSet<Integer>(PingCallbacksTable.keySet()).first();
PingCallbackHolder pch = (PingCallbackHolder)PingCallbacksTable.remove(smallest);
System.err.println("no response from "+getApplicationName()+" to ping "+smallest+" after "+pch.age()+" ms, discarding");
}
@@ -626,4 +661,11 @@ public class IvyClient implements Runnable {
}
}
+ public static void main(String[] args) {
+ String s="hello\nworld";
+ String dest=encode(s);
+ System.out.println("avant: <"+s+">\naprès: <"+dest+">");
+ System.out.println("tailles: "+s.length()+" "+dest.length());
+ }
+
}