-
Notifications
You must be signed in to change notification settings - Fork 1
/
Utils.bbj
225 lines (197 loc) · 12.2 KB
/
Utils.bbj
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
REM /**
REM * <code>Utils</code> is a BBj custom data class that is used to provide helpful utility methods to the DWC TaskApp
REM */
REM Package TaskApp
class public Utils
REM /**
REM * Method to set multiple string-based user preferences via a HashMap to reduce client-server round trips
REM * <p>
REM * The get/setCookies() methods bypasses the effort of creating string templates and BBjTemplatedStrings as well
REM * as encoding information for safety and portability. You only have to provide a unique key value that's used to
REM * store the information (usually the app's name, but it can be virtually any string) and a HashMap filled
REM * with the information to store. The method iterates through the HashMap's keys and builds a string
REM * that consists of the HashMap's key/value pairs joined by the <code>"-,-"</code> characters in an
REM * attempt to provide a reasonable separator that won't interfere with the stored data.
REM * <p>
REM * Both get/setCookies() methods throw errors, so you may want to add an <code>,err=</code> branch when
REM * calling these methods. The getCookies() method will return a Hashmap filled with key/value pairs if
REM * the cookie exists. If it does not exist, it will return <code>null()</code>.
REM * <p>
REM * The corresponding <code>getCookies()</code> method is used to retrieve the stored information from the
REM * client's computer (GUI) or browser (BUI/DWC). You only need to provide the unique key value when getting
REM * the saved cookies, greatly simplifying the reading/writing of user properties
REM *
REM * @param BBjString p_cookieKey$ A BBjString with the unique identifier for the saved cookie, such as the application's name
REM * @param HashMap p_cookieHashMap! A HashMap filled with key/value pairs to be stored where the key is the field name and the value is the string value for that field
REM *
REM * @see <a href='https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/HashMap.html' target='_blank'>HashMap</a> for more information on the Java HashMap object
REM */
method public static void setCookies(BBjString p_cookieKey$, HashMap p_cookieHashMap!)
it! = p_cookieHashMap!.keySet().iterator()
while it!.hasNext()
key$ = it!.next()
value$ = str(p_cookieHashMap!.get(key$))
fullString$ = fullString$ + key$ + "-,-" + value$ + $0A$
wend
fullString$ = fullString$(1, len(fullString$)-1)
REM Encode the string contents and store it in the user properties based on the provided application key
encodedCookies$ = URLEncoder.encode(fullString$)
tc! = BBjAPI().getThinClient(err=ERR_GETTING_THINCLIENT)
tc!.setUserProperty(p_cookieKey$, encodedCookies$, err=ERR_WRITING_COOKIE)
methodret
ERR_GETTING_THINCLIENT:
throw "Error getting the BBjThinClient when trying to set cookies. The error message was: " + errmes(-1), 725
ERR_WRITING_COOKIE:
throw "Error saving cookie. The error message was: " + errmes(-1), 720
methodend
REM /**
REM * Method to get multiple string-based user preferences in a HashMap to reduce client-server round trips
REM * <p>
REM * The get/setCookies() methods offer a simple way to persist application setting via a HashMap. You
REM * save information by calling the setCookies() method providing a unique key value that's used to
REM * store the information (usually the app's name, but it can be virtually any string) and a HashMap filled
REM * with the information to store. You can then call the getCookies() method to retrieve the saved
REM * information in a HashMap. The methods bypass the effort of creating string templates and BBjTemplatedStrings
REM * as well as encoding information for safety and portability.
REM * <p>
REM * Both get/setCookies() methods throw errors, so you may want to add an <code>,err=</code> branch when
REM * calling these methods. The getCookies() method will return a Hashmap filled with key/value pairs if
REM * the cookie exists. If it does not exist, it will return <code>null()</code>.
REM *
REM * @param BBjString p_cookieKey$ A BBjString with the unique identifier for the saved cookie, such as the application's name
REM *
REM * @return HashMap A HashMap filled with key/value pairs, basically a clone of the HahMap provided to the setCookies() method. If the cookie doesn't exist on the client's machine or browser, the method retuns null().
REM */
method public static HashMap getCookies(BBjString p_cookieKey$)
declare HashMap hashCookies!
tc! = BBjAPI().getThinClient(err=ERR_GETTING_THINCLIENT)
prop$ = tc!.getUserProperty(p_cookieKey$, ERR=ERR_READING_COOKIE)
cookieValue! = URLDecoder.decode(prop$)
if (cookieValue! <> null()) then
hashCookies! = new HashMap()
fieldList! = java.util.Arrays.asList(cookieValue!.split($0A$))
for fieldNum = 0 to fieldList!.size()-1
keyVal! = fieldList!.get(fieldNum)
keyValVector! = java.util.Arrays.asList(keyVal!.split("-,-"))
hashCookies!.put(keyValVector!.get(0,err=*NEXT), keyValVector!.get(1,err=*NEXT))
next
endif
methodret hashCookies!
ERR_GETTING_THINCLIENT:
throw "Error getting the BBjThinClient when trying to get cookies. The error message was: " + errmes(-1), 725
ERR_READING_COOKIE:
if (err=11) then
methodret null()
else
throw "Error reading cookie. The error message was: " + errmes(-1), 720
endif
methodend
REM /**
REM * Logs the provided string into the user's browser Developer Tools console.
REM *
REM * Note that this is a convenience method that calls the consoleLogValues() method
REM * with an empty string for the second parameter (the value).
REM *
REM * @param BBjString logEntry! The information to display in the Developer Tools console
REM */
method public static void consoleLog(BBjString logEntry!)
#consoleLogValues(logEntry!, "")
methodend
REM /**
REM * Logs the provided strings, usually key/value pairs, into the user's browser Developer Tools console.
REM * <p>
REM * If you're developing with VS Code, you can use its debug capabilities so that the
REM * browser's Developer Tools console is available in VS Code's debug console. This
REM * allows you to view the browser's console output and interact with the interpreter
REM * from within VS Code.
REM *
REM * @param BBjString key! The first information to display in the Developer Tools console, typically the key in a key/value pair
REM * @param BBjString value! The second information to display in the Developer Tools console, typically the value in a key/value pair
REM */
method public static void consoleLogValues(BBjString key!, BBjString value!)
REM Sanitize the log entries by escaping single quotes
if (key! = null()) then key! = ""
if (value! = null()) then value! = ""
key! = key!.replaceAll("'", "\'")
value! = value!.replaceAll("'", "\'")
REM Define the CSS to format the console output
space! = " "
cssSpace! = "'background: white;'"
cssDebugPrefix! = "'background: hsl(60, 100%, 65%); color: hsl(350, 100%, 25%); padding: 2px 4px; border-radius: 3px; border: 1px solid hsl(350, 100%, 25%); font-weight: 700;'"
cssKey! = "'background: hsl(210, 90%, 94%); color: hsl(210, 35%, 35%); padding: 2px 4px; border-radius: 3px; border: 1px solid hsl(210, 35%, 35%);'"
cssValue! = "'background: hsl(115, 90%, 94%); color: hsl(115, 35%, 35%); padding: 2px 4px; border-radius: 3px; border: 1px solid hsl(115, 35%, 35%);'"
REM Define the JavaScript that logs the information
js! = "console.log('%cDebug Log:%c%s%c%s%c%s%c%s', " + cssDebugPrefix! + ", " + cssSpace! + ", `" + space! + "`," + cssKey! + ", `" + key! + "`," + cssSpace! + ", `" + space! + "`," + cssValue! + ",`" + value! + "`);"
REM Get the SysGui device and execute the JavaScript to log the information to the Developer Tools console
sg! = BBjAPI().getSysGui(err=*NEXT)
if (sg! = null()) then sg! = BBjAPI().openSysGui("X0"); sgChan! = sg!.getChannel()
sg!.executeScript(js!)
if (sgChan! <> null()) then close(sgChan!,err=*NEXT)
methodend
REM /**
REM * Utility method that sets a CSS custom property given the property and value.
REM * It ensures that the CSS property is properly formatted, then builds a CSS
REM * string from the information and adds it to the DOM, thus overriding any
REM * previous setting.
REM *
REM * @param BBjString property! A BBjString of the property name that will be set to the given value
REM * @param BBjString value! A BBjString of the value that propety will be set to
REM */
method public static void setCssProperty(BBjString property!, BBjString value!)
REM Sanitize the property by ensuring that it starts with '--' and changing all spaces to dashes
if !(property!.startsWith("--")) then property! = "--" + property!
property! = property!.replaceAll(" ", "-").trim()
value! = value!.trim()
REM If the value contains spaces, such as a font-family listing, then it encloses the string in single quotes
if (value!.contains(" ")) then value! = "'" + value! + "'"
REM Build the CSS string for the root element and append it to the DOM's <body> element
css! = ":root { " + property! + ": " + value! + "; }"
BBjAPI().getWebManager().injectStyle(css!, 0, "app_custom_css_property")
methodend
REM ================================================================================================
REM Convert a string to title case
REM ================================================================================================
REM /**
REM * Method to convert a given string to Title Case, meaning that the first letter of each word is capitalized and the rest is set to lowercase
REM * <p>
REM * Note that this is a convenience method to the more full-featured toTitleCase() method that allows you to optionally set whether the remainder strings are set to lowercase.
REM *
REM * @param BBjString string! A BBjString to be converted to Title Case
REM * @return BBjString The orginal string converted to Title Case
REM */
method public static BBjString toTitleCase(BBjString string!)
methodret #toTitleCase(string!, 1)
methodend
REM /**
REM * Method to convert a given string to Title Case, meaning that the first letter of each word is capitalized and the rest is optionally set to lowercase
REM *
REM * @param BBjString string! A BBjString to be converted to Title Case
REM * @param BBjNumber forceLowerCase A BBjNumber acting as a boolean that indicates whether the method should force all non-titlecase letters to lowercase (1) or not (0).
REM * @return BBjString The orginal string converted to Title Case
REM */
method public static BBjString toTitleCase(BBjString string!, BBjNumber forceLowerCase)
use java.lang.Character
declare auto StringBuilder rtnVal!
rtnVal! = new StringBuilder()
nextTitleCase = 1
if (forceLowerCase) then string! = string!.toLowerCase()
charArray! = string!.toCharArray()
for i = 0 to charArray!.length - 1
char! = charArray![i]
if !(Character.isLetterOrDigit(char!)) then
nextTitleCase = 1
else
if (nextTitleCase) then
char! = Character.toTitleCase(char!)
nextTitleCase = 0
endif
endif
rtnVal!.append(char!)
next
methodret rtnVal!.toString()
methodend
classend
REM Java USE Statements
use java.util.HashMap
use java.net.URLEncoder
use java.net.URLDecoder