diff options
author | jestin | 2011-07-22 16:49:57 +0000 |
---|---|---|
committer | jestin | 2011-07-22 16:49:57 +0000 |
commit | 750f33265d208df8218f85359e3f027900c58363 (patch) | |
tree | 105db356fc9b87fc04f1c09a4c2a567e93b37eed /src/IvyClient.java | |
parent | 90ac7a3566995cc244f9fdaff41e6c5122c7ca2e (diff) | |
download | ivy-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-x | src/IvyClient.java | 178 |
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()); + } + } |