Repository navigation
Expand file tree
/
Copy pathjavaRB.cfc
More file actions
256 lines (241 loc) · 11.6 KB
/
Copy pathjavaRB.cfc
File metadata and controls
256 lines (241 loc) · 11.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
<cfcomponent displayname="javaRB" hint="reads and parses java resource bundle per locale, version 1.3 mar-2006" output="no" mixin="none">
<!---
author: paul hastings <paul@sustainableGIS.com>
date: 08-december-2003
revisions: 15-mar-2005 fixed un-scoped var variable in formatRBString method.
4-mar-2006 added messageFormat,verifyPattern method
notes: the purpose of this CFC is to extract text resources from a pure java resource bundle. these
resource bundles should be produced by a tools such as IBM's rbManager and consist of:
key=ANSI escaped string such as
(english, no need for ANSI escaped chars)
Cancel=Cancel
Go=Ok
(thai, ANSI escaped chars)
Cancel=\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01
Go=\u0E44\u0E1B
methods in this CFC:
- getResourceBundle returns a structure containing all key/messages value pairs in a given resource
bundle file. required argument is rbFile containing absolute path to resource bundle file. optional
argument is rbLocale to indicate which locale's resource bundle to use, defaults to us_EN (american
english). PUBLIC
- getRBKeys returns an array holding all keys in given resource bundle. required argument is rbFile
containing absolute path to resource bundle file. optional argument is rbLocale to indicate which
locale's resource bundle to use, defaults to us_EN (american english). PUBLIC
- getRBString returns string containing the text for a given key in a given resource bundle. required
arguments are rbFile containing absolute path to resource bundle file and rbKey a string holding the
required key. optional argument is rbLocale to indicate which locale's resource bundle to use, defaults
to us_EN (american english). PUBLIC
- formatRBString returns string w/dynamic values substituted. performs messageFormat like
operation on compound rb string: "You owe me {1}. Please pay by {2} or I will be forced to
shoot you with {3} bullets." this function will replace the place holders {1}, etc. with
values from the passed in array (or a single value, if that's all there are). required
arguments are rbString, the string containing the placeholders, and substituteValues either
an array or a single value containing the values to be substituted. note that the values
are substituted sequentially, all {1} placeholders will be substituted using the first
element in substituteValues, {2} with the second, etc. DEPRECATED. only retained for
backwards compatibility. please use messageFormat method instead.
- messageFormat returns string w/dynamic values substituted. performs MessageFormat
operation on compound rb string. required arguments: pattern string to use as pattern for
formatting, args array of "objects" to use as substitution values. optional argument is
locale, java style locale ID, "th_TH", default is "en_US". for details about format
options please see http://java.sun.com/j2se/1.4.2/docs/api/java/text/MessageFormat.html
- verifyPattern verifies MessageFormat pattern. required argument is pattern a string
holding the MessageFormat pattern to test. returns a boolean indicating if the pattern is
ok or not. PUBLIC
--->
<!--- default init --->
<cfscript>
rB=createObject("java", "java.util.PropertyResourceBundle");
fis=createObject("java", "java.io.FileInputStream");
msgFormat=createObject("java", "java.text.MessageFormat");
locale=createObject("java","java.util.Locale");
</cfscript>
<cffunction access="public" name="getResourceBundle" output="No" returntype="struct" hint="reads and parses java resource bundle per locale">
<cfargument name="rbFile" required="Yes" type="string">
<cfargument name="rbLocale" required="No" type="string" default="en_US">
<cfargument name="markDebug" required="No" type="boolean" default="false">
<cfscript>
var isOk=false; // success flag
var keys=""; // var to hold rb keys
var resourceBundle=structNew(); // structure to hold resource bundle
var thisKey="";
var thisMSG="";
var thisLang=listFirst(arguments.rbLocale,"_");
var thisDir=GetDirectoryFromPath(arguments.rbFile);
var thisFile=getFileFromPath(arguments.rbFile);
var thisRBfile=thisDir & listFirst(thisFile,".") & "_"& arguments.rbLocale & "." & listLast(thisFile,".");
if (NOT fileExists(thisRBfile)) //try just the language
thisRBfile=thisDir & listFirst(thisFile,".") & "_"& thisLang & "." & listLast(thisFile,".");
if (NOT fileExists(thisRBfile))// still nothing? strip thisRBfile back to base rb
thisRBFile=arguments.rbFile;
if (fileExists(thisRBFile)) { // final check, if this fails the file is not where it should be
isOK=true;
fis.init(thisRBFile);
rB.init(fis);
keys=rB.getKeys();
while (keys.hasMoreElements()) {
thisKEY=keys.nextElement();
thisMSG=rB.handleGetObject(thisKey);
if (arguments.markDebug)
resourceBundle["#thisKEY#"]="****"&thisMSG;
else
resourceBundle["#thisKEY#"]=thisMSG;
}
fis.close();
}
</cfscript>
<cfif isOK>
<cfreturn resourceBundle>
<cfelse>
<cfthrow message="#e.message#" detail="#e.detail#" type="#e.type#">
</cfif>
</cffunction>
<cffunction access="public" name="getRBKeys" output="No" returntype="array" hint="returns array of keys in java resource bundle per locale">
<cfargument name="rbFile" required="Yes" type="string">
<cfargument name="rbLocale" required="No" type="string" default="en_US">
<cfscript>
var isOk=false; // success flag
var keys=arrayNew(1); // var to hold rb keys
var rbKeys="";
var thisLang=listFirst(arguments.rbLocale,"_");
var thisDir=GetDirectoryFromPath(arguments.rbFile);
var thisFile=getFileFromPath(arguments.rbFile);
var thisRBfile=thisDir & listFirst(thisFile,".") & "_"& arguments.rbLocale & "." & listLast(thisFile,".");
if (NOT fileExists(thisRBfile)) //try just the language
thisRBfile=thisDir & listFirst(thisFile,".") & "_"& thisLang & "." & listLast(thisFile,".");
if (NOT fileExists(thisRBfile))// still nothing? strip thisRBfile back to base rb
thisRBFile=arguments.rbFile;
if (fileExists(thisRBFile)) { // final check
isOK=true;
fis.init(thisRBFile);
rB.init(fis);
rbKeys=rB.getKeys();
while (rbKeys.hasMoreElements()) {
arrayAppend(keys,rbKeys.nextElement());
}
fis.close();
}
</cfscript>
<cfif isOK>
<cfreturn keys>
<cfelse>
<cfthrow message="#e.message#" detail="#e.detail#" type="#e.type#">
</cfif>
</cffunction>
<cffunction access="public" name="getRBString" output="No" returntype="string" hint="returns text for given key in given java resource bundle per locale">
<cfargument name="rbFile" required="Yes" type="string">
<cfargument name="rbKey" required="Yes" type="string">
<cfargument name="rbLocale" required="No" type="string" default="en_US">
<cfscript>
var isOk=false; // success flag
var rbString=""; // text message to return
var resourceBundle=structNew(); // structure to hold resource bundle
var thisLang=listFirst(arguments.rbLocale,"_");
var thisDir=GetDirectoryFromPath(arguments.rbFile);
var thisFile=getFileFromPath(arguments.rbFile);
var thisRBfile=thisDir & listFirst(thisFile,".") & "_"& arguments.rbLocale & "." & listLast(thisFile,".");
if (NOT fileExists(thisRBfile)) //try just the language
thisRBfile=thisDir & listFirst(thisFile,".") & "_"& thisLang & "." & listLast(thisFile,".");
if (NOT fileExists(thisRBfile))// still nothing? strip thisRBfile back to base rb
thisRBFile=arguments.rbFile;
if (fileExists(thisRBFile)) { // final check
isOK=true;
fis.init(thisRBFile);
rB.init(fis);
rbString=rB.handleGetObject(arguments.rbKey);
fis.close();
}
</cfscript>
<cfif NOT isOK>
<cfthrow message="#e.message#" detail="#e.detail#" type="#e.type#">
<cfelse>
<cfif len(trim(rbString))>
<cfreturn rbString>
<cfelse>
<cfthrow message="Fatal error: resource bundle #thisRBfile# does not contain key #arguments.rbKEY#.">
</cfif>
</cfif>
</cffunction>
<cffunction name="loadResourceBundle" access="public" output="no" returnType="void" hint="Loads a bundle">
<cfargument name="rbFile" required="yes" type="string">
<cfargument name="rbLocale" required="no" type="string" default="en_US">
<cfset variables.resourceBundle = getResourceBundle(arguments.rbFile,arguments.rbLocale)>
</cffunction>
<cffunction name="formatRBString" access="public" output="no" returnType="string" hint="performs messageFormat like operation on compound rb string">
<cfargument name="rbString" required="yes" type="string">
<cfargument name="substituteValues" required="yes"> <!--- array or single value to format --->
<cfset var i=0>
<cfset tmpStr=arguments.rbString>
<cfif isArray(arguments.substituteValues)> <!--- do a bunch? --->
<cfloop index="i" from="1" to="#arrayLen(arguments.substituteValues)#">
<cfset tmpStr=replace(tmpStr,"{#i#}",arguments.substituteValues[i],"ALL")>
</cfloop>
<cfelse> <!--- do single --->
<cfset tmpStr=replace(tmpStr,"{1}",arguments.substituteValues,"ALL")>
</cfif> <!--- do a bunch? --->
<cfreturn tmpStr>
</cffunction>
<cffunction name="messageFormat" access="public" output="no" returnType="string" hint="performs messageFormat on compound rb string">
<cfargument name="thisPattern" required="yes" type="string" hint="pattern to use in formatting">
<cfargument name="args" required="yes" hint="substitution values"> <!--- array or single value to format --->
<cfargument name="thisLocale" required="no" default="en_US" hint="locale to use in formatting, defaults to en_US">
<cfset var pattern=createObject("java","java.util.regex.Pattern")>
<cfset var regexStr="(\{[0-9]{1,},number.*?\})">
<cfset var p="">
<cfset var m="">
<cfset var i=0>
<cfset var thisFormat="">
<cfset var inputArgs=arguments.args>
<cfset var lang="">
<cfset var country="">
<cfset var variant="">
<cfset var tLocale="">
<cftry>
<cfset lang=listFirst(arguments.thisLocale,"_")>
<cfif listLen(arguments.thisLocale,"_") GT 1>
<cfset country=listGetAt(arguments.thisLocale,2,"_")>
<cfset variant=listLast(arguments.thisLocale,"_")>
</cfif>
<cfset tLocale=variables.locale.init(lang,country,variant)>
<cfif NOT isArray(inputArgs)>
<cfset inputArgs=listToArray(inputArgs)>
</cfif>
<cfset thisFormat=msgFormat.init(arguments.thisPattern,tLocale)>
<!--- let's make sure any cf numerics are cast to java datatypes --->
<cfset p=pattern.compile(regexStr,pattern.CASE_INSENSITIVE)>
<cfset m=p.matcher(arguments.thisPattern)>
<cfloop condition="#m.find()#">
<cfset i=listFirst(replace(m.group(),"{",""))>
<cfset inputArgs[i]=javacast("float",inputArgs[i])>
</cfloop>
<cfset arrayPrepend(inputArgs,"")> <!--- dummy element to fool java --->
<!--- coerece to a java array of objects --->
<cfreturn thisFormat.format(inputArgs.toArray())>
<cfcatch type="Any">
<cfthrow message="#cfcatch.message#" type="any" detail="#cfcatch.detail#">
</cfcatch>
</cftry>
</cffunction>
<cffunction name="verifyPattern" access="public" output="no" returnType="boolean" hint="performs verification on MessageFormat pattern">
<cfargument name="pattern" required="yes" type="string" hint="format pattern to test">
<cfscript>
var test="";
var isOK=true;
try {
test=msgFormat.init(arguments.pattern);
}
catch (Any e) {
isOK=false;
}
return isOk;
</cfscript>
</cffunction>
<!--- remove for production? --->
<cffunction name="dumpMe" access="public" returntype="any" output="No">
<cfset var tmpStr="">
<cfsavecontent variable="tmpStr">
<cfdump var="#variables#"/>
</cfsavecontent>
<cfreturn tmpStr>
</cffunction>
</cfcomponent>