cziegeler 02/02/13 00:56:50 Modified: src/java/org/apache/cocoon/components/store FilesystemStore.java Log: Better encoding/decoding of keys Revision Changes Path 1.10 +85 -35 xml-cocoon2/src/java/org/apache/cocoon/components/store/FilesystemStore.java Index: FilesystemStore.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/store/FilesystemStore.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- FilesystemStore.java 12 Feb 2002 15:04:42 -0000 1.9 +++ FilesystemStore.java 13 Feb 2002 08:56:50 -0000 1.10 @@ -64,9 +64,11 @@ import org.apache.avalon.framework.parameters.ParameterException; import org.apache.cocoon.Constants; import org.apache.cocoon.util.IOUtils; - +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.BitSet; import java.util.Enumeration; /** @@ -75,7 +77,7 @@ * * @author ? * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a> - * @version CVS $Id: FilesystemStore.java,v 1.9 2002/02/12 15:04:42 cziegeler Exp $ + * @version CVS $Id: FilesystemStore.java,v 1.10 2002/02/13 08:56:50 cziegeler Exp $ */ public final class FilesystemStore extends AbstractLoggable @@ -294,11 +296,7 @@ if (files[i].isDirectory()) { this.addKeys(enum, files[i]); } else { - try { - // FIXME: if for any reason we get a file which was not created using - // this store, decoding will fail. - enum.add(this.decode(files[i].getAbsolutePath().substring(subStringBegin))); - } catch (Exception ignore) {} + enum.add(this.decode(files[i].getAbsolutePath().substring(subStringBegin))); } } } @@ -380,46 +378,98 @@ } /** - * Returns a String that uniquely identifies the object. - * <b>Note:</b> since this method uses the Object.toString() - * method, it's up to the caller to make sure that this method - * doesn't change between different JVM executions (like - * it may normally happen). For this reason, it's highly recommended - * (even if not mandated) that Strings be used as keys. + * Inverse of encode exept it do not use path. + * So decode(encode(s) - m_path) = s. + * In other words it returns a String that can be used as key to retive + * the record contained in the 'filename' file. */ - protected String encode( final String key ) + protected String decode( String filename ) { - final byte[] bytes = key.getBytes(); - final char[] buffer = new char[ bytes.length << 1 ]; + return java.net.URLDecoder.decode( filename ); + } + + /** A BitSet defining the characters which don't need encoding */ + static BitSet charactersDontNeedingEncoding; + static final int characterCaseDiff = ('a' - 'A'); - for( int i = 0, j = 0; i < bytes.length; i++ ) + /** Initialize the BitSet */ + static + { + charactersDontNeedingEncoding = new BitSet(256); + int i; + for (i = 'a'; i <= 'z'; i++) { - final int k = bytes[ i ]; - buffer[ j++ ] = HEX_DIGITS[ ( k >>> 4 ) & BYTE_MASK ]; - buffer[ j++ ] = HEX_DIGITS[ k & BYTE_MASK ]; + charactersDontNeedingEncoding.set(i); } - - return new String(buffer); + for (i = 'A'; i <= 'Z'; i++) + { + charactersDontNeedingEncoding.set(i); + } + for (i = '0'; i <= '9'; i++) + { + charactersDontNeedingEncoding.set(i); + } + charactersDontNeedingEncoding.set('-'); + charactersDontNeedingEncoding.set('_'); + charactersDontNeedingEncoding.set('('); + charactersDontNeedingEncoding.set(')'); } /** - * Inverse of encode exept it do not use path. - * So decode(encode(s) - m_path) = s. - * In other words it returns a String that can be used as key to retive - * the record contained in the 'filename' file. + * Returns a String that uniquely identifies the object. + * <b>Note:</b> since this method uses the Object.toString() + * method, it's up to the caller to make sure that this method + * doesn't change between different JVM executions (like + * it may normally happen). For this reason, it's highly recommended + * (even if not mandated) that Strings be used as keys. */ - protected String decode( String filename ) - { - final int size = filename.length(); - final byte[] bytes = new byte[ size >>> 1 ]; - - for( int i = 0, j = 0; i < size; j++ ) + public String encode(String s) { + final StringBuffer out = new StringBuffer( s.length() ); + final ByteArrayOutputStream buf = new ByteArrayOutputStream( 32 ); + final OutputStreamWriter writer = new OutputStreamWriter( buf ); + for (int i = 0; i < s.length(); i++) { - bytes[ j ] = Byte.parseByte( filename.substring( i, i + 2 ), 16 ); - i +=2; + int c = (int)s.charAt(i); + if (charactersDontNeedingEncoding.get(c)) + { + out.append((char)c); + } + else + { + try + { + writer.write(c); + writer.flush(); + } + catch(IOException e) + { + buf.reset(); + continue; + } + byte[] ba = buf.toByteArray(); + for (int j = 0; j < ba.length; j++) + { + out.append('%'); + char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16); + // converting to use uppercase letter as part of + // the hex value if ch is a letter. + if (Character.isLetter(ch)) + { + ch -= characterCaseDiff; + } + out.append(ch); + ch = Character.forDigit(ba[j] & 0xF, 16); + if (Character.isLetter(ch)) + { + ch -= characterCaseDiff; + } + out.append(ch); + } + buf.reset(); + } } - return new String( bytes ); + return out.toString(); } }
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]