package org.obo.app.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.prefs.BackingStoreException; import java.util.prefs.Preferences; /** * Static methods for storing arbitrary objects using the Java Preferences api. * Downloaded from http://www.ibm.com/developerworks/java/library/j-prefapi.html */ public class PrefObj { // Max byte count is 3/4 max string length (see Preferences // documentation). static private final int pieceLength = ((3*Preferences.MAX_VALUE_LENGTH)/4); static private byte[] object2Bytes( Object o ) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream( baos ); oos.writeObject( o ); return baos.toByteArray(); } static private byte[][] breakIntoPieces( byte raw[] ) { int numPieces = (raw.length + pieceLength - 1) / pieceLength; byte pieces[][] = new byte[numPieces][]; for (int i=0; i<numPieces; ++i) { int startByte = i * pieceLength; int endByte = startByte + pieceLength; if (endByte > raw.length) endByte = raw.length; int length = endByte - startByte; pieces[i] = new byte[length]; System.arraycopy( raw, startByte, pieces[i], 0, length ); } return pieces; } static private void writePieces( Preferences prefs, String key, byte pieces[][] ) throws BackingStoreException { Preferences node = prefs.node( key ); node.clear(); for (int i=0; i<pieces.length; ++i) { node.putByteArray( ""+i, pieces[i] ); } } static private byte[][] readPieces( Preferences prefs, String key ) throws BackingStoreException { Preferences node = prefs.node( key ); String keys[] = node.keys(); int numPieces = keys.length; byte pieces[][] = new byte[numPieces][]; for (int i=0; i<numPieces; ++i) { pieces[i] = node.getByteArray( ""+i, null ); } return pieces; } static private byte[] combinePieces( byte pieces[][] ) { int length = 0; for (int i=0; i<pieces.length; ++i) { length += pieces[i].length; } byte raw[] = new byte[length]; int cursor = 0; for (int i=0; i<pieces.length; ++i) { System.arraycopy( pieces[i], 0, raw, cursor, pieces[i].length ); cursor += pieces[i].length; } return raw; } static private Object bytes2Object( byte raw[] ) throws IOException, ClassNotFoundException { ByteArrayInputStream bais = new ByteArrayInputStream( raw ); ObjectInputStream ois = new ObjectInputStream( bais ); Object o = ois.readObject(); return o; } static public void putObject( Preferences prefs, String key, Object o ) throws IOException, BackingStoreException, ClassNotFoundException { byte raw[] = object2Bytes( o ); byte pieces[][] = breakIntoPieces( raw ); writePieces( prefs, key, pieces ); } static public Object getObject( Preferences prefs, String key ) throws IOException, BackingStoreException, ClassNotFoundException { byte pieces[][] = readPieces( prefs, key ); byte raw[] = combinePieces( pieces ); Object o = bytes2Object( raw ); return o; } }