source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XSLTUtil.java@ 35745

Last change on this file since 35745 was 35745, checked in by cstephen, 2 years ago

Modified the Javascript object graph that is generated in XSLTUtil.java#getInterfaceStringsAsJavascript(....) to use empty objects for the nodes, rather than arrays

  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1/*
2 * XSLTUtil.java
3 * Copyright (C) 2008 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.util;
20
21import java.io.ByteArrayInputStream;
22import java.io.File;
23import java.io.UnsupportedEncodingException;
24import java.net.URLEncoder;
25import java.text.DateFormat;
26import java.text.SimpleDateFormat;
27import java.util.ArrayList;
28import java.util.Date;
29import java.util.Enumeration;
30import java.util.HashMap;
31import java.util.HashSet;
32import java.util.Locale;
33
34import javax.xml.parsers.DocumentBuilder;
35import javax.xml.parsers.DocumentBuilderFactory;
36
37import net.tanesha.recaptcha.ReCaptcha;
38import net.tanesha.recaptcha.ReCaptchaFactory;
39
40import org.apache.commons.lang3.StringUtils;
41import org.apache.log4j.Logger;
42import org.greenstone.util.GlobalProperties;
43import org.w3c.dom.Node;
44
45/**
46 * a class to contain various static methods that are used by the xslt
47 * stylesheets
48 */
49public class XSLTUtil
50{
51 protected static HashMap<String, ArrayList<String>> _foundTableValues = new HashMap<String, ArrayList<String>>();
52 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.XSLTUtil.class.getName());
53 protected static HashMap<String, String> _stringVariables = new HashMap<String, String>();
54
55 public static void storeString(String name, String value)
56 {
57 _stringVariables.put(name, value);
58 }
59
60 public static String getString(String name)
61 {
62 return _stringVariables.get(name);
63 }
64
65 /* some tests */
66 public static boolean equals(String s1, String s2)
67 {
68 return s1.equals(s2);
69 }
70
71 public static boolean notEquals(String s1, String s2)
72 {
73 return !s1.equals(s2);
74 }
75
76 public static boolean exists(String s1, String s2)
77 {
78 return !s1.equals("");
79 }
80
81 public static boolean contains(String s1, String s2)
82 {
83 return (s1.indexOf(s2) != -1);
84 }
85
86 public static boolean startsWith(String s1, String s2)
87 {
88 return s1.startsWith(s2);
89 }
90
91 public static boolean endsWith(String s1, String s2)
92 {
93 return s1.endsWith(s2);
94 }
95
96 public static boolean lessThan(String s1, String s2)
97 {
98 return (s1.compareTo(s2) < 0);
99 }
100
101 public static boolean lessThanOrEquals(String s1, String s2)
102 {
103 return (s1.compareTo(s2) <= 0);
104 }
105
106 public static boolean greaterThan(String s1, String s2)
107 {
108 return (s1.compareTo(s2) > 0);
109 }
110
111 public static boolean greaterThanOrEquals(String s1, String s2)
112 {
113 return (s1.compareTo(s2) >= 0);
114 }
115
116 public static boolean csvContains(String user_groups, String this_group)
117 {
118 String[] groups_array = user_groups.split(",");
119 for (int i=0; i<groups_array.length; i++) {
120 if (groups_array[i].equals(this_group)) {
121 return true;
122 }
123 }
124 return false;
125
126 }
127 public static boolean oidIsMatchOrParent(String first, String second)
128 {
129 if (first.equals(second))
130 {
131 return true;
132 }
133
134 String[] firstParts = first.split(".");
135 String[] secondParts = second.split(".");
136
137 if (firstParts.length >= secondParts.length)
138 {
139 return false;
140 }
141
142 for (int i = 0; i < firstParts.length; i++)
143 {
144 if (!firstParts[i].equals(secondParts[i]))
145 {
146 return false;
147 }
148 }
149
150 return true;
151 }
152
153 public static String oidDocumentRoot(String oid)
154 {
155 String[] oidParts = oid.split("\\.");
156
157 return oidParts[0];
158 }
159
160 public static String replace(String orig, String match, String replacement)
161 {
162 return orig.replace(match, replacement);
163 }
164
165 public static String getNumberedItem(String list, int number)
166 {
167 String[] items = list.split(",", -1); //String[] items = StringUtils.split(list, ",", -1);
168 // Using StringUtils.split() causes an off-by-one error for the boolean operators (fqk)
169 // where boolean operators combining rows in multiforms are shifted up by 1 row.
170
171 if (items.length > number)
172 {
173 return items[number];
174 }
175 return ""; // index out of bounds
176 }
177
178 public static String getFormattedCCSSelection(String collections, String groups) {
179
180 String result = ",";
181 if (collections != null && !collections.equals("")) {
182 result += collections+",";
183 }
184 if (groups != null && !groups.equals("")) {
185 String[] gps = groups.split(",");
186 for (int i=0; i<gps.length; i++) {
187 result += "group."+gps[i].replace('/','.') +",";
188 }
189 }
190 return result;
191 }
192 /**
193 * Generates links to equivalent documents for a document with a default
194 * document icon/type. Links are generated from the parameters: a list of
195 * document icons which are each in turn embedded in the matching starting
196 * link tag in the list of docStartLinks (these starting links link to the
197 * equivalent documents in another format). Each link's start tag is closed
198 * with the corresponding closing tag in the docEndLinks list. Parameter
199 * token is the list separator. Parameter divider is the string that should
200 * separate each final link generated from the next. Returns a string that
201 * represents a sequence of links to equivalent documents, where the anchor
202 * is a document icon.
203 */
204 public static String getEquivDocLinks(String token, String docIconsString, String docStartLinksString, String docEndLinksString, String divider)
205 {
206 String[] docIcons = StringUtils.split(docIconsString, token, -1);
207 String[] startLinks = StringUtils.split(docStartLinksString, token, -1);
208 String[] endLinks = StringUtils.split(docEndLinksString, token, -1);
209
210 StringBuffer buffer = new StringBuffer();
211 for (int i = 0; i < docIcons.length; i++)
212 {
213 if (i > 0)
214 {
215 buffer.append(divider);
216 }
217 buffer.append(startLinks[i] + docIcons[i] + endLinks[i]);
218 }
219
220 return buffer.toString();
221 }
222
223 public static String getInterfaceText(String interface_name, String lang, String key)
224 {
225 return getInterfaceTextWithArgs(interface_name, lang, key, null);
226 }
227
228 public static String getInterfaceText(String interface_name, String lang, String key, String args_str)
229 {
230 String[] args = null;
231 if (args_str != null && !args_str.equals(""))
232 {
233 args = StringUtils.split(args_str, ";");
234 }
235 return getInterfaceTextWithArgs(interface_name, lang, key, args);
236 }
237
238 public static String getInterfaceText(String interface_name, String dictionary_name, String lang, String key, String args_str)
239 {
240 // now we allow looking for files in the interface's resources folder
241 CustomClassLoader my_loader = new CustomClassLoader(XSLTUtil.class.getClassLoader(), GSFile.interfaceResourceDir(GlobalProperties.getGSDL3Home(), interface_name));
242 String[] args = null;
243 if (args_str != null && !args_str.equals(""))
244 {
245 args = StringUtils.split(args_str, ";");
246 }
247
248 // try the specified dictionary first
249 Dictionary dict = new Dictionary(dictionary_name, lang, my_loader);
250 String result = dict.get(key, args);
251 if (result == null) {
252 // fall back to a general interface text search
253 return getInterfaceTextWithArgs(interface_name, lang, key, args);
254 }
255 result = result.replaceAll("__INTERFACE_NAME__", interface_name); // do we need to so this here?
256 return result;
257 }
258
259 public static String getInterfaceTextWithDOM(String interface_name, String lang, String key, Node arg_node)
260 {
261 return getInterfaceTextWithDOMMulti(interface_name, lang, key, arg_node);
262 }
263
264 public static String getInterfaceTextWithDOM(String interface_name, String lang, String key, Node arg1_node, Node arg2_node)
265 {
266 return getInterfaceTextWithDOMMulti(interface_name, lang, key, arg1_node, arg2_node);
267 }
268
269 public static String getInterfaceTextWithDOMMulti(String interface_name, String lang, String key, Node... nodes)
270 {
271 int num_nodes = nodes.length;
272 String[] args = null;
273 if (num_nodes != 0)
274 {
275 args = new String[num_nodes];
276
277 for (int i = 0; i < num_nodes; i++)
278 {
279 String node_str = XMLConverter.getString(nodes[i]);
280 args[i] = node_str;
281 }
282 }
283 return getInterfaceTextWithArgs(interface_name, lang, key, args);
284
285 }
286
287 /* This is the base method that actually does the work of looking up the various chain of dictionaries */
288 public static String getInterfaceTextWithArgs(String interface_name, String lang, String key, String[] args)
289 {
290 // now we allow looking for files in the interface's resources folder
291 CustomClassLoader my_loader = new CustomClassLoader(XSLTUtil.class.getClassLoader(), GSFile.interfaceResourceDir(GlobalProperties.getGSDL3Home(), interface_name));
292 Dictionary dict = new Dictionary("interface_" + interface_name, lang, my_loader);
293
294 String result = dict.get(key, args);
295 if (result == null)
296 {
297 //if not found, search a separate subdirectory named by the interface name. this is used for eg the flax interface. this could be replaced by new class loader option?
298 String sep_interface_dir = interface_name + File.separatorChar + lang + File.separatorChar + "interface";
299 dict = new Dictionary(sep_interface_dir, lang);
300 result = dict.get(key, args);
301 if (result != null)
302 {
303 return result;
304 }
305 }
306
307 if (result == null && !interface_name.startsWith("default")) {
308 // not found, try the default interface
309 if (interface_name.endsWith("2")) { // hack for interface_xxx2.properties
310 dict = new Dictionary("interface_default2", lang);
311 } else {
312 dict = new Dictionary("interface_default", lang);
313
314 }
315 result = dict.get(key, args);
316 }
317
318 if (result == null)
319 { // not found
320 return "?" + key + "?";
321 }
322 result = result.replaceAll("__INTERFACE_NAME__", interface_name);
323
324 return result;
325
326
327
328 }
329 public static String getInterfaceTextSubstituteArgs(String value, String args_str)
330 {
331 String[] args = null;
332 if (args_str != null && !args_str.equals("")) {
333 args = StringUtils.split(args_str, ";");
334 }
335
336 return Dictionary.processArgs(value,args);
337 }
338
339 public static Node getCollectionText(String collection, String site_name, String lang, String key)
340 {
341 return getCollectionTextWithArgs(collection, site_name, lang, key, null);
342 }
343
344 public static Node getCollectionText(String collection, String site_name, String lang, String key, String args_str)
345 {
346
347 String[] args = null;
348 if (args_str != null && !args_str.equals(""))
349 {
350 args = StringUtils.split(args_str, ";");
351 }
352
353 return getCollectionTextWithArgs(collection, site_name, lang, key, args);
354 }
355
356 // xslt didn't like calling the function with Node varargs, so have this hack for now
357 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1)
358 {
359 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1);
360 }
361
362 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1, Node n2)
363 {
364 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1, n2);
365 }
366
367 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1, Node n2, Node n3)
368 {
369 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1, n2, n3);
370 }
371
372 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1, Node n2, Node n3, Node n4)
373 {
374 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1, n2, n3, n4);
375 }
376
377 public static Node getCollectionTextWithDOMMulti(String collection, String site_name, String lang, String key, Node... nodes)
378 {
379 int num_nodes = nodes.length;
380 String[] args = null;
381 if (num_nodes != 0)
382 {
383 args = new String[num_nodes];
384
385 for (int i = 0; i < num_nodes; i++)
386 {
387 String node_str = XMLConverter.getString(nodes[i]);
388 args[i] = node_str;
389 }
390 }
391 return getCollectionTextWithArgs(collection, site_name, lang, key, args);
392 }
393
394 public static Node getCollectionTextWithArgs(String collection, String site_name, String lang, String key, String[] args)
395 {
396 try
397 {
398 DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
399
400 CustomClassLoader class_loader = new CustomClassLoader(XSLTUtil.class.getClassLoader(), GSFile.collectionResourceDir(GSFile.siteHome(GlobalProperties.getGSDL3Home(), site_name), collection));
401 Dictionary dict = new Dictionary("interface_custom", lang, class_loader);
402 String result = dict.get(key, args);
403 if (result != null)
404 {
405 return docBuilder.parse(new ByteArrayInputStream(("<fragment>" + result + "</fragment>").getBytes("UTF-8"))).getDocumentElement();
406 }
407 return docBuilder.parse(new ByteArrayInputStream(("<fragment>" + "text:" + collection + ":" + key + "</fragment>").getBytes())).getDocumentElement();
408 }
409 catch (Exception ex)
410 {
411 return null;
412 }
413 }
414
415 public static String getGenericText(String dictionary_name, String lang, String key) {
416 return getGenericTextWithArgs(dictionary_name, lang, key, null);
417 }
418
419 public String getGenericText(String dictionary_name, String lang, String key, String args_str) {
420 String[] args = null;
421 if (args_str != null && !args_str.equals("")) {
422 args = StringUtils.split(args_str, ";");
423 }
424 return getGenericTextWithArgs(dictionary_name, lang, key, args);
425 }
426
427 public static String getGenericTextWithArgs(String dictionary_name, String lang, String key, String[] args)
428 {
429 Dictionary dict = new Dictionary(dictionary_name, lang);
430 String result = dict.get(key, args);
431 if (result == null) {
432 return "_"+dictionary_name+"_"+key+"_";
433 }
434 return result;
435 }
436
437
438
439 public static boolean isImage(String mimetype)
440 {
441 if (mimetype.startsWith("image/"))
442 {
443 return true;
444 }
445 return false;
446 }
447
448 // formatting /preprocessing functions
449 // some require a language, so we'll have a language param for all
450 public static String toLower(String orig, String lang)
451 {
452 return orig.toLowerCase();
453 }
454
455 public static String toUpper(String orig, String lang)
456 {
457 return orig.toUpperCase();
458 }
459
460 public static String tidyWhitespace(String original, String lang)
461 {
462
463 if (original == null || original.equals(""))
464 {
465 return original;
466 }
467 String new_s = original.replaceAll("\\s+", " ");
468 return new_s;
469 }
470
471 public static String stripWhitespace(String original, String lang)
472 {
473
474 if (original == null || original.equals(""))
475 {
476 return original;
477 }
478 String new_s = original.replaceAll("\\s+", "");
479 return new_s;
480 }
481
482 public static byte[] toUTF8(String orig, String lang)
483 {
484 try
485 {
486 byte[] utf8 = orig.getBytes("UTF-8");
487 return utf8;
488 }
489 catch (Exception e)
490 {
491 logger.error("unsupported encoding");
492 return orig.getBytes();
493 }
494 }
495
496 public static String formatDate(String date, String lang)
497 {
498 String in_pattern = "yyyyMMdd";
499 String out_pattern = "dd MMMM yyyy";
500 if (date.length() == 6)
501 {
502 in_pattern = "yyyyMM";
503 out_pattern = "MMMM yyyy";
504 }
505 // remove the 00
506 else if (date.length() == 8 && date.endsWith("00")) {
507 date = date.substring(0,6);
508 in_pattern = "yyyyMM";
509 out_pattern = "MMMM yyyy";
510 }
511
512 SimpleDateFormat formatter = new SimpleDateFormat(in_pattern, new Locale(lang));
513 try
514 {
515 Date d = formatter.parse(date);
516 formatter.applyPattern(out_pattern);
517 String new_date = formatter.format(d);
518 return new_date;
519 }
520 catch (Exception e)
521 {
522 return date;
523 }
524
525 }
526
527 public static final int TS_SECS = 0;
528 public static final int TS_MILLISECS = 1;
529 public static final int F_DATE = 0;
530 public static final int F_TIME = 1;
531 public static final int F_DATETIME = 2;
532 public static final int F_DAYSAGO = 3;
533
534 public static String formatTimeStamp(String timestamp, int ts_type, int format_type, String lang) {
535 try {
536 long ts = Long.parseLong(timestamp);
537 if (ts_type == TS_SECS) {
538 ts = ts * 1000;
539 }
540 if (format_type == F_DAYSAGO) {
541 long current_time = new Date().getTime();
542 long days = (current_time - ts)/86400000;
543 return String.valueOf(days);
544 }
545 Date d = new Date(ts);
546 DateFormat df;
547 switch (format_type) {
548 case F_DATE:
549 df = DateFormat.getDateInstance(DateFormat.DEFAULT, new Locale(lang));
550 break;
551 case F_TIME:
552 df = DateFormat.getTimeInstance(DateFormat.DEFAULT, new Locale(lang));
553 break;
554 case F_DATETIME:
555 df = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, new Locale(lang));
556 break;
557 default:
558 df = DateFormat.getDateInstance(DateFormat.DEFAULT, new Locale(lang));
559 break;
560 }
561
562 return df.format(d);
563 } catch (Exception e) {
564
565 return timestamp + e.getMessage();
566 }
567
568 }
569 public static String getDetailFromDate(String date, String detail, String lang)
570 {
571 String in_pattern = "yyyyMMdd";
572 if (date.length() == 6)
573 {
574 in_pattern = "yyyyMM";
575 }
576 // remove the 00
577 else if (date.length() == 8 && date.endsWith("00")) {
578 date = date.substring(0,6);
579 in_pattern = "yyyyMM";
580 }
581
582 SimpleDateFormat formatter = new SimpleDateFormat(in_pattern, new Locale(lang));
583 try
584 {
585 Date d = formatter.parse(date);
586 if (detail.toLowerCase().equals("day"))
587 {
588 formatter.applyPattern("dd");
589 }
590 else if (detail.toLowerCase().equals("month"))
591 {
592 formatter.applyPattern("MMMM");
593 }
594 else if (detail.toLowerCase().equals("year"))
595 {
596 formatter.applyPattern("yyyy");
597 }
598 else
599 {
600 return "";
601 }
602 return formatter.format(d);
603 }
604 catch (Exception ex)
605 {
606 return "";
607 }
608 }
609
610 public static String formatLanguage(String display_lang, String lang)
611 {
612
613 return new Locale(display_lang).getDisplayLanguage(new Locale(lang));
614 }
615
616 public static boolean checkFileExistence(String site_name, String filePath){
617
618 String gsdl3_home = GlobalProperties.getGSDL3Home();
619 //Remove leading file separator
620 filePath = filePath.replaceAll("^/+", "");
621 //Remove duplicates and replace by separator for current platform
622 filePath = filePath.replaceAll("/+", File.separator);
623 //Create full path to check
624 String fullPath = GSFile.siteHome(gsdl3_home, site_name) + File.separator + filePath;
625 File file = new File(fullPath);
626 if (file.exists() && file.isFile()) {
627 return true;
628 }
629 return false;
630 }
631
632 public static String uriEncode(String input)
633 {
634 String result = "";
635 try {
636 result = URLEncoder.encode(input, "UTF-8");
637 } catch (UnsupportedEncodingException e) {
638 e.printStackTrace();
639 }
640
641 return result;
642
643 }
644
645 public static String cgiSafe(String original, String lang)
646 {
647
648 original = original.replace('&', ' ');
649 original = original.replaceAll(" ", "%20");
650 return original;
651 }
652
653 public static String formatBigNumber(String num, String lang)
654 {
655
656 String num_str = num;
657 char[] num_chars = num_str.toCharArray();
658 String zero_str = "";
659 String formatted_str = "";
660
661 for (int i = num_chars.length - 4; i >= 0; i--)
662 {
663 zero_str += '0';
664 }
665
666 String sig_str = "";
667 for (int i = 0; i < 3 && i < num_chars.length; i++)
668 {
669 sig_str = sig_str + num_chars[i];
670 if (i == 1 && i + 1 < num_chars.length)
671 {
672 sig_str = sig_str + ".";
673 }
674 }
675
676 int sig_int = Math.round(Float.parseFloat(sig_str));
677 String new_sig_str = sig_int + "";
678 if (sig_str.length() > 2)
679 {
680 new_sig_str = sig_int + "0";
681 }
682
683 char[] final_chars = (new_sig_str + zero_str).toCharArray();
684 int count = 1;
685 for (int i = final_chars.length - 1; i >= 0; i--)
686 {
687 formatted_str = final_chars[i] + formatted_str;
688 if (count == 3 && i != 0)
689 {
690 formatted_str = "," + formatted_str;
691 count = 1;
692 }
693 else
694 {
695 count++;
696 }
697 }
698 return formatted_str;
699 }
700
701 public static String hashToSectionId(String hashString)
702 {
703 if (hashString == null || hashString.length() == 0)
704 {
705 return "";
706 }
707
708 int firstDotIndex = hashString.indexOf(".");
709 if (firstDotIndex == -1)
710 {
711 return "";
712 }
713
714 String sectionString = hashString.substring(firstDotIndex + 1);
715
716 return sectionString;
717 }
718
719 public static String hashToDepthClass(String hashString)
720 {
721 if (hashString == null || hashString.length() == 0)
722 {
723 return "";
724 }
725
726 String sectionString = hashToSectionId(hashString);
727
728 int count = sectionString.split("\\.").length;
729
730 if (sectionString.equals(""))
731 {
732 return "sectionHeaderDepthTitle";
733 }
734 else
735 {
736 return "sectionHeaderDepth" + count;
737 }
738 }
739
740 public static String escapeNewLines(String str)
741 {
742 if (str == null || str.length() < 1)
743 {
744 return null;
745 }
746 return str.replace("\n", "\\\n");
747 }
748
749 public static String escapeQuotes(String str)
750 {
751 if (str == null || str.length() < 1)
752 {
753 return null;
754 }
755 return str.replace("\"", "\\\"");
756 }
757 public static String escapeAngleBrackets(String str)
758 {
759 if (str == null || str.length() < 1)
760 {
761 return null;
762 }
763 return str.replace("<", "&lt;").replace(">", "&gt;");
764 }
765
766 public static String escapeNewLinesAndQuotes(String str)
767 {
768 if (str == null || str.length() < 1)
769 {
770 return null;
771 }
772 return escapeNewLines(escapeQuotes(str));
773 }
774
775 public static String escapeNewLinesQuotesAngleBracketsForJSString(String str)
776 {
777 // The \n and " becomes \\\n and \\\"
778 // but the <> are escaped/encoded for html, i.e. &gt; and &lt;
779 if (str == null || str.length() < 1)
780 {
781 return null;
782 }
783 return escapeAngleBrackets(escapeNewLines(escapeQuotes(str)));
784 }
785 public static String getGlobalProperty(String name)
786 {
787 return GlobalProperties.getProperty(name);
788 }
789
790 public static void clearMetadataStorage()
791 {
792 _foundTableValues.clear();
793 }
794
795 public static boolean checkMetadataNotDuplicate(String name, String value)
796 {
797 if (_foundTableValues.containsKey(name))
798 {
799 for (String mapValue : _foundTableValues.get(name))
800 {
801 if (mapValue.equals(value))
802 {
803 return false;
804 }
805 }
806 _foundTableValues.get(name).add(value);
807 return true;
808 }
809
810 ArrayList<String> newList = new ArrayList<String>();
811 newList.add(value);
812
813 _foundTableValues.put(name, newList);
814
815 return true;
816 }
817
818 public static String reCAPTCHAimage(String publicKey, String privateKey)
819 {
820 ReCaptcha c = ReCaptchaFactory.newReCaptcha(publicKey, privateKey, false);
821 return c.createRecaptchaHtml(null, null);
822 }
823
824 public static String getInterfaceStringsAsJavascript(String interface_name, String lang, String prefix)
825 {
826 String prependToPrefix = "gs.text";
827 return XSLTUtil.getInterfaceStringsAsJavascript(interface_name, lang, prefix, prependToPrefix);
828 }
829
830 /**
831 * Generates a Javascript object graph to store language strings. Leaf nodes contain the string and the previous node, the key.
832 * Further preceding nodes denote the prefix of the string (i.e. the gs3 language strings object, which interface they belong to etc.).
833 * Accessing a language string on a well-formed JS object graph will be similar to this: const myString = gs.text.atea.asr.Title;
834 * @param interface_name The name of the interface to retrieve language strings for.
835 * @param lang The language to retrieve.
836 * @param prefix The prefix to place the language strings under (e.g. atea.asr).
837 * @param prependToPrefix
838 * @return Javascript code that will generate the language string object graph.
839 */
840 public static String getInterfaceStringsAsJavascript(String interface_name, String lang, String prefix, String prependToPrefix)
841 {
842 // now we allow looking for files in the interface's resources folder
843 CustomClassLoader my_loader = new CustomClassLoader(XSLTUtil.class.getClassLoader(),
844 GSFile.interfaceResourceDir(GlobalProperties.getGSDL3Home(), interface_name));
845 String prefixwithdot = prefix + ".";
846
847 StringBuffer outputStr = new StringBuffer();
848 HashSet<String> initialisedDepths = new HashSet<>();
849
850 // Initialise the root prefix object
851 outputStr.append("if(!" + prependToPrefix + ") { ");
852 outputStr.append(prependToPrefix + " = {}; ");
853 outputStr.append("}\n");
854 initialisedDepths.add(prependToPrefix);
855
856 // Initialise the prefix object structure, handling '.' characters.
857 // JS identifies these as property accessors, hence requiring a new object for each 'level'.
858 String currentDepth = prependToPrefix;
859 String[] prefixComponents = prefix.split("\\.");
860
861 for (String element : prefixComponents) {
862 currentDepth += "." + element;
863
864 outputStr.append("if(!" + currentDepth + ") { ");
865 outputStr.append(currentDepth + " = {}; ");
866 outputStr.append("}\n");
867
868 initialisedDepths.add(currentDepth);
869 }
870
871 for (String dictName : new String[] { "interface_" + interface_name, "interface_default",
872 "interface_default2" }) {
873 // get all the keys from the english dictionary as this is a complete set
874 Dictionary dict = new Dictionary(dictName, "en", my_loader);
875 Enumeration keys = dict.getKeys();
876 if (keys == null) {
877 continue;
878 }
879
880 // Get all properties in the language-specific dictionary with the given key prefix
881 // Create Javascript strings of the form:
882 // prefixPath.key= "value";\n
883 while (keys.hasMoreElements()) {
884 String key = (String) keys.nextElement();
885 if (key.startsWith(prefixwithdot)) {
886 String[] keyComponents = key.split("\\.");
887 currentDepth = prependToPrefix + "." + prefix;
888
889 for (int i = prefixComponents.length; i < keyComponents.length - 1; i++) {
890 currentDepth += "." + keyComponents[i];
891
892 if (initialisedDepths.contains(currentDepth)) {
893 continue;
894 }
895
896 outputStr.append("if(!" + currentDepth + ") { ");
897 outputStr.append(currentDepth + " = {}; ");
898 outputStr.append("}\n");
899
900 initialisedDepths.add(currentDepth);
901 }
902
903 // get the language dependent value for the key. This will return the english if no value found for the given lang
904 String value = getInterfaceText(interface_name, dictName, lang, key, null);
905
906 outputStr.append(prependToPrefix);
907 outputStr.append(".");
908 outputStr.append(key);
909 outputStr.append("=\"");
910 outputStr.append(value);
911 outputStr.append("\";\n");
912 }
913 }
914 }
915
916 return outputStr.toString();
917 }
918
919 public static String xmlNodeToString(Node node)
920 {
921 return GSXML.xmlNodeToString(node);
922 }
923
924 // Test from cmdline with:
925 // java -classpath /research/ak19/gs3-svn/web/WEB-INF/lib/gsdl3.jar:/research/ak19/gs3-svn/web/WEB-INF/lib/log4j-1.2.8.jar:/research/ak19/gs3-svn/web/WEB-INF/classes/ org.greenstone.gsdl3.util.XSLTUtil
926 public static void main(String args[])
927 {
928 System.out.println("\n@@@@@\n" + XSLTUtil.getInterfaceStringsAsJavascript("default", "en", "dse", "gs.text") + "@@@@@\n");
929 }
930}
Note: See TracBrowser for help on using the repository browser.