diff --git a/LifeBlogger.iml b/LifeBlogger.iml index ce87db1..4054451 100644 --- a/LifeBlogger.iml +++ b/LifeBlogger.iml @@ -37,6 +37,15 @@ + + + + + + + + + diff --git a/LifeBlogger.ipr b/LifeBlogger.ipr index c5c0ee3..f97a3bd 100644 --- a/LifeBlogger.ipr +++ b/LifeBlogger.ipr @@ -11,7 +11,7 @@ - + diff --git a/LifeBlogger.jnlp b/LifeBlogger.jnlp index 9dbfdc8..c0716b7 100644 --- a/LifeBlogger.jnlp +++ b/LifeBlogger.jnlp @@ -19,6 +19,7 @@ + diff --git a/build.properties b/build.properties index bca7f35..69655f9 100644 --- a/build.properties +++ b/build.properties @@ -1,6 +1,6 @@ # Project proj.name=LifeBlogger -proj.version=0.1.2 +proj.version=0.2 proj.package=net.thauvin.lifeblogger proj.run=${proj.package}.LifeBlogger diff --git a/lib/xmlrpc-1.1.jar b/lib/xmlrpc-1.1.jar new file mode 100644 index 0000000..b360b03 Binary files /dev/null and b/lib/xmlrpc-1.1.jar differ diff --git a/licenses/commons.txt b/licenses/apache.txt similarity index 100% rename from licenses/commons.txt rename to licenses/apache.txt diff --git a/licenses/base64.txt b/licenses/base64.txt deleted file mode 100644 index 5640118..0000000 --- a/licenses/base64.txt +++ /dev/null @@ -1,8 +0,0 @@ -I am placing this code in the Public Domain. Do with it as you will. -This software comes with no guarantees or warranties but with -plenty of well-wishing instead! -Please visit http://iharder.net/base64 -periodically to check for updates or to contribute improvements. - -Robert Harder -rob@iharder.net \ No newline at end of file diff --git a/src/net/thauvin/lifeblogger/Base64.java b/src/net/thauvin/lifeblogger/Base64.java deleted file mode 100644 index 59835da..0000000 --- a/src/net/thauvin/lifeblogger/Base64.java +++ /dev/null @@ -1,1451 +0,0 @@ -package net.thauvin.lifeblogger; - -/** - * Encodes and decodes to and from Base64 notation. - * - *

- * Change Log: - *

- *
    - *
  • v2.1 - Cleaned up javadoc comments and unused variables and methods. Added - * some convenience methods for reading and writing to and from files.
  • - *
  • v2.0.2 - Now specifies UTF-8 encoding in places where the code fails on systems - * with other encodings (like EBCDIC).
  • - *
  • v2.0.1 - Fixed an error when decoding a single byte, that is, when the - * encoded data was a single byte.
  • - *
  • v2.0 - I got rid of methods that used booleans to set options. - * Now everything is more consolidated and cleaner. The code now detects - * when data that's being decoded is gzip-compressed and will decompress it - * automatically. Generally things are cleaner. You'll probably have to - * change some method calls that you were making to support the new - * options format (ints that you "OR" together).
  • - *
  • v1.5.1 - Fixed bug when decompressing and decoding to a - * byte[] using decode( String s, boolean gzipCompressed ). - * Added the ability to "suspend" encoding in the Output Stream so - * you can turn on and off the encoding if you need to embed base64 - * data in an otherwise "normal" stream (like an XML file).
  • - *
  • v1.5 - Output stream pases on flush() command but doesn't do anything itself. - * This helps when using GZIP streams. - * Added the ability to GZip-compress objects before encoding them.
  • - *
  • v1.4 - Added helper methods to read/write files.
  • - *
  • v1.3.6 - Fixed OutputStream.flush() so that 'position' is reset.
  • - *
  • v1.3.5 - Added flag to turn on and off line breaks. Fixed bug in input stream - * where last buffer being read, if not completely full, was not returned.
  • - *
  • v1.3.4 - Fixed when "improperly padded stream" error was thrown at the wrong time.
  • - *
  • v1.3.3 - Fixed I/O streams which were totally messed up.
  • - *
- * - *

- * I am placing this code in the Public Domain. Do with it as you will. - * This software comes with no guarantees or warranties but with - * plenty of well-wishing instead! - * Please visit http://iharder.net/base64 - * periodically to check for updates or to contribute improvements. - *

