1 /**
2  * Authors: Frank Benoit <keinfarbton@googlemail.com>
3  */
4 module java.util.ResourceBundle;
5 
6 import java.lang.util;
7 import java.lang.Integer;
8 import java.lang.exceptions;
9 import java.util.MissingResourceException;
10 import java.util.Enumeration;
11 import java.nonstandard.Locale;
12 version(Tango){
13     //import tango.text.Util;
14     import tango.io.device.File;
15 } else { // Phobos
16     static import std.file;
17 }
18 
19 
20 class ResourceBundle {
21 
22     String[ String ] map;
23 
24     /++
25      + First entry is the default entry if no maching locale is found
26      +/
27     public this( in ImportData[] data ){
28         char[] name = caltureName.dup;
29         if( name.length is 5 && name[2] is '-' ){
30             name[2] = '_';
31             char[] end = "_" ~ name ~ ".properties";
32             foreach( entry; data ){
33                 if( entry.name.length > end.length && entry.name[ $-end.length .. $ ] == end ){
34                     //Trace.formatln( "ResourceBundle {}", entry.name );
35                     initialize( cast(String)entry.data );
36                     return;
37                 }
38             }
39         }
40         char[] end = "_" ~ name[0..2] ~ ".properties";
41         foreach( entry; data ){
42             if( entry.name.length > end.length && entry.name[ $-end.length .. $ ] == end ){
43                 //Trace.formatln( "ResourceBundle {}", entry.name );
44                 initialize( cast(String)entry.data );
45                 return;
46             }
47         }
48         //Trace.formatln( "ResourceBundle default" );
49         initialize( cast(String)data[0].data );
50     }
51     public this( in ImportData data ){
52         initialize( cast(String)data.data );
53     }
54     public this( String data ){
55         initialize( data );
56     }
57     private void initialize( String data ){
58         String line;
59         int dataIndex;
60 
61         void readLine(){
62             line.length = 0;
63             char i = data[ dataIndex++ ];
64             while( dataIndex < data.length && i !is '\n' && i !is '\r' ){
65                 line ~= i;
66                 i = data[ dataIndex++ ];
67             }
68         }
69 
70         bool linecontinue = false;
71         bool iskeypart = true;
72         String key;
73         String value;
74 nextline:
75         while( dataIndex < data.length ){
76             readLine();
77             line = java.lang.util.trim(line);
78             if( line.length is 0 ){
79                 continue;
80             }
81             if( line[0] == '#' ){
82                 continue;
83             }
84             int pos = 0;
85             bool esc = false;
86             if( !linecontinue ){
87                 iskeypart = true;
88                 key = null;
89                 value = null;
90             }
91             else{
92                 linecontinue = false;
93             }
94             while( pos < line.length ){
95                 dchar c = line[pos];
96                 if( esc ){
97                     esc = false;
98                     switch( c ){
99                         case 't' : c = '\t'; break;
100                         case 'n' : c = '\n'; break;
101                         case '\\': c = '\\'; break;
102                         case '\"': c = '\"'; break;
103                         case 'u' :
104                                c = Integer.parseInt( line[ pos+1 .. pos+5 ], 16 );
105                                pos += 4;
106                                break;
107                         default: break;
108                     }
109                 }
110                 else{
111                     if( c == '\\' ){
112                         if( pos == line.length -1 ){
113                             linecontinue = true;
114                             goto nextline;
115                         }
116                         esc = true;
117                         pos++;
118                         continue;
119                     }
120                     else if( iskeypart && c == '=' ){
121                         pos++;
122                         iskeypart = false;
123                         continue;
124                     }
125                 }
126                 pos++;
127                 if( iskeypart ){
128                     key ~= dcharToString(c);
129                 }
130                 else{
131                     value ~= dcharToString(c);
132                 }
133             }
134             if( iskeypart ){
135                 throw new RuntimeException( __FILE__, __LINE__, "Cannot find = in record" );
136             }
137             key = java.lang.util.trim(key);
138             value = java.lang.util.trim(value);
139 
140             map[ _idup(key) ] = _idup(value);
141         }
142     }
143 
144     public bool hasString( String key ){
145         return ( key in map ) !is null;
146     }
147 
148     public String getString( String key ){
149         if( auto v = key in map ){
150             return _idup(*v);
151         }
152         throw new MissingResourceException( "key not found", this.classinfo.name, key._idup() );
153     }
154 
155     public Enumeration getKeys(){
156         implMissing(__FILE__,__LINE__);
157         return null;
158     }
159     public String[] getKeysAsArray(){
160         return map.keys;
161     }
162 
163     public static ResourceBundle getBundle( in ImportData[] data ){
164         return new ResourceBundle( data );
165     }
166     public static ResourceBundle getBundle( in ImportData data ){
167         return new ResourceBundle( data );
168     }
169     public static ResourceBundle getBundle( String name ){
170         try{
171             version(Tango){
172                 return new ResourceBundle( cast(String) File.get(name) );
173             } else { // Phobos
174                 return new ResourceBundle( cast(String) std.file.read(name) );
175             }
176         }
177         catch( IOException e){
178             e.msg ~= " file:" ~ name;
179             throw e;
180         }
181     }
182     public static ResourceBundle getBundleFromData( String data ){
183         return new ResourceBundle( data );
184     }
185 }
186 
187