/
XslUtil.java
364 lines (324 loc) · 12.1 KB
/
XslUtil.java
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
package org.fao.geonet.util;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jeeves.component.ProfileManager;
import jeeves.server.context.ServiceContext;
import org.fao.geonet.GeonetContext;
import org.fao.geonet.kernel.SchemaManager;
import org.fao.geonet.kernel.search.CodeListTranslator;
import org.fao.geonet.kernel.search.Translator;
import org.fao.geonet.utils.Log;
import org.fao.geonet.utils.Xml;
import org.fao.geonet.constants.Geonet;
import org.fao.geonet.kernel.search.LuceneSearcher;
import org.fao.geonet.languages.IsoLanguagesMapper;
import javax.annotation.Nonnull;
/**
* These are all extension methods for calling from xsl docs. Note: All
* params are objects because it is hard to determine what is passed in from XSLT.
* Most are converted to string by calling tostring.
*
* @author jesse
*/
public final class XslUtil
{
private static final char TS_DEFAULT = ' ';
private static final char CS_DEFAULT = ',';
private static final char TS_WKT = ',';
private static final char CS_WKT = ' ';
/**
* clean the src of ' and <>
*/
public static String clean(Object src)
{
String result = src.toString().replaceAll("'","\'").replaceAll("[><\n\r]", " ");
return result;
}
/**
* Returns 'true' if the pattern matches the src
*/
public static String countryMatch(Object src, Object pattern)
{
if( src.toString().trim().length()==0){
return "false";
}
boolean result = src.toString().toLowerCase().contains(pattern.toString().toLowerCase());
return String.valueOf(result);
}
/**
* Replace the pattern with the substitution
*/
public static String replace(Object src, Object pattern, Object substitution)
{
String result = src.toString().replaceAll(pattern.toString(), substitution.toString());
return result;
}
public static boolean isCasEnabled() {
return ProfileManager.isCasEnabled();
}
/**
* Check if bean is defined in the context
*
* @param beanId id of the bean to look up
*/
public static boolean existsBean(String beanId) {
return ProfileManager.existsBean(beanId);
}
/**
* Optimistically check if user can access a given url. If not possible to determine then
* the methods will return true. So only use to show url links, not check if a user has access
* for certain. Spring security should ensure that users cannot access restricted urls though.
*
* @param serviceName the raw services name (main.home) or (admin)
*
* @return true if accessible or system is unable to determine because the current
* thread does not have a ServiceContext in its thread local store
*/
public static boolean isAccessibleService(Object serviceName) {
return ProfileManager.isAccessibleService(serviceName);
}
/**
* Takes the characters until the pattern is matched
*/
public static String takeUntil(Object src, Object pattern)
{
String src2 = src.toString();
Matcher matcher = Pattern.compile(pattern.toString()).matcher(src2);
if( !matcher.find() )
return src2;
int index = matcher.start();
if( index==-1 ){
return src2;
}
return src2.substring(0,index);
}
/**
* Convert a serialized XML node in JSON
*
* @param xml
* @return
*/
public static String xmlToJson(Object xml) {
try {
return Xml.getJSON(xml.toString());
} catch (IOException e) {
Log.error(Geonet.GEONETWORK, "XMLtoJSON conversion I/O error. Error is " + e.getMessage() + ". XML is " + xml.toString());
}
return "";
}
/**
* Converts the seperators of the coords to the WKT from ts and cs
*
* @param coords the coords string to convert
* @param ts the separator that separates 2 coordinates
* @param cs the separator between 2 numbers in a coordinate
*/
public static String toWktCoords(Object coords, Object ts, Object cs){
String coordsString = coords.toString();
char tsString;
if( ts==null || ts.toString().length()==0){
tsString = TS_DEFAULT;
}else{
tsString = ts.toString().charAt(0);
}
char csString;
if( cs==null || cs.toString().length()==0){
csString = CS_DEFAULT;
}else{
csString = cs.toString().charAt(0);
}
if( tsString == TS_WKT && csString == CS_WKT ){
return coordsString;
}
if( tsString == CS_WKT ){
tsString=';';
coordsString = coordsString.replace(CS_WKT, tsString);
}
coordsString = coordsString.replace(csString, CS_WKT);
String result = coordsString.replace(tsString, TS_WKT);
char lastChar = result.charAt(result.length()-1);
if(result.charAt(result.length()-1)==TS_WKT || lastChar==CS_WKT ){
result = result.substring(0, result.length()-1);
}
return result;
}
public static String posListToWktCoords(Object coords, Object dim){
String[] coordsString = coords.toString().split(" ");
int dimension;
if( dim==null ){
dimension = 2;
}else{
try{
dimension=Integer.parseInt(dim.toString());
}catch (NumberFormatException e) {
dimension=2;
}
}
StringBuilder results = new StringBuilder();
for (int i = 0; i < coordsString.length; i++) {
if( i>0 && i%dimension==0 ){
results.append(',');
}else if( i>0 ){
results.append(' ');
}
results.append(coordsString[i]);
}
return results.toString();
}
/**
* Get field value for metadata identified by uuid.
*
* @param appName Web application name to access Lucene index from environment variable
* @param uuid Metadata uuid
* @param field Lucene field name
* @param lang Language of the index to search in
*
* @return metadata title or an empty string if Lucene index or uuid could not be found
*/
public static String getIndexField(Object appName, Object uuid, Object field, Object lang) {
String id = uuid.toString();
String fieldname = field.toString();
String language = (lang.toString().equals("") ? null : lang.toString());
try {
String fieldValue = LuceneSearcher.getMetadataFromIndex(language, id, fieldname);
if(fieldValue == null) {
return getIndexFieldById(appName,uuid,field,lang);
} else {
return fieldValue;
}
} catch (Exception e) {
Log.error(Geonet.GEONETWORK, "Failed to get index field value caused by " + e.getMessage());
return "";
}
}
public static String getIndexFieldById(Object appName, Object id, Object field, Object lang) {
String fieldname = field.toString();
String language = (lang.toString().equals("") ? null : lang.toString());
try {
String fieldValue = LuceneSearcher.getMetadataFromIndexById(language, id.toString(), fieldname);
return fieldValue == null ? "" : fieldValue;
} catch (Exception e) {
Log.error(Geonet.GEONETWORK, "Failed to get index field value caused by " + e.getMessage());
return "";
}
}
/**
* Return a translation for a codelist or enumeration element.
*
* @param codelist The codelist name (eg. gmd:MD_TopicCategoryCode)
* @param value The value to search for in the translation file
* @param langCode The language
* @return The translation or the code list value if not found.
*/
public static String getCodelistTranslation(Object codelist, Object value, Object langCode) {
String translation;
String codeListValue = (String) value;
try {
final GeonetContext gc = (GeonetContext) ServiceContext.get().getHandlerContext(Geonet.CONTEXT_NAME);
Translator t = new CodeListTranslator(gc.getBean(SchemaManager.class), (String) langCode, (String) codelist);
translation = t.translate(codeListValue);
} catch (Exception e) {
Log.error(Geonet.GEONETWORK, "Failed to translate codelist " + e.getMessage());
translation = codeListValue;
}
return translation;
}
/**
* Return 2 iso lang code from a 3 iso lang code. If any error occurs return "".
*
* @param iso3LangCode The 2 iso lang code
* @return The related 3 iso lang code
*/
public static @Nonnull String twoCharLangCode(String iso3LangCode) {
if(iso3LangCode==null || iso3LangCode.length() == 0) {
return Geonet.DEFAULT_LANGUAGE;
} else {
String iso2LangCode = null;
try {
if (iso3LangCode.length() == 2){
iso2LangCode = iso3LangCode;
} else {
if (ServiceContext.get() != null) {
final IsoLanguagesMapper mapper = ServiceContext.get().getBean(IsoLanguagesMapper.class);
iso2LangCode = mapper.iso639_2_to_iso639_1(iso3LangCode);
}
}
} catch (Exception ex) {
Log.error(Geonet.GEONETWORK, "Failed to get iso 2 language code for " + iso3LangCode + " caused by " + ex.getMessage());
}
if(iso2LangCode == null) {
return iso3LangCode.substring(0,2);
} else {
return iso2LangCode;
}
}
}
/**
* Return '' or error message if error occurs during URL connection.
*
* @param url The URL to ckeck
* @return
*/
public static String getUrlStatus(String url){
URL u;
URLConnection conn;
int connectionTimeout = 500;
try {
u = new URL(url);
conn = u.openConnection();
conn.setConnectTimeout(connectionTimeout);
// TODO : set proxy
if (conn instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) conn;
httpConnection.setInstanceFollowRedirects(true);
httpConnection.connect();
httpConnection.disconnect();
// FIXME : some URL return HTTP200 with an empty reply from server
// which trigger SocketException unexpected end of file from server
int code = httpConnection.getResponseCode();
if (code == HttpURLConnection.HTTP_OK) {
return "";
} else {
return "Status: " + code;
}
} // TODO : Other type of URLConnection
} catch (Throwable e) {
e.printStackTrace();
return e.toString();
}
return "";
}
public static String threeCharLangCode(String langCode) {
if (langCode == null || langCode.length() < 2) {
return Geonet.DEFAULT_LANGUAGE;
}
if (langCode.length() == 3) {
return langCode;
}
final ServiceContext serviceContext = ServiceContext.get();
if (serviceContext != null) {
final IsoLanguagesMapper mapper;
mapper = serviceContext.getBean(IsoLanguagesMapper.class);
return mapper.iso639_1_to_iso639_2(langCode);
} else {
return langCode;
}
}
public static boolean match(Object src, Object pattern) {
if (src == null || src.toString().trim().isEmpty()) {
return false;
}
return src.toString().matches(pattern.toString());
}
private static ThreadLocal<Boolean> allowScripting = new InheritableThreadLocal<Boolean>();
public static void setNoScript() {
allowScripting.set(false);
}
public static boolean allowScripting() {
return allowScripting.get() == null || allowScripting.get();
}
}