jon 02/02/18 18:25:02 Modified: src/java/org/apache/xmlrpc Base64.java ServerInputStream.java WebServer.java XmlRpc.java XmlRpcClient.java Log: I did a bunch of code cleanup and minor optimizations, switched to the catalina Base64 (note the one FIXME, if someone has a suggestion for a better way, let me know). Found a couple optimizations (such as not calling System.currentTimeMillis() unless debug is on... Revision Changes Path 1.2 +271 -275 xml-rpc/src/java/org/apache/xmlrpc/Base64.java Index: Base64.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/Base64.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- Base64.java 20 Jul 2001 19:38:16 -0000 1.1 +++ Base64.java 19 Feb 2002 02:25:01 -0000 1.2 @@ -1,326 +1,322 @@ package org.apache.xmlrpc; -// We can replace this with some apache code I'm sure. jvz. - -//////////////////////license & copyright header///////////////////////// -// // -// Base64 - encode/decode data using the Base64 encoding scheme // -// // -// Copyright (c) 1998 by Kevin Kelley // -// // -// This library is free software; you can redistribute it and/or // -// modify it under the terms of the GNU Lesser General Public // -// License as published by the Free Software Foundation; either // -// version 2.1 of the License, or (at your option) any later version. // -// // -// This library is distributed in the hope that it will be useful, // -// but WITHOUT ANY WARRANTY; without even the implied warranty of // -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // -// GNU Lesser General Public License for more details. // -// // -// You should have received a copy of the GNU Lesser General Public // -// License along with this library; if not, write to the Free Software // -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // -// 02111-1307, USA, or contact the author: // -// // -// Kevin Kelley <[EMAIL PROTECTED]> - 30718 Rd. 28, La Junta, CO, // -// 81050 USA. // -// // -////////////////////end license & copyright header/////////////////////// - -import java.io.*; // needed only for main() method. - +/* + * $Header: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/Base64.java,v 1.2 2002/02/19 02:25:01 jon Exp $ + * $Revision: 1.2 $ + * $Date: 2002/02/19 02:25:01 $ + * + * ==================================================================== + * + * The Apache Software License, Version 1.1 + * + * Copyright (c) 1999 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, if + * any, must include the following acknowlegement: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowlegement may appear in the software itself, + * if and wherever such third-party acknowlegements normally appear. + * + * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software + * Foundation" must not be used to endorse or promote products derived + * from this software without prior written permission. For written + * permission, please contact [EMAIL PROTECTED] + * + * 5. Products derived from this software may not be called "Apache" + * nor may "Apache" appear in their names without prior written + * permission of the Apache Group. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * <http://www.apache.org/>. + * + * [Additional notices, if required by prior licensing conditions] + * + */ /** -* Provides encoding of raw bytes to base64-encoded characters, and -* decoding of base64 characters to raw bytes. -* -* @author Kevin Kelley ([EMAIL PROTECTED]) -* @version 1.3 -* @date 06 August 1998 -* @modified 14 February 2000 -* @modified 22 September 2000 -*/ -public class Base64 + * This class provides encode/decode for RFC 2045 Base64 as defined by + * RFC 2045, N. Freed and N. Borenstein. <a + * href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>: + * Multipurpose Internet Mail Extensions (MIME) Part One: Format of + * Internet Message Bodies. Reference 1996 + * + * @author Jeffrey Rodriguez + * @version $Id: Base64.java,v 1.2 2002/02/19 02:25:01 jon Exp $ + */ +public final class Base64 { + static private final int BASELENGTH = 255; + static private final int LOOKUPLENGTH = 64; + static private final int TWENTYFOURBITGROUP = 24; + static private final int EIGHTBIT = 8; + static private final int SIXTEENBIT = 16; + static private final int SIXBIT = 6; + static private final int FOURBYTE = 4; + static private final int SIGN = -128; + static private final byte PAD = (byte) '='; + static private byte [] base64Alphabet = new byte[BASELENGTH]; + static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH]; + //static private final Log log = LogSource.getInstance("org.apache.commons.util.Base64"); - /** - * returns an array of base64-encoded characters to represent the - * passed data array. - * - * @param data the array of bytes to encode - * @return base64-coded character array. - */ - static public char[] encode(byte[] data) + static { - char[] out = new char[((data.length + 2) / 3) * 4]; - - // - // 3 bytes encode to 4 chars. Output is always an even - // multiple of 4 characters. - // - for (int i = 0, index = 0; i < data.length; i += 3, index += 4) - { - boolean quad = false; - boolean trip = false; - - int val = (0xFF & (int) data[i]); - val <<= 8; - if ((i + 1) < data.length) - { - val |= (0xFF & (int) data[i + 1]); - trip = true; - } - val <<= 8; - if ((i + 2) < data.length) - { - val |= (0xFF & (int) data[i + 2]); - quad = true; - } - out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)]; - val >>= 6; - out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)]; - val >>= 6; - out[index + 1] = alphabet[val & 0x3F]; - val >>= 6; - out[index + 0] = alphabet[val & 0x3F]; + for (int i = 0; i < BASELENGTH; i++ ) + { + base64Alphabet[i] = -1; } - return out; - } - - /** - * Decodes a BASE-64 encoded stream to recover the original - * data. White space before and after will be trimmed away, - * but no other manipulation of the input will be performed. - * - * As of version 1.2 this method will properly handle input - * containing junk characters (newlines and the like) rather - * than throwing an error. It does this by pre-parsing the - * input and generating from that a count of VALID input - * characters. - **/ - static public byte[] decode(char[] data) - { - // as our input could contain non-BASE64 data (newlines, - // whitespace of any sort, whatever) we must first adjust - // our count of USABLE data so that... - // (a) we don't misallocate the output array, and - // (b) think that we miscalculated our data length - // just because of extraneous throw-away junk - - int tempLen = data.length; - for (int ix = 0; ix < data.length; ix++) + for (int i = 'Z'; i >= 'A'; i--) { - if ((data[ix] > 255) || codes[data[ix]] < 0) - --tempLen; // ignore non-valid chars and padding + base64Alphabet[i] = (byte) (i - 'A'); } - // calculate required length: - // -- 3 bytes for every 4 valid base64 chars - // -- plus 2 bytes if there are 3 extra base64 chars, - // or plus 1 byte if there are 2 extra. - - int len = (tempLen / 4) * 3; - if ((tempLen % 4) == 3) - len += 2; - if ((tempLen % 4) == 2) - len += 1; - - byte[] out = new byte[len]; - - - - int shift = 0; // # of excess bits stored in accum - int accum = 0; // excess bits - int index = 0; - - // we now go through the entire array (NOT using the 'tempLen' value) - for (int ix = 0; ix < data.length; ix++) + for (int i = 'z'; i>= 'a'; i--) { - int value = (data[ix] > 255) ? -1 : codes[data[ix]]; - - if (value >= 0)// skip over non-code - - { - accum <<= 6; // bits shift up by 6 each time thru - shift += 6; // loop, with new bits being put in - accum |= value; // at the bottom. - if (shift >= 8)// whenever there are 8 or more shifted in, - - { - shift -= 8; // write them out (from the top, leaving any - out[index++] = // excess at the bottom for next iteration. - (byte)((accum >> shift) & 0xff); - } - } - // we will also have skipped processing a padding null byte ('=') here; - // these are used ONLY for padding to an even length and do not legally - // occur as encoded data. for this reason we can ignore the fact that - // no index++ operation occurs in that special case: the out[] array is - // initialized to all-zero bytes to start with and that works to our - // advantage in this combination. + base64Alphabet[i] = (byte) (i - 'a' + 26); } - - // if there is STILL something wrong we just have to throw up now! - if (index != out.length) + for (int i = '9'; i >= '0'; i--) { - throw new Error("Miscalculated data length (wrote " + - index + " instead of " + out.length + ")"); + base64Alphabet[i] = (byte) (i - '0' + 52); } - return out; - } - + base64Alphabet['+'] = 62; + base64Alphabet['/'] = 63; - // - // code characters for values 0..63 - // - static private char[] alphabet = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" .toCharArray(); - - // - // lookup table for converting base64 characters to value in range 0..63 - // - static private byte[] codes = new byte[256]; - static - { - for (int i = 0; i < 256; i++) - codes[i] = -1; - for (int i = 'A'; i <= 'Z'; i++) - codes[i] = (byte)(i - 'A'); - for (int i = 'a'; i <= 'z'; i++) - codes[i] = (byte)(26 + i - 'a'); - for (int i = '0'; i <= '9'; i++) - codes[i] = (byte)(52 + i - '0'); - codes['+'] = 62; - codes['/'] = 63; - } + for (int i = 0; i <= 25; i++ ) + lookUpBase64Alphabet[i] = (byte) ('A' + i); + for (int i = 26, j = 0; i <= 51; i++, j++ ) + lookUpBase64Alphabet[i] = (byte) ('a'+ j); + for (int i = 52, j = 0; i <= 61; i++, j++ ) + lookUpBase64Alphabet[i] = (byte) ('0' + j); + lookUpBase64Alphabet[62] = (byte) '+'; + lookUpBase64Alphabet[63] = (byte) '/'; + } - /////////////////////////////////////////////////// - // remainder (main method and helper functions) is - // for testing purposes only, feel free to clip it. - /////////////////////////////////////////////////// + public static boolean isBase64( String isValidString ) + { + return isArrayByteBase64(isValidString.getBytes()); + } - public static void main(String[] args) + public static boolean isBase64( byte octect ) { - boolean decode = false; + //shall we ignore white space? JEFF?? + return (octect == PAD || base64Alphabet[octect] != -1); + } - if (args.length == 0) + public static boolean isArrayByteBase64( byte[] arrayOctect ) + { + int length = arrayOctect.length; + if (length == 0) { - System.out.println("usage: java Base64 [-d[ecode]] filename"); - System.exit(0); + // shouldn't a 0 length array be valid base64 data? + // return false; + return true; } - for (int i = 0; i < args.length; i++) + for (int i=0; i < length; i++) { - if ("-decode".equalsIgnoreCase(args[i])) - decode = true; - else if ("-d".equalsIgnoreCase(args[i])) - decode = true; + if ( !Base64.isBase64(arrayOctect[i]) ) + return false; } + return true; + } - String filename = args[args.length - 1]; - File file = new File(filename); - if (!file.exists()) - { - System.out.println("Error: file '" + filename + "' doesn't exist!"); - System.exit(0); - } + /** + * Encodes hex octects into Base64. + * + * @param binaryData Array containing binary data to encode. + * @return Base64-encoded data. + */ + public static byte[] encode( byte[] binaryData ) + { + int lengthDataBits = binaryData.length*EIGHTBIT; + int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; + int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; + byte encodedData[] = null; - if (decode) + + if (fewerThan24bits != 0) { - char[] encoded = readChars(file); - byte[] decoded = decode(encoded); - writeBytes(file, decoded); + //data not divisible by 24 bit + encodedData = new byte[ (numberTriplets + 1 ) * 4 ]; } else { - byte[] decoded = readBytes(file); - char[] encoded = encode(decoded); - writeChars(file, encoded); + // 16 or 8 bit + encodedData = new byte[ numberTriplets * 4 ]; } - } - private static byte[] readBytes(File file) - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - try - { - InputStream fis = new FileInputStream(file); - InputStream is = new BufferedInputStream(fis); - int count = 0; - byte[] buf = new byte[16384]; - while ((count = is.read(buf)) != -1) - { - if (count > 0) - baos.write(buf, 0, count); - } - is.close(); - } - catch (Exception e) - { - e.printStackTrace(); + byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; + + int encodedIndex = 0; + int dataIndex = 0; + int i = 0; + //log.debug("number of triplets = " + numberTriplets); + for ( i = 0; i<numberTriplets; i++ ) + { + dataIndex = i*3; + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex + 1]; + b3 = binaryData[dataIndex + 2]; + + //log.debug("b1= " + b1 +", b2= " + b2 + ", b3= " + b3); + + l = (byte)(b2 & 0x0f); + k = (byte)(b1 & 0x03); + + encodedIndex = i * 4; + byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); + byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); + byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc); + + encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; + //log.debug( "val2 = " + val2 ); + //log.debug( "k4 = " + (k<<4) ); + //log.debug( "vak = " + (val2 | (k<<4)) ); + encodedData[encodedIndex+1] = + lookUpBase64Alphabet[ val2 | ( k<<4 )]; + encodedData[encodedIndex+2] = + lookUpBase64Alphabet[ (l <<2 ) | val3 ]; + encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ]; + } + + // form integral number of 6-bit groups + dataIndex = i*3; + encodedIndex = i*4; + if (fewerThan24bits == EIGHTBIT ) + { + b1 = binaryData[dataIndex]; + k = (byte) ( b1 &0x03 ); + //log.debug("b1=" + b1); + //log.debug("b1<<2 = " + (b1>>2) ); + byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); + encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; + encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ]; + encodedData[encodedIndex + 2] = PAD; + encodedData[encodedIndex + 3] = PAD; + } + else if (fewerThan24bits == SIXTEENBIT) + { + + b1 = binaryData[dataIndex]; + b2 = binaryData[dataIndex +1 ]; + l = (byte) (b2 & 0x0f); + k = (byte) (b1 & 0x03); + + byte val1 = ((b1 & SIGN) == 0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); + byte val2 = ((b2 & SIGN) == 0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); + + encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; + encodedData[encodedIndex + 1] = + lookUpBase64Alphabet[ val2 | ( k<<4 )]; + encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ]; + encodedData[encodedIndex + 3] = PAD; } - return baos.toByteArray(); + return encodedData; } - private static char[] readChars(File file) + /** + * Decodes Base64 data into octects + * + * @param binaryData Byte array containing Base64 data + * @return Array containing decoded data. + */ + public static byte[] decode( byte[] base64Data ) { - CharArrayWriter caw = new CharArrayWriter(); - try - { - Reader fr = new FileReader(file); - Reader in = new BufferedReader(fr); - int count = 0; - char[] buf = new char[16384]; - while ((count = in.read(buf)) != -1) + // handle the edge case, so we don't have to worry about it later + if(base64Data.length == 0) { return new byte[0]; } + + int numberQuadruple = base64Data.length/FOURBYTE; + byte decodedData[] = null; + byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0; + + // Throw away anything not in base64Data + + int encodedIndex = 0; + int dataIndex = 0; + { + // this sizes the output array properly - rlw + int lastData = base64Data.length; + // ignore the '=' padding + while (base64Data[lastData-1] == PAD) { - if (count > 0) - caw.write(buf, 0, count); + if (--lastData == 0) + { + return new byte[0]; + } } - in.close(); + decodedData = new byte[ lastData - numberQuadruple ]; } - catch (Exception e) + + for (int i = 0; i < numberQuadruple; i++) { - e.printStackTrace(); - } + dataIndex = i * 4; + marker0 = base64Data[dataIndex + 2]; + marker1 = base64Data[dataIndex + 3]; - return caw.toCharArray(); - } + b1 = base64Alphabet[base64Data[dataIndex]]; + b2 = base64Alphabet[base64Data[dataIndex +1]]; - private static void writeBytes(File file, byte[] data) - { - try - { - OutputStream fos = new FileOutputStream(file); - OutputStream os = new BufferedOutputStream(fos); - os.write(data); - os.close(); - } - catch (Exception e) - { - e.printStackTrace(); - } - } + if (marker0 != PAD && marker1 != PAD) + { + //No PAD e.g 3cQl + b3 = base64Alphabet[ marker0 ]; + b4 = base64Alphabet[ marker1 ]; + + decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; + decodedData[encodedIndex + 1] = + (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); + decodedData[encodedIndex + 2] = (byte)( b3<<6 | b4 ); + } + else if (marker0 == PAD) + { + //Two PAD e.g. 3c[Pad][Pad] + decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; + } + else if (marker1 == PAD) + { + //One PAD e.g. 3cQ[Pad] + b3 = base64Alphabet[ marker0 ]; - private static void writeChars(File file, char[] data) - { - try - { - Writer fos = new FileWriter(file); - Writer os = new BufferedWriter(fos); - os.write(data); - os.close(); - } - catch (Exception e) - { - e.printStackTrace(); + decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ); + decodedData[encodedIndex + 1] = + (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); + } + encodedIndex += 3; } + return decodedData; } - /////////////////////////////////////////////////// - // end of test code. - /////////////////////////////////////////////////// + } 1.2 +12 -9 xml-rpc/src/java/org/apache/xmlrpc/ServerInputStream.java Index: ServerInputStream.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/ServerInputStream.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ServerInputStream.java 20 Jul 2001 19:38:16 -0000 1.1 +++ ServerInputStream.java 19 Feb 2002 02:25:01 -0000 1.2 @@ -69,8 +69,8 @@ // This is used in order to correctly return a -1 when all the // data POSTed was read. If this is left to -1, content length is // assumed as unknown and the standard InputStream methods will be used - long available = -1; - long markedAvailable; + private long available = -1; + private long markedAvailable; private BufferedInputStream in; @@ -120,7 +120,9 @@ return read; } else if (available == -1) - return in.read (b, off, len); + { + return in.read(b, off, len); + } return -1; } @@ -128,25 +130,26 @@ { long skip = in.skip(n); if (available > 0) + { available -= skip; + } return skip; } - public void mark (int readlimit) + public void mark(int readlimit) { - in.mark (readlimit); + in.mark(readlimit); markedAvailable = available; } - public void reset () throws IOException + public void reset() throws IOException { - in.reset (); + in.reset(); available = markedAvailable; } - public boolean markSupported () + public boolean markSupported() { return true; } - } 1.5 +166 -126 xml-rpc/src/java/org/apache/xmlrpc/WebServer.java Index: WebServer.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- WebServer.java 13 Feb 2002 00:51:55 -0000 1.4 +++ WebServer.java 19 Feb 2002 02:25:01 -0000 1.5 @@ -87,6 +87,9 @@ protected static final byte[] ok = " 200 OK\r\n".getBytes(); protected static final byte[] server = "Server: Apache XML-RPC 1.0\r\n".getBytes(); + private static final String HTTP_11 = "HTTP/1.1"; + private static final String STAR = "*"; + /** * This <em>can</em> be called from command line, but you'll have to edit and recompile * to change the server port or handler objects. By default, it sets up the following responders: @@ -113,44 +116,44 @@ XmlRpc.setKeepAlive (true); try { - WebServer webserver = new WebServer (p); + WebServer webserver = new WebServer(p); // webserver.setParanoid (true); // webserver.acceptClient ("192.168.*.*"); - webserver.addHandler ("string", "Welcome to XML-RPC!"); - webserver.addHandler ("math", Math.class); - webserver.addHandler ("auth", new AuthDemo()); - webserver.addHandler ("$default", new Echo()); + webserver.addHandler("string", "Welcome to XML-RPC!"); + webserver.addHandler("math", Math.class); + webserver.addHandler("auth", new AuthDemo()); + webserver.addHandler("$default", new Echo()); // XmlRpcClients can be used as Proxies in XmlRpcServers which is a cool feature for applets. - webserver.addHandler ("mttf", new XmlRpcClient ("http://www.mailtothefuture.com:80/RPC2")); - System.err.println ("started web server on port "+p); + webserver.addHandler("mttf", new XmlRpcClient("http://www.mailtothefuture.com:80/RPC2")); + System.err.println("started web server on port "+p); } catch (IOException x) { - System.err.println ("Error creating web server: "+x); + System.err.println("Error creating web server: "+x); } } /** * Creates a Web server at the specified port number. */ - public WebServer (int port) + public WebServer(int port) throws IOException { - this (port, null); + this(port, null); } /** * Creates a Web server at the specified port number and IP address. */ - public WebServer (int port, InetAddress add) + public WebServer(int port, InetAddress add) throws IOException { this.port = port; - xmlrpc = new XmlRpcServer (); - accept = new Vector (); - deny = new Vector (); - threadpool = new Stack (); - runners = new ThreadGroup ("XML-RPC Runner"); + xmlrpc = new XmlRpcServer(); + accept = new Vector(); + deny = new Vector(); + threadpool = new Stack(); + runners = new ThreadGroup("XML-RPC Runner"); try { @@ -193,7 +196,7 @@ public void start() { - listener = new Thread (this, "XML-RPC Weblistener"); + listener = new Thread(this, "XML-RPC Weblistener"); listener.start(); } @@ -201,17 +204,17 @@ * Register a handler object with this name. Methods of this objects will be * callable over XML-RPC as "name.method". */ - public void addHandler (String name, Object target) + public void addHandler(String name, Object target) { - xmlrpc.addHandler (name, target); + xmlrpc.addHandler(name, target); } /** * Remove a handler object that was previously registered with this server. */ - public void removeHandler (String name) + public void removeHandler(String name) { - xmlrpc.removeHandler (name); + xmlrpc.removeHandler(name); } /** @@ -219,7 +222,7 @@ * @see acceptClient(java.lang.String) * @see denyClient(java.lang.String) */ - public void setParanoid (boolean p) + public void setParanoid(boolean p) { paranoid = p; } @@ -232,17 +235,19 @@ * @see denyClient(java.lang.String) * @see setParanoid(boolean) */ - public void acceptClient (String address) - throws IllegalArgumentException + public void acceptClient(String address) + throws IllegalArgumentException { try { - AddressMatcher m = new AddressMatcher (address); - accept.addElement (m); + AddressMatcher m = new AddressMatcher(address); + accept.addElement(m); } catch (Exception x) { - throw new IllegalArgumentException ("\""+address + "\" does not represent a valid IP address"); + throw new IllegalArgumentException("\"" + + address + + "\" does not represent a valid IP address"); } } @@ -254,35 +259,41 @@ * @see acceptClient(java.lang.String) * @see setParanoid(boolean) */ - public void denyClient (String address) throws IllegalArgumentException + public void denyClient(String address) throws IllegalArgumentException { try { - AddressMatcher m = new AddressMatcher (address); - deny.addElement (m); + AddressMatcher m = new AddressMatcher(address); + deny.addElement(m); } catch (Exception x) { - throw new IllegalArgumentException ("\""+address + "\" does not represent a valid IP address"); + throw new IllegalArgumentException("\"" + + address + + "\" does not represent a valid IP address"); } } - protected boolean checkSocket (Socket s) + protected boolean checkSocket(Socket s) { - int l = deny.size (); - byte address[] = s.getInetAddress ().getAddress (); + int l = deny.size(); + byte address[] = s.getInetAddress().getAddress(); for (int i = 0; i < l; i++) { - AddressMatcher match = (AddressMatcher) deny.elementAt (i); - if (match.matches (address)) + AddressMatcher match = (AddressMatcher)deny.elementAt(i); + if (match.matches(address)) + { return false; + } } - l = accept.size (); + l = accept.size(); for (int i = 0; i < l; i++) { - AddressMatcher match = (AddressMatcher) accept.elementAt (i); - if (match.matches (address)) + AddressMatcher match = (AddressMatcher)accept.elementAt(i); + if (match.matches(address)) + { return true; + } } return false; } @@ -299,14 +310,15 @@ try { Socket socket = serverSocket.accept(); - if (!paranoid || checkSocket (socket)) + if (!paranoid || checkSocket(socket)) { - Runner runner = getRunner (); + Runner runner = getRunner(); runner.handle (socket); - // new Connection (socket); } else - socket.close (); + { + socket.close(); + } } catch (InterruptedIOException checkState) { @@ -341,14 +353,15 @@ serverSocket = null; } catch (IOException ignore) - {} + { + } } } /** * Stop listening on the server port. */ - public void shutdown () + public void shutdown() { if (listener != null) { @@ -358,19 +371,19 @@ } } - - - protected Runner getRunner () + protected Runner getRunner() { try { - return (Runner) threadpool.pop (); + return (Runner)threadpool.pop(); } catch (EmptyStackException empty) { if (runners.activeCount () > 255) + { throw new RuntimeException ("System overload"); - return new Runner (); + } + return new Runner(); } } @@ -381,28 +394,27 @@ class Runner implements Runnable { - Thread thread; Connection con; int count; - public synchronized void handle (Socket socket) + public synchronized void handle(Socket socket) throws IOException { - con = new Connection (socket); + con = new Connection(socket); count = 0; if (thread == null || !thread.isAlive()) { - thread = new Thread (runners, this); - thread.start (); + thread = new Thread(runners, this); + thread.start(); } else { - this.notify (); + this.notify(); } } - public void run () + public void run() { while (Thread.currentThread () == thread) { @@ -411,14 +423,15 @@ con = null; if (count > 200 || threadpool.size() > 20) + { return; - - synchronized (this) + } + synchronized(this) { - releaseRunner (this); + releaseRunner(this); try { - this.wait (); + this.wait(); } catch (InterruptedException ir) { @@ -427,19 +440,15 @@ } } } - - } // end class Runner - + } class Connection implements Runnable { - private Socket socket; private BufferedInputStream input; private BufferedOutputStream output; - // private Thread responder; - private long lastRequest; private String user, password; + byte[] buffer; public Connection (Socket socket) throws IOException { @@ -447,13 +456,11 @@ socket.setSoTimeout (30000); this.socket = socket; - input = new BufferedInputStream (socket.getInputStream()); - output = new BufferedOutputStream (socket.getOutputStream()); - // responder = new Thread (this, "xmlrpc-worker"); - // responder.start(); + input = new BufferedInputStream(socket.getInputStream()); + output = new BufferedOutputStream(socket.getOutputStream()); } - public void run () + public void run() { try { @@ -463,43 +470,52 @@ { // reset user authentication user = password = null; - String line = readLine (); + String line = readLine(); // Netscape sends an extra \n\r after bodypart, swallow it - if ("".equals (line)) + if (line != null && line.length() == 0) + { line = readLine(); + } if (XmlRpc.debug) + { System.err.println (line); - // get time of last request - lastRequest = System.currentTimeMillis (); + } int contentLength = -1; // tokenize first line of HTTP request StringTokenizer tokens = new StringTokenizer(line); String method = tokens.nextToken(); - String uri = tokens.nextToken (); - String httpversion = tokens.nextToken (); - keepalive = XmlRpc.getKeepAlive() && "HTTP/1.1".equals (httpversion); + String uri = tokens.nextToken(); + String httpversion = tokens.nextToken(); + keepalive = XmlRpc.getKeepAlive() && HTTP_11.equals(httpversion); do { line = readLine(); if (line != null) { if (XmlRpc.debug) - System.err.println (line); - String lineLower = line.toLowerCase (); - if (lineLower.startsWith ("content-length:")) - contentLength = Integer.parseInt ( - line.substring (15).trim ()); - if (lineLower.startsWith ("connection:")) + { + System.err.println(line); + } + String lineLower = line.toLowerCase(); + if (lineLower.startsWith("content-length:")) + { + contentLength = Integer.parseInt( + line.substring(15).trim()); + } + if (lineLower.startsWith("connection:")) + { keepalive = XmlRpc.getKeepAlive() && lineLower.indexOf ("keep-alive") > -1; - if (lineLower.startsWith ("authorization: basic ")) + } + if (lineLower.startsWith("authorization: basic ")) + { parseAuth (line); + } } } - while (line != null && ! line.equals("")) - ; + while (line != null && line.length() != 0); if ("POST".equalsIgnoreCase (method)) { @@ -508,35 +524,38 @@ contentLength); byte result[] = xmlrpc.execute (sin, user, password); - output.write (httpversion.getBytes()); - output.write (ok); - output.write (server); + output.write(httpversion.getBytes()); + output.write(ok); + output.write(server); if (keepalive) - output.write (conkeep); + { + output.write(conkeep); + } else + { output.write (conclose); - output.write (ctype); - output.write (clength); - output.write ( Integer.toString ( + } + output.write(ctype); + output.write(clength); + output.write(Integer.toString( result.length).getBytes()); - output.write (doubleNewline); - output.write (result); - output.flush (); + output.write(doubleNewline); + output.write(result); + output.flush(); } else { - output.write (httpversion.getBytes()); - output.write (" 400 Bad Request\r\n".getBytes()); - output.write (server); - output.write ("\r\n".getBytes()); - output.write ( ("Method "+method + - " not implemented (try POST)"). getBytes()); - output.flush (); + output.write(httpversion.getBytes()); + output.write(" 400 Bad Request\r\n".getBytes()); + output.write(server); + output.write("\r\n".getBytes()); + output.write(("Method "+method + + " not implemented (try POST)").getBytes()); + output.flush(); keepalive = false; } } - while (keepalive) - ; + while (keepalive); } catch (Exception exception) { @@ -546,16 +565,22 @@ exception.printStackTrace (); } } - finally { try + finally + { + try { - socket.close(); + if (socket != null) + { + socket.close(); + } } catch (IOException ignore) - {} - } } + { + } + } + } - byte[] buffer; - private String readLine () throws IOException + private String readLine() throws IOException { if (buffer == null) { @@ -567,51 +592,63 @@ { next = input.read(); if (next < 0 || next == '\n') + { break; + } if (next != '\r') { buffer[count++] = (byte) next; } if (count >= 512) + { throw new IOException ("HTTP Header too long"); + } } return new String (buffer, 0, count); } - private void parseAuth (String line) + private void parseAuth(String line) { try { byte[] c = - Base64.decode (line.substring (21).toCharArray()); + Base64.decode (line.substring(21).getBytes()); String str = new String (c); - int col = str.indexOf (":"); + int col = str.indexOf (':'); user = str.substring (0, col); password = str.substring (col + 1); } catch (Throwable ignore) - {} + { + } } - } class AddressMatcher { int pattern[]; - + public AddressMatcher (String address) throws Exception { pattern = new int[4]; - StringTokenizer st = new StringTokenizer (address, "."); - if (st.countTokens () != 4) - throw new Exception ("\""+address + "\" does not represent a valid IP address"); + StringTokenizer st = new StringTokenizer(address, "."); + if (st.countTokens() != 4) + { + throw new Exception ("\"" + + address + + "\" does not represent a valid IP address"); + } for (int i = 0; i < 4; i++) { - String next = st.nextToken (); - if ("*".equals (next)) + String next = st.nextToken(); + if (STAR.equals(next)) + { pattern[i] = 256; + } else - pattern[i] = (byte) Integer.parseInt (next); + { + pattern[i] = (byte) Integer.parseInt(next); + } } } @@ -620,10 +657,13 @@ for (int i = 0; i < 4; i++) { if (pattern[i] > 255)// wildcard - + { continue; + } if (pattern[i] != address[i]) + { return false; + } } return true; } 1.18 +3 -2 xml-rpc/src/java/org/apache/xmlrpc/XmlRpc.java Index: XmlRpc.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/XmlRpc.java,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- XmlRpc.java 18 Feb 2002 23:22:29 -0000 1.17 +++ XmlRpc.java 19 Feb 2002 02:25:01 -0000 1.18 @@ -587,7 +587,7 @@ } break; case BASE64: - value = Base64.decode (cdata.toCharArray()); + value = Base64.decode (cdata.getBytes()); break; case STRING: value = cdata; @@ -700,7 +700,8 @@ else if (obj instanceof byte[]) { startElement("base64"); - write(Base64.encode((byte[]) obj)); + // FIXME: Yucky! Find a better way! + write(new String(Base64.encode((byte[]) obj)).toCharArray()); endElement("base64"); } else if (obj instanceof Vector) 1.7 +172 -144 xml-rpc/src/java/org/apache/xmlrpc/XmlRpcClient.java Index: XmlRpcClient.java =================================================================== RCS file: /home/cvs/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcClient.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- XmlRpcClient.java 18 Feb 2002 23:22:29 -0000 1.6 +++ XmlRpcClient.java 19 Feb 2002 02:25:01 -0000 1.7 @@ -4,7 +4,7 @@ * The Apache Software License, Version 1.1 * * - * Copyright (c) 2001 The Apache Software Foundation. All rights + * Copyright(c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -22,7 +22,7 @@ * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." + * Apache Software Foundation(http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * @@ -40,11 +40,11 @@ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== @@ -62,7 +62,7 @@ /** * A multithreaded, reusable XML-RPC client object. Use this if you need a full-grown - * HTTP client (e.g. for Proxy and Cookies support). If you don't need that, <code>XmlRpcClientLite</code> + * HTTP client(e.g. for Proxy and Cookies support). If you don't need that, <code>XmlRpcClientLite</code> * may work better for you. * * @author <a href="mailto:[EMAIL PROTECTED]">Hannes Wallnoefer</a> @@ -70,21 +70,21 @@ public class XmlRpcClient implements XmlRpcHandler { - URL url; - String auth; + protected URL url; + private String auth; // pool of worker instances - Stack pool = new Stack (); - int workers = 0; - int asyncWorkers = 0; + protected Stack pool = new Stack(); + protected int workers = 0; + protected int asyncWorkers = 0; // a queue of calls to be handled asynchronously - CallData first, last; + private CallData first, last; /** * Construct a XML-RPC client with this URL. */ - public XmlRpcClient (URL url) + public XmlRpcClient(URL url) { this.url = url; } @@ -92,24 +92,24 @@ /** * Construct a XML-RPC client for the URL represented by this String. */ - public XmlRpcClient (String url) throws MalformedURLException + public XmlRpcClient(String url) throws MalformedURLException { - this.url = new URL (url); + this.url = new URL(url); } /** * Construct a XML-RPC client for the specified hostname and port. */ - public XmlRpcClient (String hostname, + public XmlRpcClient(String hostname, int port) throws MalformedURLException { - this.url = new URL ("http://" + hostname + ':' + port + "/RPC2"); + this.url = new URL("http://" + hostname + ':' + port + "/RPC2"); } /** * Return the URL for this XML-RPC client. */ - public URL getURL () + public URL getURL() { return url; } @@ -118,15 +118,17 @@ * Sets Authentication for this client. This will be sent as Basic Authentication header * to the server as described in <a href="http://www.ietf.org/rfc/rfc2617.txt">http://www.ietf.org/rfc/rfc2617.txt</a>. */ - public void setBasicAuthentication (String user, String password) + public void setBasicAuthentication(String user, String password) { if (user == null || password == null) + { auth = null; + } else { - char[] basicAuth = - Base64.encode ((user + ":"+password).getBytes()); - auth = new String (basicAuth).trim(); + auth = new String( + Base64.encode((user + ':' + password) + .getBytes())).trim(); } } @@ -138,18 +140,18 @@ * @exception XmlRpcException: If the remote host returned a fault message. * @exception IOException: If the call could not be made because of lower level problems. */ - public Object execute (String method, + public Object execute(String method, Vector params) throws XmlRpcException, IOException { - Worker worker = getWorker (false); + Worker worker = getWorker(false); try { - Object retval = worker.execute (method, params); + Object retval = worker.execute(method, params); return retval; } finally { - releaseWorker (worker, false); + releaseWorker(worker, false); } } @@ -159,78 +161,93 @@ * If the callback parameter is not null, it will be called later to handle the result or error when the call is finished. * */ - public void executeAsync (String method, Vector params, - AsyncCallback callback) + public void executeAsync(String method, Vector params, + AsyncCallback callback) { // if at least 4 threads are running, don't create any new ones, - // just enqueue the request. + // just enqueue the request. if (asyncWorkers >= 4) { - enqueue (method, params, callback); + enqueue(method, params, callback); return; } Worker worker = null; try { - worker = getWorker (true); - worker.start (method, params, callback); + worker = getWorker(true); + worker.start(method, params, callback); } - catch (IOException iox) + catch(IOException iox) { // make a queued worker that doesn't run immediately - enqueue (method, params, callback); + enqueue(method, params, callback); } } - - synchronized Worker getWorker (boolean async) + synchronized Worker getWorker(boolean async) throws IOException { try { - Worker w = (Worker) pool.pop (); + Worker w =(Worker) pool.pop(); if (async) + { asyncWorkers += 1; + } else + { workers += 1; + } return w; } - catch (EmptyStackException x) + catch(EmptyStackException x) { if (workers < XmlRpc.getMaxThreads()) { if (async) + { asyncWorkers += 1; + } else + { workers += 1; - return new Worker (); + } + return new Worker(); } - throw new IOException ("XML-RPC System overload"); + throw new IOException("XML-RPC System overload"); } } /** * Release possibly big per-call object references to allow them to be garbage collected */ - synchronized void releaseWorker (Worker w, boolean async) + synchronized void releaseWorker(Worker w, boolean async) { w.result = null; w.call = null; if (pool.size() < 20 && !w.fault) - pool.push (w); + { + pool.push(w); + } if (async) + { asyncWorkers -= 1; + } else + { workers -= 1; + } } - synchronized void enqueue (String method, Vector params, + synchronized void enqueue(String method, Vector params, AsyncCallback callback) { - CallData call = new CallData (method, params, callback); + CallData call = new CallData(method, params, callback); if (last == null) + { first = last = call; + } else { last.next = call; @@ -238,15 +255,21 @@ } } - synchronized CallData dequeue () + synchronized CallData dequeue() { if (first == null) + { return null; + } CallData call = first; if (first == last) + { first = last = null; + } else + { first = first.next; + } return call; } @@ -262,52 +285,53 @@ CallData call; - public Worker () + public Worker() { - super (); + super(); } - public void start (String method, Vector params, + public void start(String method, Vector params, AsyncCallback callback) { - this.call = new CallData (method, params, callback); - Thread t = new Thread (this); - t.start (); + this.call = new CallData(method, params, callback); + Thread t = new Thread(this); + t.start(); } - public void run () + public void run() { while (call != null) { - executeAsync (call.method, call.params, call.callback); - call = dequeue (); + executeAsync(call.method, call.params, call.callback); + call = dequeue(); } - releaseWorker (this, true); + releaseWorker(this, true); } - /** * Execute an XML-RPC call and handle asyncronous callback. */ - void executeAsync (String method, Vector params, AsyncCallback callback) + void executeAsync(String method, Vector params, AsyncCallback callback) { Object res = null; try { - res = execute (method, params); + res = execute(method, params); // notify callback object if (callback != null) - callback.handleResult (res, url, method); + { + callback.handleResult(res, url, method); + } } - catch (Exception x) + catch(Exception x) { if (callback != null) { try { - callback.handleError (x, url, method); + callback.handleError(x, url, method); } - catch (Exception ignore) + catch(Exception ignore) { } } @@ -317,18 +341,23 @@ /** * Execute an XML-RPC call. */ - Object execute (String method, + Object execute(String method, Vector params) throws XmlRpcException, IOException { - if (debug) + fault = false; + long now = 0; + + if (XmlRpc.debug) + { System.err.println("Client calling procedure '" + method + "' with parameters " + params); - fault = false; - long now = System.currentTimeMillis (); + now = System.currentTimeMillis(); + } + try { - ByteArrayOutputStream bout = new ByteArrayOutputStream (); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); if (buffer == null) { @@ -339,33 +368,36 @@ buffer.reset(); } - XmlWriter writer = new XmlWriter (buffer); - writeRequest (writer, method, params); + XmlWriter writer = new XmlWriter(buffer); + writeRequest(writer, method, params); writer.flush(); byte[] request = buffer.toByteArray(); - URLConnection con = url.openConnection (); - con.setDoInput (true); - con.setDoOutput (true); - con.setUseCaches (false); + URLConnection con = url.openConnection(); + con.setDoInput(true); + con.setDoOutput(true); + con.setUseCaches(false); con.setAllowUserInteraction(false); - con.setRequestProperty ("Content-Length", - Integer.toString (request.length)); - con.setRequestProperty ("Content-Type", "text/xml"); + con.setRequestProperty("Content-Length", + Integer.toString(request.length)); + con.setRequestProperty("Content-Type", "text/xml"); if (auth != null) - con.setRequestProperty ("Authorization", "Basic "+auth); - // con.connect (); - OutputStream out = con.getOutputStream (); - out.write (request); - out.flush (); - InputStream in = con.getInputStream (); - parse (in); - } - catch (Exception x) - { - if (debug) - x.printStackTrace (); - throw new IOException (x.getMessage ()); + { + con.setRequestProperty("Authorization", "Basic " + auth); + } + OutputStream out = con.getOutputStream(); + out.write(request); + out.flush(); + InputStream in = con.getInputStream(); + parse(in); + } + catch(Exception x) + { + if (XmlRpc.debug) + { + x.printStackTrace(); + } + throw new IOException(x.getMessage()); } if (fault) { @@ -373,78 +405,76 @@ XmlRpcException exception = null; try { - Hashtable f = (Hashtable) result; - String faultString = (String) f.get ("faultString"); - int faultCode = Integer.parseInt ( - f.get ("faultCode").toString ()); - exception = new XmlRpcException (faultCode, - faultString.trim ()); + Hashtable f =(Hashtable) result; + String faultString =(String) f.get("faultString"); + int faultCode = Integer.parseInt( + f.get("faultCode").toString()); + exception = new XmlRpcException(faultCode, + faultString.trim()); } - catch (Exception x) + catch(Exception x) { - throw new XmlRpcException (0, "Invalid fault response"); + throw new XmlRpcException(0, "Invalid fault response"); } throw exception; } - if (debug) - System.err.println ("Spent "+ - (System.currentTimeMillis () - now) + " in request"); + if (XmlRpc.debug) + { + System.err.println("Spent "+ + (System.currentTimeMillis() - now) + " in request"); + } return result; } - /** * Called when the return value has been parsed. */ - void objectParsed (Object what) + void objectParsed(Object what) { result = what; } - /** * Generate an XML-RPC request from a method name and a parameter vector. */ - void writeRequest (XmlWriter writer, String method, + void writeRequest(XmlWriter writer, String method, Vector params) throws IOException, XmlRpcException { - writer.startElement ("methodCall"); - - writer.startElement ("methodName"); - writer.write (method); - writer.endElement ("methodName"); - - writer.startElement ("params"); - int l = params.size (); + writer.startElement("methodCall"); + writer.startElement("methodName"); + writer.write(method); + writer.endElement("methodName"); + writer.startElement("params"); + int l = params.size(); for (int i = 0; i < l; i++) { - writer.startElement ("param"); - writer.writeObject (params.elementAt (i)); - writer.endElement ("param"); + writer.startElement("param"); + writer.writeObject(params.elementAt(i)); + writer.endElement("param"); } - writer.endElement ("params"); - writer.endElement ("methodCall"); + writer.endElement("params"); + writer.endElement("methodCall"); } /** * Overrides method in XmlRpc to handle fault repsonses. */ - public void startElement (String name, + public void startElement(String name, AttributeList atts) throws SAXException { - if ("fault".equals (name)) + if ("fault".equals(name)) + { fault = true; + } else - super.startElement (name, atts); + { + super.startElement(name, atts); + } } - - } // end of inner class Worker - class CallData { - String method; Vector params; AsyncCallback callback; @@ -453,7 +483,7 @@ /** * Make a call to be queued and then executed by the next free async thread */ - public CallData (String method, Vector params, + public CallData(String method, Vector params, AsyncCallback callback) { this.method = method; @@ -461,49 +491,47 @@ this.callback = callback; this.next = null; } - } - /** * Just for testing. */ - public static void main (String args[]) throws Exception + public static void main(String args[]) throws Exception { - // XmlRpc.setDebug (true); - // XmlRpc.setKeepAlive (true); + // XmlRpc.setDebug(true); + // XmlRpc.setKeepAlive(true); try { String url = args[0]; String method = args[1]; - Vector v = new Vector (); + Vector v = new Vector(); for (int i = 2; i < args.length; i++) + { try { - v.addElement ( - new Integer (Integer.parseInt (args[i]))); + v.addElement( + new Integer(Integer.parseInt(args[i]))); } - catch (NumberFormatException nfx) + catch(NumberFormatException nfx) { - v.addElement (args[i]); + v.addElement(args[i]); } - XmlRpcClient client = new XmlRpcClientLite (url); + } + XmlRpcClient client = new XmlRpcClientLite(url); try { - System.err.println (client.execute (method, v)); + System.err.println(client.execute(method, v)); } - catch (Exception ex) + catch(Exception ex) { - System.err.println ("Error: "+ex.getMessage()); + System.err.println("Error: " + ex.getMessage()); } } - catch (Exception x) + catch(Exception x) { - System.err.println (x); - System.err.println ("Usage: java org.apache.xmlrpc.XmlRpcClient <url> <method> <arg> ...."); - System.err.println ("Arguments are sent as integers or strings."); + System.err.println(x); + System.err.println("Usage: java org.apache.xmlrpc.XmlRpcClient <url> <method> <arg> ...."); + System.err.println("Arguments are sent as integers or strings."); } } } - -