1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package net.sf.beanform.util;
16
17 import java.util.HashMap;
18 import java.util.Map;
19
20 /***
21 * A thread-safe cache of strings that allows aliasing of long strings to smaller
22 * strings that can then be used to reverse the process.
23 *
24 * @author Daniel Gredler
25 */
26 public class StringCache {
27
28 protected final static char[] CHARS = {
29 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
30 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
31 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
32
33 protected int maxSize;
34 protected Map<String, String> cacheByShort;
35 protected Map<String, String> cacheByReal;
36
37 public StringCache( int maxSize ) {
38 this.maxSize = maxSize;
39 this.cacheByShort = new HashMap<String, String>( maxSize );
40 this.cacheByReal = new HashMap<String, String>( maxSize );
41 }
42
43 public synchronized String getShortVersion( String real ) {
44 if( this.cacheByReal.size() == this.maxSize ) return real;
45 String s;
46 if( this.cacheByReal.containsKey( real ) ) {
47 s = this.cacheByReal.get( real );
48 }
49 else {
50 s = Character.toString( CHARS[ 0 ] );
51 for( int i = 1; this.cacheByShort.containsKey( s ); i++ ) {
52 s = getChars( CHARS, i );
53 }
54 this.cacheByShort.put( s, real );
55 this.cacheByReal.put( real, s );
56 }
57 return s;
58 }
59
60 public synchronized String getRealVersion( String shortVersion ) {
61 String real;
62 if( this.cacheByShort.containsKey( shortVersion ) ) {
63 real = this.cacheByShort.get( shortVersion );
64 }
65 else {
66 real = shortVersion;
67 }
68 return real;
69 }
70
71 protected static String getChars( char[] chars, int index ) {
72 String s = new String();
73 int i = index / chars.length;
74 if( i > 0 ) {
75 s = getChars( chars, i - 1 ) + s;
76 }
77 s = s + chars[ index % chars.length ];
78 return s;
79 }
80
81 }