- * - * @author Robert Harder - * @author rob@iharder.net - * @version 2.1 - */ -public class Base64 -{ - -/* ******** P U B L I C F I E L D S ******** */ - - - /** No options specified. Value is zero. */ - public final static int NO_OPTIONS = 0; - - /** Specify encoding. */ - public final static int ENCODE = 1; - - - /** Specify decoding. */ - public final static int DECODE = 0; - - - /** Specify that data should be gzip-compressed. */ - public final static int GZIP = 2; - - - /** Don't break lines when encoding (violates strict Base64 specification) */ - public final static int DONT_BREAK_LINES = 8; - - -/* ******** P R I V A T E F I E L D S ******** */ - - - /** Maximum line length (76) of Base64 output. */ - private final static int MAX_LINE_LENGTH = 76; - - - /** The equals sign (=) as a byte. */ - private final static byte EQUALS_SIGN = (byte)'='; - - - /** The new line character (\n) as a byte. */ - private final static byte NEW_LINE = (byte)'\n'; - - - /** Preferred encoding. */ - private final static String PREFERRED_ENCODING = "UTF-8"; - - - /** The 64 valid Base64 values. */ - private final static byte[] ALPHABET; - private final static byte[] _NATIVE_ALPHABET = /* May be something funny like EBCDIC */ - { - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', (byte)'w', (byte)'x', (byte)'y', (byte)'z', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', - (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/' - }; - - /** Determine which ALPHABET to use. */ - static - { - byte[] __bytes; - try - { - __bytes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".getBytes( PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException use) - { - __bytes = _NATIVE_ALPHABET; // Fall back to native encoding - } // end catch - ALPHABET = __bytes; - } // end static - - - /** - * Translates a Base64 value to either its 6-bit reconstruction value - * or a negative number indicating some other meaning. - **/ - private final static byte[] DECODABET = - { - -9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 0 - 8 - -5,-5, // Whitespace: Tab and Linefeed - -9,-9, // Decimal 11 - 12 - -5, // Whitespace: Carriage Return - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 14 - 26 - -9,-9,-9,-9,-9, // Decimal 27 - 31 - -5, // Whitespace: Space - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 33 - 42 - 62, // Plus sign at decimal 43 - -9,-9,-9, // Decimal 44 - 46 - 63, // Slash at decimal 47 - 52,53,54,55,56,57,58,59,60,61, // Numbers zero through nine - -9,-9,-9, // Decimal 58 - 60 - -1, // Equals sign at decimal 61 - -9,-9,-9, // Decimal 62 - 64 - 0,1,2,3,4,5,6,7,8,9,10,11,12,13, // Letters 'A' through 'N' - 14,15,16,17,18,19,20,21,22,23,24,25, // Letters 'O' through 'Z' - -9,-9,-9,-9,-9,-9, // Decimal 91 - 96 - 26,27,28,29,30,31,32,33,34,35,36,37,38, // Letters 'a' through 'm' - 39,40,41,42,43,44,45,46,47,48,49,50,51, // Letters 'n' through 'z' - -9,-9,-9,-9 // Decimal 123 - 126 - /*,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 127 - 139 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 140 - 152 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 153 - 165 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 166 - 178 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 179 - 191 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 192 - 204 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 205 - 217 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 218 - 230 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9, // Decimal 231 - 243 - -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 // Decimal 244 - 255 */ - }; - - // I think I end up not using the BAD_ENCODING indicator. - //private final static byte BAD_ENCODING = -9; // Indicates error in encoding - private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding - private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding - - - /** Defeats instantiation. */ - private Base64(){} - - - -/* ******** E N C O D I N G M E T H O D S ******** */ - - - /** - * Encodes up to the first three bytes of array threeBytes - * and returns a four-byte array in Base64 notation. - * The actual number of significant bytes in your array is - * given by numSigBytes. - * The array threeBytes needs only be as big as - * numSigBytes. - * Code can reuse a byte array by passing a four-byte array as b4. - * - * @param b4 A reusable byte array to reduce array instantiation - * @param threeBytes the array to convert - * @param numSigBytes the number of significant bytes in your array - * @return four byte array in Base64 notation. - * @since 1.5.1 - */ - private static byte[] encode3to4( byte[] b4, byte[] threeBytes, int numSigBytes ) - { - encode3to4( threeBytes, 0, numSigBytes, b4, 0 ); - return b4; - } // end encode3to4 - - - /** - * Encodes up to three bytes of the array source - * and writes the resulting four Base64 bytes to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 3 for - * the source array or destOffset + 4 for - * the destination array. - * The actual number of significant bytes in your array is - * given by numSigBytes. - * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param numSigBytes the number of significant bytes in your array - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @return the destination array - * @since 1.3 - */ - private static byte[] encode3to4( - byte[] source, int srcOffset, int numSigBytes, - byte[] destination, int destOffset ) - { - // 1 2 3 - // 01234567890123456789012345678901 Bit position - // --------000000001111111122222222 Array position from threeBytes - // --------| || || || | Six bit groups to index ALPHABET - // >>18 >>12 >> 6 >> 0 Right shift necessary - // 0x3f 0x3f 0x3f Additional AND - - // Create buffer with zero-padding if there are only one or two - // significant bytes passed in the array. - // We have to shift left 24 in order to flush out the 1's that appear - // when Java treats a value as negative that is cast from a byte to an int. - int inBuff = ( numSigBytes > 0 ? ((source[ srcOffset ] << 24) >>> 8) : 0 ) - | ( numSigBytes > 1 ? ((source[ srcOffset + 1 ] << 24) >>> 16) : 0 ) - | ( numSigBytes > 2 ? ((source[ srcOffset + 2 ] << 24) >>> 24) : 0 ); - - switch( numSigBytes ) - { - case 3: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = ALPHABET[ (inBuff ) & 0x3f ]; - return destination; - - case 2: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = ALPHABET[ (inBuff >>> 6) & 0x3f ]; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - case 1: - destination[ destOffset ] = ALPHABET[ (inBuff >>> 18) ]; - destination[ destOffset + 1 ] = ALPHABET[ (inBuff >>> 12) & 0x3f ]; - destination[ destOffset + 2 ] = EQUALS_SIGN; - destination[ destOffset + 3 ] = EQUALS_SIGN; - return destination; - - default: - return destination; - } // end switch - } // end encode3to4 - - - - /** - * Serializes an object and returns the Base64-encoded - * version of that serialized object. If the object - * cannot be serialized or there is another error, - * the method will return null. - * The object is not GZip-compressed before being encoded. - * - * @param serializableObject The object to encode - * @return The Base64-encoded object - * @since 1.4 - */ - public static String encodeObject( java.io.Serializable serializableObject ) - { - return encodeObject( serializableObject, NO_OPTIONS ); - } // end encodeObject - - - - /** - * Serializes an object and returns the Base64-encoded - * version of that serialized object. If the object - * cannot be serialized or there is another error, - * the method will return null. - *

- * Valid options:

-     *   GZIP: gzip-compresses object before encoding it.
-     *   DONT_BREAK_LINES: don't break lines at 76 characters
-     *     Note: Technically, this makes your encoding non-compliant.
-     * 
- *

- * Example: encodeObject( myObj, Base64.GZIP ) or - *

- * Example: encodeObject( myObj, Base64.GZIP | Base64.DONT_BREAK_LINES ) - * - * @param serializableObject The object to encode - * @param options Specified options - * @return The Base64-encoded object - * @see Base64#GZIP - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public static String encodeObject( java.io.Serializable serializableObject, int options ) - { - // Streams - java.io.ByteArrayOutputStream baos = null; - java.io.OutputStream b64os = null; - java.io.ObjectOutputStream oos = null; - java.util.zip.GZIPOutputStream gzos = null; - - // Isolate options - int gzip = (options & GZIP); - int dontBreakLines = (options & DONT_BREAK_LINES); - - try - { - // ObjectOutputStream -> (GZIP) -> Base64 -> ByteArrayOutputStream - baos = new java.io.ByteArrayOutputStream(); - b64os = new Base64.OutputStream( baos, ENCODE | dontBreakLines ); - - // GZip? - if( gzip == GZIP ) - { - gzos = new java.util.zip.GZIPOutputStream( b64os ); - oos = new java.io.ObjectOutputStream( gzos ); - } // end if: gzip - else - oos = new java.io.ObjectOutputStream( b64os ); - - oos.writeObject( serializableObject ); - } // end try - catch( java.io.IOException e ) - { - e.printStackTrace(); - return null; - } // end catch - finally - { - try{ oos.close(); } catch( Exception e ){} - try{ gzos.close(); } catch( Exception e ){} - try{ b64os.close(); } catch( Exception e ){} - try{ baos.close(); } catch( Exception e ){} - } // end finally - - // Return value according to relevant encoding. - try - { - return new String( baos.toByteArray(), PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue) - { - return new String( baos.toByteArray() ); - } // end catch - - } // end encode - - - - /** - * Encodes a byte array into Base64 notation. - * Does not GZip-compress data. - * - * @param source The data to convert - * @since 1.4 - */ - public static String encodeBytes( byte[] source ) - { - return encodeBytes( source, 0, source.length, NO_OPTIONS ); - } // end encodeBytes - - - - /** - * Encodes a byte array into Base64 notation. - *

- * Valid options:

-     *   GZIP: gzip-compresses object before encoding it.
-     *   DONT_BREAK_LINES: don't break lines at 76 characters
-     *     Note: Technically, this makes your encoding non-compliant.
-     * 
- *

- * Example: encodeBytes( myData, Base64.GZIP ) or - *

- * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) - * - * - * @param source The data to convert - * @param options Specified options - * @see Base64#GZIP - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public static String encodeBytes( byte[] source, int options ) - { - return encodeBytes( source, 0, source.length, options ); - } // end encodeBytes - - - /** - * Encodes a byte array into Base64 notation. - * Does not GZip-compress data. - * - * @param source The data to convert - * @param off Offset in array where conversion should begin - * @param len Length of data to convert - * @since 1.4 - */ - public static String encodeBytes( byte[] source, int off, int len ) - { - return encodeBytes( source, off, len, NO_OPTIONS ); - } // end encodeBytes - - - - /** - * Encodes a byte array into Base64 notation. - *

- * Valid options:

-     *   GZIP: gzip-compresses object before encoding it.
-     *   DONT_BREAK_LINES: don't break lines at 76 characters
-     *     Note: Technically, this makes your encoding non-compliant.
-     * 
- *

- * Example: encodeBytes( myData, Base64.GZIP ) or - *

- * Example: encodeBytes( myData, Base64.GZIP | Base64.DONT_BREAK_LINES ) - * - * - * @param source The data to convert - * @param off Offset in array where conversion should begin - * @param len Length of data to convert - * @param options Specified options - * @see Base64#GZIP - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public static String encodeBytes( byte[] source, int off, int len, int options ) - { - // Isolate options - int dontBreakLines = ( options & DONT_BREAK_LINES ); - int gzip = ( options & GZIP ); - - // Compress? - if( gzip == GZIP ) - { - java.io.ByteArrayOutputStream baos = null; - java.util.zip.GZIPOutputStream gzos = null; - Base64.OutputStream b64os = null; - - - try - { - // GZip -> Base64 -> ByteArray - baos = new java.io.ByteArrayOutputStream(); - b64os = new Base64.OutputStream( baos, ENCODE | dontBreakLines ); - gzos = new java.util.zip.GZIPOutputStream( b64os ); - - gzos.write( source, off, len ); - gzos.close(); - } // end try - catch( java.io.IOException e ) - { - e.printStackTrace(); - return null; - } // end catch - finally - { - try{ gzos.close(); } catch( Exception e ){} - try{ b64os.close(); } catch( Exception e ){} - try{ baos.close(); } catch( Exception e ){} - } // end finally - - // Return value according to relevant encoding. - try - { - return new String( baos.toByteArray(), PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue) - { - return new String( baos.toByteArray() ); - } // end catch - } // end if: compress - - // Else, don't compress. Better not to use streams at all then. - else - { - // Convert option to boolean in way that code likes it. - boolean breakLines = dontBreakLines == 0; - - int len43 = len * 4 / 3; - byte[] outBuff = new byte[ ( len43 ) // Main 4:3 - + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding - + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines - int d = 0; - int e = 0; - int len2 = len - 2; - int lineLength = 0; - for( ; d < len2; d+=3, e+=4 ) - { - encode3to4( source, d+off, 3, outBuff, e ); - - lineLength += 4; - if( breakLines && lineLength == MAX_LINE_LENGTH ) - { - outBuff[e+4] = NEW_LINE; - e++; - lineLength = 0; - } // end if: end of line - } // en dfor: each piece of array - - if( d < len ) - { - encode3to4( source, d+off, len - d, outBuff, e ); - e += 4; - } // end if: some padding needed - - - // Return value according to relevant encoding. - try - { - return new String( outBuff, 0, e, PREFERRED_ENCODING ); - } // end try - catch (java.io.UnsupportedEncodingException uue) - { - return new String( outBuff, 0, e ); - } // end catch - - } // end else: don't compress - - } // end encodeBytes - - - - - -/* ******** D E C O D I N G M E T H O D S ******** */ - - - /** - * Decodes four bytes from array source - * and writes the resulting bytes (up to three of them) - * to destination. - * The source and destination arrays can be manipulated - * anywhere along their length by specifying - * srcOffset and destOffset. - * This method does not check to make sure your arrays - * are large enough to accomodate srcOffset + 4 for - * the source array or destOffset + 3 for - * the destination array. - * This method returns the actual number of bytes that - * were converted from the Base64 encoding. - * - * - * @param source the array to convert - * @param srcOffset the index where conversion begins - * @param destination the array to hold the conversion - * @param destOffset the index where output will be put - * @return the number of decoded bytes converted - * @since 1.3 - */ - private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset ) - { - // Example: Dk== - if( source[ srcOffset + 2] == EQUALS_SIGN ) - { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1] ] & 0xFF ) << 12 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - return 1; - } - - // Example: DkL= - else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) - { - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6 ); - - destination[ destOffset ] = (byte)( outBuff >>> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); - return 2; - } - - // Example: DkLE - else - { - try{ - // Two ways to do the same thing. Don't know which way I like best. - //int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) - // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) - // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) - // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); - int outBuff = ( ( DECODABET[ source[ srcOffset ] ] & 0xFF ) << 18 ) - | ( ( DECODABET[ source[ srcOffset + 1 ] ] & 0xFF ) << 12 ) - | ( ( DECODABET[ source[ srcOffset + 2 ] ] & 0xFF ) << 6) - | ( ( DECODABET[ source[ srcOffset + 3 ] ] & 0xFF ) ); - - - destination[ destOffset ] = (byte)( outBuff >> 16 ); - destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); - destination[ destOffset + 2 ] = (byte)( outBuff ); - - return 3; - }catch( Exception e){ - System.out.println(""+source[srcOffset]+ ": " + ( DECODABET[ source[ srcOffset ] ] ) ); - System.out.println(""+source[srcOffset+1]+ ": " + ( DECODABET[ source[ srcOffset + 1 ] ] ) ); - System.out.println(""+source[srcOffset+2]+ ": " + ( DECODABET[ source[ srcOffset + 2 ] ] ) ); - System.out.println(""+source[srcOffset+3]+ ": " + ( DECODABET[ source[ srcOffset + 3 ] ] ) ); - return -1; - } //e nd catch - } - } // end decodeToBytes - - - - - /** - * Very low-level access to decoding ASCII characters in - * the form of a byte array. Does not support automatically - * gunzipping or any other "fancy" features. - * - * @param source The Base64 encoded data - * @param off The offset of where to begin decoding - * @param len The length of characters to decode - * @return decoded data - * @since 1.3 - */ - public static byte[] decode( byte[] source, int off, int len ) - { - int len34 = len * 3 / 4; - byte[] outBuff = new byte[ len34 ]; // Upper limit on size of output - int outBuffPosn = 0; - - byte[] b4 = new byte[4]; - int b4Posn = 0; - int i = 0; - byte sbiCrop = 0; - byte sbiDecode = 0; - for( i = off; i < off+len; i++ ) - { - sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits - sbiDecode = DECODABET[ sbiCrop ]; - - if( sbiDecode >= WHITE_SPACE_ENC ) // White space, Equals sign or better - { - if( sbiDecode >= EQUALS_SIGN_ENC ) - { - b4[ b4Posn++ ] = sbiCrop; - if( b4Posn > 3 ) - { - outBuffPosn += decode4to3( b4, 0, outBuff, outBuffPosn ); - b4Posn = 0; - - // If that was the equals sign, break out of 'for' loop - if( sbiCrop == EQUALS_SIGN ) - break; - } // end if: quartet built - - } // end if: equals sign or better - - } // end if: white space, equals sign or better - else - { - System.err.println( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)" ); - return null; - } // end else: - } // each input character - - byte[] out = new byte[ outBuffPosn ]; - System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); - return out; - } // end decode - - - - - /** - * Decodes data from Base64 notation, automatically - * detecting gzip-compressed data and decompressing it. - * - * @param s the string to decode - * @return the decoded data - * @since 1.4 - */ - public static byte[] decode( String s ) - { - byte[] bytes; - try - { - bytes = s.getBytes( PREFERRED_ENCODING ); - } // end try - catch( java.io.UnsupportedEncodingException uee ) - { - bytes = s.getBytes(); - } // end catch - // - - // Decode - bytes = decode( bytes, 0, bytes.length ); - - - // Check to see if it's gzip-compressed - // GZIP Magic Two-Byte Number: 0x8b1f (35615) - if( bytes != null && bytes.length >= 4 ) - { - - int head = ((int)bytes[0] & 0xff) | ((bytes[1] << 8) & 0xff00); - if( java.util.zip.GZIPInputStream.GZIP_MAGIC == head ) - { - java.io.ByteArrayInputStream bais = null; - java.util.zip.GZIPInputStream gzis = null; - java.io.ByteArrayOutputStream baos = null; - byte[] buffer = new byte[2048]; - int length = 0; - - try - { - baos = new java.io.ByteArrayOutputStream(); - bais = new java.io.ByteArrayInputStream( bytes ); - gzis = new java.util.zip.GZIPInputStream( bais ); - - while( ( length = gzis.read( buffer ) ) >= 0 ) - { - baos.write(buffer,0,length); - } // end while: reading input - - // No error? Get new bytes. - bytes = baos.toByteArray(); - - } // end try - catch( java.io.IOException e ) - { - // Just return originally-decoded bytes - } // end catch - finally - { - try{ baos.close(); } catch( Exception e ){} - try{ gzis.close(); } catch( Exception e ){} - try{ bais.close(); } catch( Exception e ){} - } // end finally - - } // end if: gzipped - } // end if: bytes.length >= 2 - - return bytes; - } // end decode - - - - - /** - * Attempts to decode Base64 data and deserialize a Java - * Object within. Returns null if there was an error. - * - * @param encodedObject The Base64 data to decode - * @return The decoded and deserialized object - * @since 1.5 - */ - public static Object decodeToObject( String encodedObject ) - { - // Decode and gunzip if necessary - byte[] objBytes = decode( encodedObject ); - - java.io.ByteArrayInputStream bais = null; - java.io.ObjectInputStream ois = null; - Object obj = null; - - try - { - bais = new java.io.ByteArrayInputStream( objBytes ); - ois = new java.io.ObjectInputStream( bais ); - - obj = ois.readObject(); - } // end try - catch( java.io.IOException e ) - { - e.printStackTrace(); - obj = null; - } // end catch - catch( java.lang.ClassNotFoundException e ) - { - e.printStackTrace(); - obj = null; - } // end catch - finally - { - try{ bais.close(); } catch( Exception e ){} - try{ ois.close(); } catch( Exception e ){} - } // end finally - - return obj; - } // end decodeObject - - - - /** - * Convenience method for encoding data to a file. - * - * @param dataToEncode byte array of data to encode in base64 form - * @param filename Filename for saving encoded data - * @return true if successful, false otherwise - * - * @since 2.1 - */ - public static boolean encodeToFile( byte[] dataToEncode, String filename ) - { - boolean success = false; - Base64.OutputStream bos = null; - try - { - bos = new Base64.OutputStream( - new java.io.FileOutputStream( filename ), Base64.ENCODE ); - bos.write( dataToEncode ); - success = true; - } // end try - catch( java.io.IOException e ) - { - - success = false; - } // end catch: IOException - finally - { - try{ bos.close(); } catch( Exception e ){} - } // end finally - - return success; - } // end encodeToFile - - - /** - * Convenience method for decoding data to a file. - * - * @param dataToDecode Base64-encoded data as a string - * @param filename Filename for saving decoded data - * @return true if successful, false otherwise - * - * @since 2.1 - */ - public static boolean decodeToFile( String dataToDecode, String filename ) - { - boolean success = false; - Base64.OutputStream bos = null; - try - { - bos = new Base64.OutputStream( - new java.io.FileOutputStream( filename ), Base64.DECODE ); - bos.write( dataToDecode.getBytes( PREFERRED_ENCODING ) ); - success = true; - } // end try - catch( java.io.IOException e ) - { - success = false; - } // end catch: IOException - finally - { - try{ bos.close(); } catch( Exception e ){} - } // end finally - - return success; - } // end decodeToFile - - - - - /** - * Convenience method for reading a base64-encoded - * file and decoding it. - * - * @param filename Filename for reading encoded data - * @return decoded byte array or null if unsuccessful - * - * @since 2.1 - */ - public static byte[] decodeFromFile( String filename ) - { - byte[] decodedData = null; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer = null; - int length = 0; - int numBytes = 0; - - // Check for size of file - if( file.length() > Integer.MAX_VALUE ) - { - System.err.println( "File is too big for this convenience method (" + file.length() + " bytes)." ); - return null; - } // end if: file too big for int index - buffer = new byte[ (int)file.length() ]; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.DECODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) - length += numBytes; - - // Save in a variable to return - decodedData = new byte[ length ]; - System.arraycopy( buffer, 0, decodedData, 0, length ); - - } // end try - catch( java.io.IOException e ) - { - System.err.println( "Error decoding from file " + filename ); - } // end catch: IOException - finally - { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return decodedData; - } // end decodeFromFile - - - - /** - * Convenience method for reading a binary file - * and base64-encoding it. - * - * @param filename Filename for reading binary data - * @return base64-encoded string or null if unsuccessful - * - * @since 2.1 - */ - public static String encodeFromFile( String filename ) - { - String encodedData = null; - Base64.InputStream bis = null; - try - { - // Set up some useful variables - java.io.File file = new java.io.File( filename ); - byte[] buffer = new byte[ (int)(file.length() * 1.4) ]; - int length = 0; - int numBytes = 0; - - // Open a stream - bis = new Base64.InputStream( - new java.io.BufferedInputStream( - new java.io.FileInputStream( file ) ), Base64.ENCODE ); - - // Read until done - while( ( numBytes = bis.read( buffer, length, 4096 ) ) >= 0 ) - length += numBytes; - - // Save in a variable to return - encodedData = new String( buffer, 0, length, Base64.PREFERRED_ENCODING ); - - } // end try - catch( java.io.IOException e ) - { - System.err.println( "Error encoding from file " + filename ); - } // end catch: IOException - finally - { - try{ bis.close(); } catch( Exception e) {} - } // end finally - - return encodedData; - } // end encodeFromFile - - - - - /* ******** I N N E R C L A S S I N P U T S T R E A M ******** */ - - - - /** - * A {@link Base64.InputStream} will read data from another - * java.io.InputStream, given in the constructor, - * and encode/decode to/from Base64 notation on the fly. - * - * @see Base64 - * @since 1.3 - */ - public static class InputStream extends java.io.FilterInputStream - { - private boolean encode; // Encoding or decoding - private int position; // Current position in the buffer - private byte[] buffer; // Small buffer holding converted data - private int bufferLength; // Length of buffer (3 or 4) - private int numSigBytes; // Number of meaningful bytes in the buffer - private int lineLength; - private boolean breakLines; // Break lines at less than 80 characters - - - /** - * Constructs a {@link Base64.InputStream} in DECODE mode. - * - * @param in the java.io.InputStream from which to read data. - * @since 1.3 - */ - public InputStream( java.io.InputStream in ) - { - this( in, DECODE ); - } // end constructor - - - /** - * Constructs a {@link Base64.InputStream} in - * either ENCODE or DECODE mode. - *

- * Valid options:

-         *   ENCODE or DECODE: Encode or Decode as data is read.
-         *   DONT_BREAK_LINES: don't break lines at 76 characters
-         *     (only meaningful when encoding)
-         *     Note: Technically, this makes your encoding non-compliant.
-         * 
- *

- * Example: new Base64.InputStream( in, Base64.DECODE ) - * - * - * @param in the java.io.InputStream from which to read data. - * @param options Specified options - * @see Base64#ENCODE - * @see Base64#DECODE - * @see Base64#DONT_BREAK_LINES - * @since 2.0 - */ - public InputStream( java.io.InputStream in, int options ) - { - super( in ); - this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; - this.encode = (options & ENCODE) == ENCODE; - this.bufferLength = encode ? 4 : 3; - this.buffer = new byte[ bufferLength ]; - this.position = -1; - this.lineLength = 0; - } // end constructor - - /** - * Reads enough of the input stream to convert - * to/from Base64 and returns the next byte. - * - * @return next byte - * @since 1.3 - */ - public int read() throws java.io.IOException - { - // Do we need to get data? - if( position < 0 ) - { - if( encode ) - { - byte[] b3 = new byte[3]; - int numBinaryBytes = 0; - for( int i = 0; i < 3; i++ ) - { - try - { - int b = in.read(); - - // If end of stream, b is -1. - if( b >= 0 ) - { - b3[i] = (byte)b; - numBinaryBytes++; - } // end if: not end of stream - - } // end try: read - catch( java.io.IOException e ) - { - // Only a problem if we got no data at all. - if( i == 0 ) - throw e; - - } // end catch - } // end for: each needed input byte - - if( numBinaryBytes > 0 ) - { - encode3to4( b3, 0, numBinaryBytes, buffer, 0 ); - position = 0; - numSigBytes = 4; - } // end if: got data - else - { - return -1; - } // end else - } // end if: encoding - - // Else decoding - else - { - byte[] b4 = new byte[4]; - int i = 0; - for( i = 0; i < 4; i++ ) - { - // Read four "meaningful" bytes: - int b = 0; - do{ b = in.read(); } - while( b >= 0 && DECODABET[ b & 0x7f ] <= WHITE_SPACE_ENC ); - - if( b < 0 ) - break; // Reads a -1 if end of stream - - b4[i] = (byte)b; - } // end for: each needed input byte - - if( i == 4 ) - { - numSigBytes = decode4to3( b4, 0, buffer, 0 ); - position = 0; - } // end if: got four characters - else if( i == 0 ){ - return -1; - } // end else if: also padded correctly - else - { - // Must have broken out from above. - throw new java.io.IOException( "Improperly padded Base64 input." ); - } // end - - } // end else: decode - } // end else: get data - - // Got data? - if( position >= 0 ) - { - // End of relevant data? - if( /*!encode &&*/ position >= numSigBytes ) - return -1; - - if( encode && breakLines && lineLength >= MAX_LINE_LENGTH ) - { - lineLength = 0; - return '\n'; - } // end if - else - { - lineLength++; // This isn't important when decoding - // but throwing an extra "if" seems - // just as wasteful. - - int b = buffer[ position++ ]; - - if( position >= bufferLength ) - position = -1; - - return b & 0xFF; // This is how you "cast" a byte that's - // intended to be unsigned. - } // end else - } // end if: position >= 0 - - // Else error - else - { - // When JDK1.4 is more accepted, use an assertion here. - throw new java.io.IOException( "Error in Base64 code reading stream." ); - } // end else - } // end read - - - /** - * Calls {@link #read()} repeatedly until the end of stream - * is reached or len bytes are read. - * Returns number of bytes read into array or -1 if - * end of stream is encountered. - * - * @param dest array to hold values - * @param off offset for array - * @param len max number of bytes to read into array - * @return bytes read into array or -1 if end of stream is encountered. - * @since 1.3 - */ - public int read( byte[] dest, int off, int len ) throws java.io.IOException - { - int i; - int b; - for( i = 0; i < len; i++ ) - { - b = read(); - - //if( b < 0 && i == 0 ) - // return -1; - - if( b >= 0 ) - dest[off + i] = (byte)b; - else if( i == 0 ) - return -1; - else - break; // Out of 'for' loop - } // end for: each byte read - return i; - } // end read - - } // end inner class InputStream - - - - - - - /* ******** I N N E R C L A S S O U T P U T S T R E A M ******** */ - - - - /** - * A {@link Base64.OutputStream} will write data to another - * java.io.OutputStream, given in the constructor, - * and encode/decode to/from Base64 notation on the fly. - * - * @see Base64 - * @since 1.3 - */ - public static class OutputStream extends java.io.FilterOutputStream - { - private boolean encode; - private int position; - private byte[] buffer; - private int bufferLength; - private int lineLength; - private boolean breakLines; - private byte[] b4; // Scratch used in a few places - private boolean suspendEncoding; - - /** - * Constructs a {@link Base64.OutputStream} in ENCODE mode. - * - * @param out the java.io.OutputStream to which data will be written. - * @since 1.3 - */ - public OutputStream( java.io.OutputStream out ) - { - this( out, ENCODE ); - } // end constructor - - - /** - * Constructs a {@link Base64.OutputStream} in - * either ENCODE or DECODE mode. - *

- * Valid options:

-         *   ENCODE or DECODE: Encode or Decode as data is read.
-         *   DONT_BREAK_LINES: don't break lines at 76 characters
-         *     (only meaningful when encoding)
-         *     Note: Technically, this makes your encoding non-compliant.
-         * 
- *

- * Example: new Base64.OutputStream( out, Base64.ENCODE ) - * - * @param out the java.io.OutputStream to which data will be written. - * @param options Specified options. - * @see Base64#ENCODE - * @see Base64#DECODE - * @see Base64#DONT_BREAK_LINES - * @since 1.3 - */ - public OutputStream( java.io.OutputStream out, int options ) - { - super( out ); - this.breakLines = (options & DONT_BREAK_LINES) != DONT_BREAK_LINES; - this.encode = (options & ENCODE) == ENCODE; - this.bufferLength = encode ? 3 : 4; - this.buffer = new byte[ bufferLength ]; - this.position = 0; - this.lineLength = 0; - this.suspendEncoding = false; - this.b4 = new byte[4]; - } // end constructor - - - /** - * Writes the byte to the output stream after - * converting to/from Base64 notation. - * When encoding, bytes are buffered three - * at a time before the output stream actually - * gets a write() call. - * When decoding, bytes are buffered four - * at a time. - * - * @param theByte the byte to write - * @since 1.3 - */ - public void write(int theByte) throws java.io.IOException - { - // Encoding suspended? - if( suspendEncoding ) - { - super.out.write( theByte ); - return; - } // end if: supsended - - // Encode? - if( encode ) - { - buffer[ position++ ] = (byte)theByte; - if( position >= bufferLength ) // Enough to encode. - { - out.write( encode3to4( b4, buffer, bufferLength ) ); - - lineLength += 4; - if( breakLines && lineLength >= MAX_LINE_LENGTH ) - { - out.write( NEW_LINE ); - lineLength = 0; - } // end if: end of line - - position = 0; - } // end if: enough to output - } // end if: encoding - - // Else, Decoding - else - { - // Meaningful Base64 character? - if( DECODABET[ theByte & 0x7f ] > WHITE_SPACE_ENC ) - { - buffer[ position++ ] = (byte)theByte; - if( position >= bufferLength ) // Enough to output. - { - int len = Base64.decode4to3( buffer, 0, b4, 0 ); - out.write( b4, 0, len ); - //out.write( Base64.decode4to3( buffer ) ); - position = 0; - } // end if: enough to output - } // end if: meaningful base64 character - else if( DECODABET[ theByte & 0x7f ] != WHITE_SPACE_ENC ) - { - throw new java.io.IOException( "Invalid character in Base64 data." ); - } // end else: not white space either - } // end else: decoding - } // end write - - - - /** - * Calls {@link #write(int)} repeatedly until len - * bytes are written. - * - * @param theBytes array from which to read bytes - * @param off offset for array - * @param len max number of bytes to read into array - * @since 1.3 - */ - public void write( byte[] theBytes, int off, int len ) throws java.io.IOException - { - // Encoding suspended? - if( suspendEncoding ) - { - super.out.write( theBytes, off, len ); - return; - } // end if: supsended - - for( int i = 0; i < len; i++ ) - { - write( theBytes[ off + i ] ); - } // end for: each byte written - - } // end write - - - - /** - * Method added by PHIL. [Thanks, PHIL. -Rob] - * This pads the buffer without closing the stream. - */ - public void flushBase64() throws java.io.IOException - { - if( position > 0 ) - { - if( encode ) - { - out.write( encode3to4( b4, buffer, position ) ); - position = 0; - } // end if: encoding - else - { - throw new java.io.IOException( "Base64 input not properly padded." ); - } // end else: decoding - } // end if: buffer partially full - - } // end flush - - - /** - * Flushes and closes (I think, in the superclass) the stream. - * - * @since 1.3 - */ - public void close() throws java.io.IOException - { - // 1. Ensure that pending characters are written - flushBase64(); - - // 2. Actually close the stream - // Base class both flushes and closes. - super.close(); - - buffer = null; - out = null; - } // end close - - - - /** - * Suspends encoding of the stream. - * May be helpful if you need to embed a piece of - * base640-encoded data in a stream. - * - * @since 1.5.1 - */ - public void suspendEncoding() throws java.io.IOException - { - flushBase64(); - this.suspendEncoding = true; - } // end suspendEncoding - - - /** - * Resumes encoding of the stream. - * May be helpful if you need to embed a piece of - * base640-encoded data in a stream. - * - * @since 1.5.1 - */ - public void resumeEncoding() - { - this.suspendEncoding = false; - } // end resumeEncoding - - - - } // end inner class OutputStream - - -} // end class Base64 diff --git a/src/net/thauvin/lifeblogger/LifeBlogger.java b/src/net/thauvin/lifeblogger/LifeBlogger.java index 6a31ae8..1a93bc0 100644 --- a/src/net/thauvin/lifeblogger/LifeBlogger.java +++ b/src/net/thauvin/lifeblogger/LifeBlogger.java @@ -1,7 +1,7 @@ /* * @(#)LifeBlogger.java * - * Copyright (c) 2004, Erik C. Thauvin (http://www.thauvin.net/erik/) + * Copyright (c) 2005, Erik C. Thauvin (http://www.thauvin.net/erik/) * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -55,29 +55,30 @@ import javax.imageio.ImageIO; import javax.swing.*; +import org.apache.xmlrpc.Base64; + /** * The LifeBlogger class uploads/posts Lifeblog's favorite data to a blog. * - * @author Erik C. Thauvin + * @author Erik C. Thauvin * @version $Revision$, $Date$ - * - * @created Jul 19, 2004 - * @since 1.0 + * @created April 13, 2005 + * @since 1.0 */ public class LifeBlogger extends AntiAliasedThinlet { private static final String DRIVER = "SQLite.JDBCDriver"; - private static final String PREFS = - System.getProperty("user.home") + File.separator + ReleaseInfo.getProject() + ".properties"; + private static final String PREFS = System.getProperty("user.home") + File.separator + ReleaseInfo.getProject() + + ".properties"; private static final String JDBC_PREFIX = "jdbc:sqlite:/"; private static final String DATABASE = "\\DataBase\\NokiaLifeblogDataBase.db"; private static final String DEFAULT_ACTION = "mw"; private static final String MIME_JPG = "image/jpeg"; private static final String MIME_3GP = "video/3gpp"; - private final Properties _prefs = new Properties(); - private File _homeDir = new File(System.getProperty("user.home") + "\\My Documents\\NokiaLifeblogData"); private String _action; + private File _homeDir = new File(System.getProperty("user.home") + "\\My Documents\\NokiaLifeblogData"); + private final Properties _prefs = new Properties(); /** * Creates a new LifeBlogger object. @@ -163,18 +164,6 @@ public class LifeBlogger extends AntiAliasedThinlet } } - /** - * Sets the blog action. - * - * @param action The action - */ - public final void setAction(String action) - { - _action = action; - _prefs.put("via", _action); - savePrefs(); - } - /** * Displays the about dialog. */ @@ -200,9 +189,9 @@ public class LifeBlogger extends AntiAliasedThinlet /** * Populates the table rows. * - * @param thinlet The Thinlet object. - * @param table The table to populate. - * @param buttonsPanel The panel containing the buttons/label to update. + * @param thinlet The Thinlet object. + * @param table The table to populate. + * @param buttonsPanel The panel containing the buttons/label to update. * * @throws Exception If an error occurs while populate the table. */ @@ -320,7 +309,7 @@ public class LifeBlogger extends AntiAliasedThinlet /** * Performs the blog action. * - * @param table The table containing the selected item to perform the action on. + * @param table The table containing the selected item to perform the action on. * * @throws Exception If an error occurs while performing the action. */ @@ -342,6 +331,10 @@ public class LifeBlogger extends AntiAliasedThinlet { ftpDialog(info[1]); } + else if ("ta".equals(_action)) + { + taDialog(info[1], info[2]); + } else { mwDialog(info[1], info[2]); @@ -371,8 +364,8 @@ public class LifeBlogger extends AntiAliasedThinlet /** * Preforms the FTP action. * - * @param dialog The FTP dialog, - * @param ftpPanel The panel contaning the FTP data. + * @param dialog The FTP dialog, + * @param ftpPanel The panel contaning the FTP data. * * @throws IOException If an error occurs while performing the action. */ @@ -401,16 +394,14 @@ public class LifeBlogger extends AntiAliasedThinlet { _prefs.put("host", host); _prefs.put("login", login); - _prefs.put("password", Base64.encodeBytes(password.getBytes(), Base64.DONT_BREAK_LINES)); + _prefs.put("password", new String(Base64.encode(password.getBytes()))); _prefs.put("path", path); - savePrefs(); closeDialog(dialog); - final LifeFTP ftp = - new LifeFTP(this, host, login, password, path, filename, - new File(getString(find(ftpPanel, "file"), "text"))); + final LifeFTP ftp = new LifeFTP(this, host, login, password, path, filename, + new File(getString(find(ftpPanel, "file"), "text"))); ftp.start(); } } @@ -418,8 +409,8 @@ public class LifeBlogger extends AntiAliasedThinlet /** * Preforms the MetaWeblog action. * - * @param dialog The MetaWeblog dialog, - * @param mwPanel The panel contaning the MetaWeblog data. + * @param dialog The MetaWeblog dialog, + * @param mwPanel The panel contaning the MetaWeblog data. * * @throws IOException If an error occurs while performing the action. */ @@ -456,14 +447,14 @@ public class LifeBlogger extends AntiAliasedThinlet { _prefs.put("mw-host", host); _prefs.put("mw-login", login); - _prefs.put("mw-password", Base64.encodeBytes(password.getBytes(), Base64.DONT_BREAK_LINES)); + _prefs.put("mw-password", new String(Base64.encode(password.getBytes()))); _prefs.put("mw-id", blogID); if (_prefs.getProperty("blog-host") == null) { _prefs.put("blog-host", host); _prefs.put("blog-login", login); - _prefs.put("blog-password", Base64.encodeBytes(password.getBytes(), Base64.DONT_BREAK_LINES)); + _prefs.put("blog-password", new String(Base64.encode(password.getBytes()))); _prefs.put("blog-id", blogID); } @@ -471,35 +462,22 @@ public class LifeBlogger extends AntiAliasedThinlet closeDialog(dialog); - final LifeMediaObject mw = - new LifeMediaObject(this, host, blogID, login, password, filename, - String.valueOf(getProperty(find(mwPanel, "file"), "mtype")), - new File(getString(find(mwPanel, "file"), "text"))); + final LifeMediaObject mw = new LifeMediaObject(this, host, blogID, login, password, filename, + String.valueOf(getProperty(find(mwPanel, "file"), "mtype")), + new File(getString(find(mwPanel, "file"), "text"))); mw.start(); } } - /** - * Preforms the post to blog action. - * - * @param dialog The post dialog, - * @param blogPanel The panel contaning the post data. - * - * @throws IOException If an error occurs while performing the action. - */ - public final void post(Object dialog, Object blogPanel) - throws IOException - { - post(dialog, blogPanel, false); - } /** * Displays the post to blog dialog. * - * @param url The URL pointing to the location of the media object. - * @param filename DOCUMENT ME! + * @param url The URL pointing to the location of the media object. + * @param filename The file name. + * @param metaWeblog The metaWeblog flag. */ - public final void postDialog(String url, String filename) + public final void postDialog(String url, String filename, boolean metaWeblog) { try { @@ -507,10 +485,25 @@ public class LifeBlogger extends AntiAliasedThinlet setString(find(post, "host"), "text", _prefs.getProperty("blog-host", "")); setString(find(post, "blogid"), "text", _prefs.getProperty("blog-id", "")); setString(find(post, "login"), "text", _prefs.getProperty("blog-login", "")); - setString(find(post, "password"), "text", new String(Base64.decode(_prefs.getProperty("blog-password", "")))); + setString(find(post, "password"), "text", + new String(Base64.decode(_prefs.getProperty("blog-password", "").getBytes()))); setString(find(post, "entry"), "text", "\""\r

via LifeBlogger

"); + + if (metaWeblog) + { + setBoolean(find(post, "title"), "visible", true); + setBoolean(find(post, "titleFld"), "visible", true); + setString(post, "text", getString(post, "text") + " (MetaWeblog API)"); + } + else + { + setBoolean(find(post, "title"), "visible", false); + setBoolean(find(post, "titleFld"), "visible", false); + setString(post, "text", getString(post, "text") + " (Blogger API)"); + } + add(post); } catch (Exception e) @@ -522,7 +515,7 @@ public class LifeBlogger extends AntiAliasedThinlet /** * Previews a JPEG image. * - * @param table The data table. + * @param table The data table. * * @throws Exception If an error occurs while previewing the image. */ @@ -540,7 +533,7 @@ public class LifeBlogger extends AntiAliasedThinlet if ((info[1] != null) && MIME_JPG.equals(info[2])) { - // Retrieve the jpg image + // Retrieve the jpg image final BufferedImage in = ImageIO.read(new File(info[1])); final int maxDim = 200; @@ -589,21 +582,89 @@ public class LifeBlogger extends AntiAliasedThinlet /** * Preforms the publish to blog action. * - * @param dialog The post dialog, - * @param blogPanel The panel contaning the post data. + * @param dialog The post dialog, + * @param blogPanel The panel contaning the post data. * * @throws IOException If an error occurs while performing the action. */ - public final void publish(Object dialog, Object blogPanel) - throws IOException + public void publish(Object dialog, Object blogPanel) + throws IOException { - post(dialog, blogPanel, true); + final String host = getString(find(blogPanel, "host"), "text"); + final String blogID = getString(find(blogPanel, "blogid"), "text"); + final String login = getString(find(blogPanel, "login"), "text"); + final String password = getString(find(blogPanel, "password"), "text"); + final String entry = getString(find(blogPanel, "entry"), "text"); + + final Object fileFld = find(blogPanel, "file"); + final String file = getString(fileFld, "text"); + final String fileType = (String) getProperty(fileFld, "mime"); + + final String title; + final Object titleFld = find(blogPanel, "title"); + + if (getBoolean(titleFld, "visible")) + { + title = getString(titleFld, "text"); + } + else + { + title = null; + } + + if (host.length() <= 0) + { + alert("Please specify a XML-RPC URL."); + } + else if (login.length() <= 0) + { + alert("Please specify a login name."); + } + else if (password.length() <= 0) + { + alert("Please specify a password."); + } + else if (entry.length() <= 0) + { + alert("Please specify a post entry."); + } + else if (blogID.length() <= 0) + { + alert("Please specify a blog ID."); + } + else + { + _prefs.put("blog-host", host); + _prefs.put("blog-login", login); + _prefs.put("blog-password", new String(Base64.encode(password.getBytes()))); + _prefs.put("blog-id", blogID); + + savePrefs(); + + closeDialog(dialog); + + final LifePost post = new LifePost(this, host, blogID, login, password, title, + getString(find(blogPanel, "entry"), "text"), file, fileType); + post.start(); + } + } + + /** + * Sets the blog action. + * + * @param action The action + */ + public final void setAction(String action) + { + _action = action; + _prefs.put("via", _action); + savePrefs(); } /** * Toggles the given button based on the specified table selection. * - * @param table The table. + * @param table The table. * @param button The button. */ public final void toggleButton(Object table, Object button) @@ -614,8 +675,8 @@ public class LifeBlogger extends AntiAliasedThinlet /** * Updates the table data. * - * @param thinlet The Thinlet object. - * @param table The table to update. + * @param thinlet The Thinlet object. + * @param table The table to update. * @param buttonsPanel The panel containing the buttons/label to update. */ public final void updateTable(Thinlet thinlet, Object table, Object buttonsPanel) @@ -737,7 +798,7 @@ public class LifeBlogger extends AntiAliasedThinlet setString(find(ftp, "host"), "text", _prefs.getProperty("host", "")); setString(find(ftp, "login"), "text", _prefs.getProperty("login", "anonymous")); setString(find(ftp, "path"), "text", _prefs.getProperty("path", "")); - setString(find(ftp, "password"), "text", new String(Base64.decode(_prefs.getProperty("password", "")))); + setString(find(ftp, "password"), "text", new String(Base64.decode(_prefs.getProperty("password", "").getBytes()))); add(ftp); requestFocus(find(ftp, "host")); } @@ -758,7 +819,7 @@ public class LifeBlogger extends AntiAliasedThinlet setString(find(mw, "filename"), "text", file.substring(file.lastIndexOf('\\') + 1)); setString(find(mw, "host"), "text", _prefs.getProperty("mw-host", "")); setString(find(mw, "login"), "text", _prefs.getProperty("mw-login", "")); - setString(find(mw, "password"), "text", new String(Base64.decode(_prefs.getProperty("mw-password", "")))); + setString(find(mw, "password"), "text", new String(Base64.decode(_prefs.getProperty("mw-password", "").getBytes()))); setString(find(mw, "blogid"), "text", _prefs.getProperty("mw-id", "")); add(mw); requestFocus(find(mw, "host")); @@ -769,61 +830,6 @@ public class LifeBlogger extends AntiAliasedThinlet } } - /** - * Preforms the post/publish to blog action. - * - * @param dialog The post dialog, - * @param blogPanel The panel contaning the post data. - * @param publish Set to true to publish the post, false otherwise. - * - * @throws IOException If an error occurs while performing the action. - */ - private void post(Object dialog, Object blogPanel, boolean publish) - throws IOException - { - final String host = getString(find(blogPanel, "host"), "text"); - final String blogID = getString(find(blogPanel, "blogid"), "text"); - final String login = getString(find(blogPanel, "login"), "text"); - final String password = getString(find(blogPanel, "password"), "text"); - final String entry = getString(find(blogPanel, "entry"), "text"); - - if (host.length() <= 0) - { - alert("Please specify a XML-RPC URL."); - } - else if (login.length() <= 0) - { - alert("Please specify a login name."); - } - else if (password.length() <= 0) - { - alert("Please specify a password."); - } - else if (entry.length() <= 0) - { - alert("Please specify a post entry."); - } - else if (blogID.length() <= 0) - { - alert("Please specify a blog ID."); - } - else - { - _prefs.put("blog-host", host); - _prefs.put("blog-login", login); - _prefs.put("blog-password", Base64.encodeBytes(password.getBytes(), Base64.DONT_BREAK_LINES)); - _prefs.put("blog-id", blogID); - - savePrefs(); - - closeDialog(dialog); - - final LifePost post = - new LifePost(this, host, blogID, login, password, getString(find(blogPanel, "entry"), "text"), publish); - post.start(); - } - } - // Saves the properties. private void savePrefs() { @@ -854,4 +860,39 @@ public class LifeBlogger extends AntiAliasedThinlet } } } + + // Display the Textamerica dialog + private void taDialog(String file, String mimeType) + { + if ((!mimeType.equals(MIME_JPG)) && (!mimeType.equals(MIME_3GP))) + { + alert("This media type is not supported by Textamerica."); + + return; + } + + try + { + final Object post = parse("post.xml"); + setString(find(post, "host"), "text", _prefs.getProperty("blog-host", "http://xml.api.textamerica.com/")); + setString(find(post, "blogid"), "text", _prefs.getProperty("blog-id", "")); + setString(find(post, "login"), "text", _prefs.getProperty("blog-login", "")); + setString(find(post, "password"), "text", + new String(Base64.decode(_prefs.getProperty("blog-password", "").getBytes()))); + + final Object fileFld = find(post, "file"); + setString(fileFld, "text", file); + putProperty(fileFld, "mime", ((mimeType == MIME_JPG) ? "JPG" : "3GP")); + + setBoolean(find(post, "title"), "visible", true); + setBoolean(find(post, "titleFld"), "visible", true); + setString(post, "text", getString(post, "text") + " (Textamerica API)"); + + add(post); + } + catch (Exception e) + { + e.printStackTrace(); + } + } } diff --git a/src/net/thauvin/lifeblogger/LifeFTP.java b/src/net/thauvin/lifeblogger/LifeFTP.java index f1a54c4..e2a6f74 100644 --- a/src/net/thauvin/lifeblogger/LifeFTP.java +++ b/src/net/thauvin/lifeblogger/LifeFTP.java @@ -136,7 +136,7 @@ public class LifeFTP extends LifeBlog else { getThinlet().closeDialog(getDialog()); - getThinlet().postDialog(getPath() + (getPath().endsWith("/") ? "" : "/") + getFilename(), getFilename()); + getThinlet().postDialog(getPath() + (getPath().endsWith("/") ? "" : "/") + getFilename(), getFilename(), false); } ftp.logout(); diff --git a/src/net/thauvin/lifeblogger/LifeMediaObject.java b/src/net/thauvin/lifeblogger/LifeMediaObject.java index 721ecae..548c40d 100644 --- a/src/net/thauvin/lifeblogger/LifeMediaObject.java +++ b/src/net/thauvin/lifeblogger/LifeMediaObject.java @@ -45,11 +45,10 @@ import java.net.URLConnection; /** * The LifeMediaObject class posts a new media object via the metaWeblog.newMediaObject XML-RPC method. * - * @author Erik C. Thauvin + * @author Erik C. Thauvin * @version $Revision$, $Date$ - * * @created Jul 21, 2004 - * @since 1.0 + * @since 1.0 */ public class LifeMediaObject extends LifeBlog { @@ -59,14 +58,14 @@ public class LifeMediaObject extends LifeBlog /** * Creates a new LifeMediaObject object. * - * @param thinlet The Thinlet instance. - * @param url The MetaWeblog XML-RPC URL. - * @param blogID The blog ID. - * @param login The MetaWeblog login username. - * @param password The MetaWeblog login password. - * @param filename The name of the object to store. - * @param mimeType The object's MIME type. - * @param file The file to store. + * @param thinlet The Thinlet instance. + * @param url The XML-RPC URL endpoint. + * @param blogID The blog ID. + * @param login The login username. + * @param password The login password. + * @param filename The name of the object to store. + * @param mimeType The object's MIME type. + * @param file The file to store. * * @throws IOException If an error occurs while creating the object. */ @@ -87,147 +86,18 @@ public class LifeMediaObject extends LifeBlog */ public final void run() { - FileInputStream fis = null; - FileOutputStream fos = null; - BufferedOutputStream bos = null; - Base64.OutputStream out = null; + getThinlet().add(getDialog()); try { - getThinlet().add(getDialog()); - - final URL url = new URL(getHost()); - - if (!"http".equalsIgnoreCase(url.getProtocol())) - { - throw new IOException("Unsupported URL protocol: " + url.getProtocol()); - } - - final File tmpFile = File.createTempFile(ReleaseInfo.getProject(), ".b64"); - tmpFile.deleteOnExit(); - - fis = new FileInputStream(getFile()); - fos = new FileOutputStream(tmpFile); - bos = new BufferedOutputStream(fos); - out = new Base64.OutputStream(bos, Base64.ENCODE | Base64.DONT_BREAK_LINES); - - final byte[] buf = new byte[1024]; - int len; - - while ((len = fis.read(buf)) > 0) - { - out.write(buf, 0, len); - } - - fis.close(); - - final StringBuffer start = - new StringBuffer("metaWeblog.newMediaObject").append(_blogID) - .append("") - .append(getLogin()) - .append("") - .append(getPassword()) - .append("bits"); - - final StringBuffer end = - new StringBuffer("name").append(getFilename()) - .append("type") - .append(_mimeType) - .append(""); - - final URLConnection urlConn = url.openConnection(); - urlConn.setDoInput(true); - urlConn.setDoOutput(true); - urlConn.setUseCaches(false); - urlConn.setRequestProperty("Content-Length", - String.valueOf(start.length() + tmpFile.length() + end.length())); - urlConn.setRequestProperty("Content-Type", "text/xml"); - - final DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream()); - dos.write(start.toString().getBytes()); - dos.flush(); - - fis = new FileInputStream(tmpFile); - - while ((len = fis.read(buf)) > 0) - { - dos.write(buf, 0, len); - dos.flush(); - } - - fis.close(); - - dos.write(end.toString().getBytes()); - dos.flush(); - - dos.close(); - - final LifeRPCResponse xmlrpc = new LifeRPCResponse(urlConn.getInputStream()); - - if (xmlrpc.isValidResponse()) - { - getThinlet().closeDialog(getDialog()); - getThinlet().postDialog(xmlrpc.getResponse(), getFilename()); - } - else - { - alert(xmlrpc.getResponse()); - } - } - catch (IOException e) - { + final String url = LifeRPC.metaWeblogNewMediaObject(getHost(), _blogID, getLogin(), getPassword(), + getFilename(), _mimeType, getFile()); getThinlet().closeDialog(getDialog()); - getThinlet().handleException(e); + getThinlet().postDialog(url, getFilename(), true); } - finally + catch (Exception e) { - if (fis != null) - { - try - { - fis.close(); - } - catch (IOException ignore) - { - ; // Do nothing - } - } - - if (bos != null) - { - try - { - bos.close(); - } - catch (IOException ignore) - { - ; // Do nothing - } - } - - if (fos != null) - { - try - { - fos.close(); - } - catch (IOException ignore) - { - ; // Do nothing - } - } - - if (out != null) - { - try - { - out.close(); - } - catch (IOException ignore) - { - ; // Do nothing - } - } + alert(e.getMessage()); } } } diff --git a/src/net/thauvin/lifeblogger/LifePost.java b/src/net/thauvin/lifeblogger/LifePost.java index 3fa228e..81d0bec 100644 --- a/src/net/thauvin/lifeblogger/LifePost.java +++ b/src/net/thauvin/lifeblogger/LifePost.java @@ -36,50 +36,51 @@ */ package net.thauvin.lifeblogger; -import java.io.DataOutputStream; import java.io.IOException; -import java.net.URL; -import java.net.URLConnection; - /** * The LifePost class posts a new blog entry using the blogger.newPost() XML-RPC method. * - * @author Erik C. Thauvin + * @author Erik C. Thauvin * @version $Revision$, $Date$ - * * @created Jul 21, 2004 - * @since 1.0 + * @since 1.0 */ public class LifePost extends LifeAction { - private final String _blogEntry; private final String _blogID; - private final boolean _publish; + private final String _entry; + private final String _file; + private final String _fileType; + private final String _title; /** * Creates a new LifePost object. * - * @param thinlet The Thinlet instance. - * @param url The MetaWeblog XML-RPC URL. - * @param blogID The blog ID. - * @param login The MetaWeblog login username. - * @param password The MetaWeblog login password. - * @param blogEntry The blog entry. - * @param publish DOCUMENT ME! + * @param thinlet The Thinlet instance. + * @param url The MetaWeblog XML-RPC URL. + * @param blogID The blog ID. + * @param login The MetaWeblog login username. + * @param password The MetaWeblog login password. + * @param title The post's title, if any. + * @param description The blog description's text/description. + * @param file The file location, if any. + * @param fileType The file type, if any. * * @throws IOException If an error occurs while creating the object. */ - public LifePost(LifeBlogger thinlet, String url, String blogID, String login, String password, String blogEntry, - boolean publish) + public LifePost(LifeBlogger thinlet, String url, String blogID, String login, String password, String title, + String description, String file, String fileType) throws IOException { super(thinlet, url, login, password); - _blogEntry = blogEntry; + _entry = description; _blogID = blogID; - _publish = publish; + _title = title; + _file = file; + _fileType = fileType; } /** @@ -89,122 +90,39 @@ public class LifePost extends LifeAction */ public final void run() { + getThinlet().add(getDialog()); + + try { - getThinlet().add(getDialog()); + final String response; - final URL url = new URL(getHost()); - - if (!"http".equalsIgnoreCase(url.getProtocol())) + if (_file.length() != 0) { - throw new IOException("Unsupported URL protocol: " + url.getProtocol()); + response = LifeRPC.taEntryUpdate(getHost(), _blogID, getLogin(), getPassword(), _title, _entry, _file, + _fileType); } - - final StringBuffer request = - new StringBuffer("blogger.newPost0a6afffffffaffffffb8ffffff8569474cffffffc778500c03ffffffecffffff876116565a27283bffffffda56").append(_blogID) - .append("") - .append(getLogin()) - .append("") - .append(getPassword()) - .append("") - .append(textToXML(_blogEntry)) - .append("") - .append(String.valueOf(_publish)) - .append(""); - final URLConnection urlConn = url.openConnection(); - urlConn.setDoInput(true); - urlConn.setDoOutput(true); - urlConn.setUseCaches(false); - urlConn.setRequestProperty("Content-Length", String.valueOf(request.length())); - urlConn.setRequestProperty("Content-Type", "text/xml"); - - final DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream()); - dos.write(request.toString().getBytes()); - dos.flush(); - dos.close(); - - //System.out.println(request); - final LifeRPCResponse xmlrpc = new LifeRPCResponse(urlConn.getInputStream()); - - if (xmlrpc.isValidResponse()) + else if (_title != null) { - //getThinlet().closeDialog(getDialog()); - getThinlet().setIcon(getThinlet().find(getDialog(), "iconlbl"), "icon", - getThinlet().getIcon("/icon/info.gif")); - getThinlet().setString(getThinlet().find(getDialog(), "message"), "text", - "Post successful. (ID " + xmlrpc.getResponse() + ')'); - getThinlet().setBoolean(getThinlet().find(getDialog(), "closebtn"), "enabled", true); + response = LifeRPC.metaWeblogNewPost(getHost(), _blogID, getLogin(), getPassword(), _title, _entry); } else { - alert(xmlrpc.getResponse()); + response = LifeRPC.bloggerNewPost(getHost(), _blogID, getLogin(), getPassword(), _entry); } + + getThinlet().setIcon(getThinlet().find(getDialog(), "iconlbl"), "icon", + getThinlet().getIcon("/icon/info.gif")); + getThinlet().setString(getThinlet().find(getDialog(), "message"), "text", + "Post successful. (ID " + response + ')'); + getThinlet().setBoolean(getThinlet().find(getDialog(), "closebtn"), "enabled", true); } - catch (IOException e) + catch (Exception e) { - getThinlet().closeDialog(getDialog()); - getThinlet().handleException(e); + alert(e.getMessage()); } + } - /** - * Converts a character to XML entity. - * - * @param ch The character to convert. - * - * @return The converted string. - */ - private String charToXML(char ch) - { - final int c; - // Convert left bracket - if (ch == '<') - { - return ("<"); - } - - // Convert ampersand - else if (ch == '&') - { - return ("&"); - } - - // High/Low-ASCII character - else if ((ch >= 128) || (ch < 32)) - { - c = (int) ch; - - return ("&#" + c + ';'); - } - - // No conversion - else - { - // Return character as string - return (String.valueOf(ch)); - } - } - - /** - * Converts a text string to XML entities. - * - * @param text The string to convert. - * - * @return The converted string. - */ - private String textToXML(String text) - { - final StringBuffer html = new StringBuffer(); - - // Loop thru each characters of the text - for (int i = 0; i < text.length(); i++) - { - // Convert character to XML - html.append(charToXML(text.charAt(i))); - } - - // Return XML string - return html.toString(); - } } diff --git a/src/net/thauvin/lifeblogger/LifeRPC.java b/src/net/thauvin/lifeblogger/LifeRPC.java new file mode 100644 index 0000000..c699d59 --- /dev/null +++ b/src/net/thauvin/lifeblogger/LifeRPC.java @@ -0,0 +1,256 @@ +/* + * @(#)LifeRPC.java + * + * Copyright (C) 2005 by Erik C. Thauvin (erik@thauvin.net) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 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. + * + * Neither the name of the authors nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR + * 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. + * + * $Id$ + * + */ +package net.thauvin.lifeblogger; + +import org.apache.xmlrpc.Base64; +import org.apache.xmlrpc.XmlRpcClient; + +import java.io.*; + +import java.util.Hashtable; +import java.util.Vector; + + +/** + * The LifeRPC class implements the blogger.newPost, metaWeblog.newPost, metaWeblog.newMediaObject and + * ta.Entry.Update XML-RPC methods. + * + * @author Erik C. Thauvin + * @version $Revision$, $Date$ + * @created Apr 13, 2005 + * @since 1.0 + */ +public class LifeRPC +{ + /** + * Disables the default constructor. + * + * @throws UnsupportedOperationException if the constructor is called. + */ + private LifeRPC() + throws UnsupportedOperationException + { + throw new UnsupportedOperationException("Illegal constructor call."); + } + + /** + * Implements the blogger.newPost XML-RPC call. + * + * @param url The XML-RPC URL endpoint. + * @param blogID The blog ID. + * @param login The login username. + * @param password The login password. + * @param description The blog description's text/description. + * + * @return The post ID. + * + * @throws Exception If an error occurred while posting. + */ + public static String bloggerNewPost(String url, String blogID, String login, String password, String description) + throws Exception + { + final XmlRpcClient xmlrpc = new XmlRpcClient(url); + final Vector params = new Vector(0); + + // Set the API key + params.add("0a6afffffffaffffffb8ffffff8569474cffffffc778500c03ffffffecffffff876116565a27283bffffffda56"); + + params.add(blogID); + params.add(login); + params.add(password); + params.add(description); + + // Set the publish flag + params.add(Boolean.valueOf(true)); + + return ((String) xmlrpc.execute("blogger.newPost", params)); + + } + + /** + * Implements blogger.newPost XML-RPC call. + * + * @param url The XML-RPC URL endpoint. + * @param blogID The blog ID. + * @param login The login username. + * @param password The login password. + * @param filename The name of the object to store. + * @param mimeType The object's MIME type. + * @param file The file to store. + * + * @return The URL of the new media object. + * + * @throws Exception If an error occurred while upload the new media object. + */ + public static String metaWeblogNewMediaObject(String url, String blogID, String login, String password, + String filename, String mimeType, File file) + throws Exception + { + final XmlRpcClient xmlrpc = new XmlRpcClient(url); + final Vector params = new Vector(0); + + final InputStream is = new FileInputStream(file); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024); + final BufferedInputStream bufferedInputStream = new BufferedInputStream(is); + + final byte[] bytes = new byte[1024]; + int len = 0; + + while ((len = bufferedInputStream.read(bytes)) > 0) + { + byteArrayOutputStream.write(bytes, 0, len); + } + + is.close(); + bufferedInputStream.close(); + + params.add(blogID); + params.add(login); + params.add(password); + + final Hashtable media = new Hashtable(0); + + media.put("name", filename); + media.put("type", mimeType); + media.put("bits", byteArrayOutputStream.toByteArray()); + + params.add(media); + + final Hashtable response = (Hashtable) xmlrpc.execute("metaWeblog.newMediaObject", params); + + return ((String) response.get("url")); + } + + /** + * Implements the metaWeblog.newPost XML-RPC call. + * + * @param url The XML-RPC URL endpoint. + * @param blogID The blog ID. + * @param login The login username. + * @param password The login password. + * @param title The blog description's title. + * @param description The blog description's text/description. + * + * @return The post ID. + * + * @throws Exception If an error occurred while posting. + */ + public static String metaWeblogNewPost(String url, String blogID, String login, String password, String title, + String description) + throws Exception + { + final XmlRpcClient xmlrpc = new XmlRpcClient(url); + final Vector params = new Vector(0); + + params.add(blogID); + params.add(login); + params.add(password); + + final Hashtable blogEntry = new Hashtable(0); + blogEntry.put("title", title); + blogEntry.put("description", description); + params.add(blogEntry); + + // Set the publish flag + params.add(Boolean.valueOf(true)); + + return ((String) xmlrpc.execute("metaWeblog.newPost", params)); + + } + + /** + * Implements the metaWeblog.newPost XML-RPC call. + * + * @param url The XML-RPC URL endpoint. + * @param blogID The blog ID. + * @param login The login username. + * @param password The login password. + * @param title The blog description's title. + * @param description The blog description's text/description. + * @param file The file location. + * @param fileType The file type. + * + * @return The post ID. + * + * @throws Exception If an error occurred while posting. + */ + public static String taEntryUpdate(String url, String blogID, String login, String password, String title, + String description, String file, String fileType) + throws Exception + { + final XmlRpcClient xmlrpc = new XmlRpcClient(url); + final Vector params = new Vector(0); + + final InputStream is = new FileInputStream(file); + final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024); + final BufferedInputStream bufferedInputStream = new BufferedInputStream(is); + + final byte[] bytes = new byte[1024]; + int len = 0; + + while ((len = bufferedInputStream.read(bytes)) > 0) + { + byteArrayOutputStream.write(bytes, 0, len); + } + + is.close(); + bufferedInputStream.close(); + + final byte[] encodedBytes = Base64.encode(byteArrayOutputStream.toByteArray()); + + // Set the API key + params.add("TA113805"); + + params.add(login); + params.add(password); + params.add(blogID); + + // Set the entry ID + params.add("0"); + + params.add(title); + params.add(description); + + // Set the category ID + params.add("0"); + + params.add(new String(encodedBytes)); + params.add(fileType); + + return ((String) xmlrpc.execute("ta.entry.Update", params)); + } +} diff --git a/src/net/thauvin/lifeblogger/LifeRPCResponse.java b/src/net/thauvin/lifeblogger/LifeRPCResponse.java deleted file mode 100644 index 6a252e0..0000000 --- a/src/net/thauvin/lifeblogger/LifeRPCResponse.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * @(#)LifeRPCResponse.java - * - * Copyright (c) 2004, Erik C. Thauvin (http://www.thauvin.net/erik/) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 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. - * - * Neither the name of the authors nor the names of its contributors may be - * used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR - * 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. - * - * $Id$ - * - */ -package net.thauvin.lifeblogger; - -import thinlet.Thinlet; - -import java.io.IOException; -import java.io.InputStream; - - -/** - * The LifeRPCResponse class uses the Thinlet DOM parser to process a XML-RCP response. - * - * @author Erik C. Thauvin - * @version $Revision$, $Date$ - * - * @created Jul 21, 2004 - * @since 1.0 - */ -public class LifeRPCResponse extends Thinlet -{ - private final InputStream _inputStream; - private String _response; - - /** - * Creates a new LifeRPCResponse object. - * - * @param inputStream The input stream. - */ - public LifeRPCResponse(InputStream inputStream) - { - _inputStream = inputStream; - } - - /** - * Returns the XML-RPC response/fault string. - * - * @return The response string. - */ - public final String getResponse() - { - return _response; - } - - /** - * Parses and validates the XML-RPC response. - * - * @return true is the response is valid, false if it is a fault. - * - * @throws IOException If an error occurs while processing the response. - */ - public final boolean isValidResponse() - throws IOException - { - try - { - final Object dom = parseDOM(_inputStream); - final Object params = getDOMNode(dom, "params", 0); - - if (params != null) - { - final Object param = getDOMNode(params, "param", 0); - final Object value = getDOMNode(param, "value", 0); - final Object struct = getDOMNode(value, "struct", 0); - - if (struct == null) - { - final Object string = getDOMNode(value, "string", 0); - - if (string == null) - { - _response = getDOMText(value); - } - else - { - _response = getDOMText(string); - } - } - else - { - final Object member = getDOMNode(struct, "member", 0); - final Object url = getDOMNode(member, "value", 0); - final Object string = getDOMNode(url, "string", 0); - - if (string == null) - { - _response = getDOMText(url); - } - else - { - _response = getDOMText(string); - } - } - - return true; - } - else - { - final Object fault = getDOMNode(dom, "fault", 0); - final Object value = getDOMNode(fault, "value", 0); - final Object struct = getDOMNode(value, "struct", 0); - Object member = getDOMNode(struct, "member", 0); - - if (getDOMCount(struct, "member") > 1) - { - member = getDOMNode(struct, "member", 1); - } - - final Object error = getDOMNode(member, "value", 0); - final Object string = getDOMNode(error, "string", 0); - - if (string != null) - { - _response = getDOMText(string); - } - else - { - throw new IOException("Could not parse the XML-RPC error response."); - } - - return false; - } - } - catch (IOException e) - { - throw e; - } - finally - { - try - { - _inputStream.close(); - } - catch (IOException ignore) - { - ; // Do nothing - } - } - } -} diff --git a/src/net/thauvin/lifeblogger/ReleaseInfo.java b/src/net/thauvin/lifeblogger/ReleaseInfo.java index 040811a..ee5c511 100644 --- a/src/net/thauvin/lifeblogger/ReleaseInfo.java +++ b/src/net/thauvin/lifeblogger/ReleaseInfo.java @@ -1,5 +1,5 @@ /* Created by JReleaseInfo AntTask from Open Source Competence Group */ -/* Creation date Sun Feb 06 00:48:16 PST 2005 */ +/* Creation date Thu Apr 14 03:27:19 PDT 2005 */ package net.thauvin.lifeblogger; import java.util.Date; @@ -12,28 +12,28 @@ import java.util.Date; public class ReleaseInfo { - /** buildDate (set during build process to 1107679696812L). */ - private static Date buildDate = new Date(1107679696812L); + /** buildDate (set during build process to 1113474439925L). */ + private static Date buildDate = new Date(1113474439925L); /** - * Get buildDate (set during build process to Sun Feb 06 00:48:16 PST 2005). + * Get buildDate (set during build process to Thu Apr 14 03:27:19 PDT 2005). * @return Date buildDate */ public static final Date getBuildDate() { return buildDate; } /** - * Get buildNumber (set during build process to 5). + * Get buildNumber (set during build process to 1). * @return int buildNumber */ - public static final int getBuildNumber() { return 5; } + public static final int getBuildNumber() { return 1; } - /** version (set during build process to "0.1.2"). */ - private static String version = new String("0.1.2"); + /** version (set during build process to "0.2"). */ + private static String version = new String("0.2"); /** - * Get version (set during build process to "0.1.2"). + * Get version (set during build process to "0.2"). * @return String version */ public static final String getVersion() { return version; } diff --git a/src/net/thauvin/lifeblogger/main.xml b/src/net/thauvin/lifeblogger/main.xml index 9a7aac7..dc209a6 100644 --- a/src/net/thauvin/lifeblogger/main.xml +++ b/src/net/thauvin/lifeblogger/main.xml @@ -7,6 +7,7 @@ + diff --git a/src/net/thauvin/lifeblogger/post.xml b/src/net/thauvin/lifeblogger/post.xml index 42c3da8..6454f17 100644 --- a/src/net/thauvin/lifeblogger/post.xml +++ b/src/net/thauvin/lifeblogger/post.xml @@ -1,16 +1,17 @@ - +