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

Last change on this file since 26557 was 26557, checked in by sjm84, 11 years ago

Fixing string fragments being missing after some being moved to interface_default2.properties

  • Property svn:keywords set to Author Date Id Revision
File size: 20.3 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.text.SimpleDateFormat;
24import java.util.ArrayList;
25import java.util.Date;
26import java.util.Enumeration;
27import java.util.HashMap;
28import java.util.Locale;
29
30import javax.xml.parsers.DocumentBuilder;
31import javax.xml.parsers.DocumentBuilderFactory;
32
33import net.tanesha.recaptcha.ReCaptcha;
34import net.tanesha.recaptcha.ReCaptchaFactory;
35
36import org.apache.commons.lang3.StringUtils;
37import org.apache.log4j.Logger;
38import org.greenstone.util.GlobalProperties;
39import org.w3c.dom.Node;
40
41/**
42 * a class to contain various static methods that are used by the xslt
43 * stylesheets
44 */
45public class XSLTUtil
46{
47 protected static HashMap<String, ArrayList<String>> _foundTableValues = new HashMap<String, ArrayList<String>>();
48 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.XSLTUtil.class.getName());
49 protected static HashMap<String, String> _stringVariables = new HashMap<String, String>();
50
51 public static void storeString(String name, String value)
52 {
53 _stringVariables.put(name, value);
54 }
55
56 public static String getString(String name)
57 {
58 return _stringVariables.get(name);
59 }
60
61 /* some tests */
62 public static boolean equals(String s1, String s2)
63 {
64 return s1.equals(s2);
65 }
66
67 public static boolean notEquals(String s1, String s2)
68 {
69 return !s1.equals(s2);
70 }
71
72 public static boolean exists(String s1, String s2)
73 {
74 return !s1.equals("");
75 }
76
77 public static boolean contains(String s1, String s2)
78 {
79 return (s1.indexOf(s2) != -1);
80 }
81
82 public static boolean startsWith(String s1, String s2)
83 {
84 return s1.startsWith(s2);
85 }
86
87 public static boolean endsWith(String s1, String s2)
88 {
89 return s1.endsWith(s2);
90 }
91
92 public static boolean lessThan(String s1, String s2)
93 {
94 return (s1.compareTo(s2) < 0);
95 }
96
97 public static boolean lessThanOrEquals(String s1, String s2)
98 {
99 return (s1.compareTo(s2) <= 0);
100 }
101
102 public static boolean greaterThan(String s1, String s2)
103 {
104 return (s1.compareTo(s2) > 0);
105 }
106
107 public static boolean greaterThanOrEquals(String s1, String s2)
108 {
109 return (s1.compareTo(s2) >= 0);
110 }
111
112 public static boolean oidIsMatchOrParent(String first, String second)
113 {
114 if (first.equals(second))
115 {
116 return true;
117 }
118
119 String[] firstParts = first.split(".");
120 String[] secondParts = second.split(".");
121
122 if (firstParts.length >= secondParts.length)
123 {
124 return false;
125 }
126
127 for (int i = 0; i < firstParts.length; i++)
128 {
129 if (!firstParts[i].equals(secondParts[i]))
130 {
131 return false;
132 }
133 }
134
135 return true;
136 }
137
138 public static String oidDocumentRoot(String oid)
139 {
140 String[] oidParts = oid.split("\\.");
141
142 return oidParts[0];
143 }
144
145 public static String replace(String orig, String match, String replacement)
146 {
147 return orig.replace(match, replacement);
148 }
149
150 public static String getNumberedItem(String list, int number)
151 {
152 String[] items = StringUtils.split(list, ",", -1);
153 if (items.length > number)
154 {
155 return items[number];
156 }
157 return ""; // index out of bounds
158 }
159
160 /**
161 * Generates links to equivalent documents for a document with a default
162 * document icon/type. Links are generated from the parameters: a list of
163 * document icons which are each in turn embedded in the matching starting
164 * link tag in the list of docStartLinks (these starting links link to the
165 * equivalent documents in another format). Each link's start tag is closed
166 * with the corresponding closing tag in the docEndLinks list. Parameter
167 * token is the list separator. Parameter divider is the string that should
168 * separate each final link generated from the next. Returns a string that
169 * represents a sequence of links to equivalent documents, where the anchor
170 * is a document icon.
171 */
172 public static String getEquivDocLinks(String token, String docIconsString, String docStartLinksString, String docEndLinksString, String divider)
173 {
174 String[] docIcons = StringUtils.split(docIconsString, token, -1);
175 String[] startLinks = StringUtils.split(docStartLinksString, token, -1);
176 String[] endLinks = StringUtils.split(docEndLinksString, token, -1);
177
178 StringBuffer buffer = new StringBuffer();
179 for (int i = 0; i < docIcons.length; i++)
180 {
181 if (i > 0)
182 {
183 buffer.append(divider);
184 }
185 buffer.append(startLinks[i] + docIcons[i] + endLinks[i]);
186 }
187
188 return buffer.toString();
189 }
190
191 public static String getInterfaceText(String interface_name, String lang, String key)
192 {
193 return getInterfaceText(interface_name, lang, key, null);
194 }
195
196 public static String getInterfaceText(String interface_name, String lang, String key, String args_str)
197 {
198 key = key.replaceAll("__INTERFACE_NAME__", interface_name);
199
200 String[] args = null;
201 if (args_str != null && !args_str.equals(""))
202 {
203 args = StringUtils.split(args_str, ";");
204 }
205 Dictionary dict = new Dictionary("interface_" + interface_name, lang);
206 String result = dict.get(key, args);
207 if (result == null)
208 { // not found
209 //if not found, search a separate subdirectory named by the interface name
210 String sep_interface_dir = interface_name + File.separatorChar + lang + File.separatorChar + "interface";
211 dict = new Dictionary(sep_interface_dir, lang);
212 result = dict.get(key, args);
213 if (result != null)
214 {
215 result = result.replaceAll("__INTERFACE_NAME__", interface_name);
216 return result;
217 }
218 }
219
220 if (result == null && !interface_name.equals("default"))
221 { // not found, try the default interface
222 dict = new Dictionary("interface_default", lang);
223 result = dict.get(key, args);
224 }
225
226 if (result == null)
227 { // not found
228 return "_" + key + "_";
229 }
230 result = result.replaceAll("__INTERFACE_NAME__", interface_name);
231 return result;
232 }
233
234 public static String getInterfaceText(String interfaceName, String dictionaryName, String lang, String key, String args_str)
235 {
236 key = key.replaceAll("__INTERFACE_NAME__", interfaceName);
237
238 String[] args = null;
239 if (args_str != null && !args_str.equals(""))
240 {
241 args = StringUtils.split(args_str, ";");
242 }
243 Dictionary dict = new Dictionary(dictionaryName, lang);
244 String result = dict.get(key, args);
245 if (result == null)
246 { // not found
247 //if not found, search a separate subdirectory named by the interface name
248 String sep_interface_dir = interfaceName + File.separatorChar + lang + File.separatorChar + "interface";
249 dict = new Dictionary(sep_interface_dir, lang);
250 result = dict.get(key, args);
251 if (result != null)
252 {
253 result = result.replaceAll("__INTERFACE_NAME__", interfaceName);
254 return result;
255 }
256 }
257
258 if (result == null && !interfaceName.equals("default"))
259 { // not found, try the default interface
260 dict = new Dictionary("interface_default", lang);
261 result = dict.get(key, args);
262 }
263
264 if (result == null)
265 { // not found
266 return "_" + key + "_";
267 }
268 result = result.replaceAll("__INTERFACE_NAME__", interfaceName);
269 return result;
270 }
271
272 public static String getInterfaceTextWithDOM(String interface_name, String lang, String key, Node arg_node)
273 {
274 String[] args = new String[1];
275
276 String node_str = XMLConverter.getString(arg_node);
277 args[0] = node_str;
278 Dictionary dict = new Dictionary("interface_" + interface_name, lang);
279 String result = dict.get(key, args);
280 if (result == null)
281 { // not found
282 //if not found, search a separate subdirectory named by the interface name
283 String sep_interface_dir = interface_name + File.separatorChar + lang + File.separatorChar + "interface";
284 dict = new Dictionary(sep_interface_dir, lang);
285 result = dict.get(key, args);
286 if (result != null)
287 {
288 return result;
289 }
290 }
291
292 if (result == null && !interface_name.equals("default"))
293 { // not found, try the default interface
294 dict = new Dictionary("interface_default", lang);
295 result = dict.get(key, args);
296 }
297
298 if (result == null)
299 { // not found
300 return "_" + key + "_";
301 }
302
303 return result;
304 }
305
306 public static String getInterfaceTextWithDOM(String interface_name, String lang, String key, Node arg1_node, Node arg2_node)
307 {
308 String[] args = new String[2];
309
310 String node_str = XMLConverter.getString(arg1_node);
311 args[0] = node_str;
312 node_str = XMLConverter.getString(arg2_node);
313 args[1] = node_str;
314 Dictionary dict = new Dictionary("interface_" + interface_name, lang);
315 String result = dict.get(key, args);
316 if (result == null)
317 { // not found
318 //if not found, search a separate subdirectory named by the interface name
319 String sep_interface_dir = interface_name + File.separatorChar + lang + File.separatorChar + "interface";
320 dict = new Dictionary(sep_interface_dir, lang);
321 result = dict.get(key, args);
322 if (result != null)
323 {
324 return result;
325 }
326 }
327
328 if (result == null && !interface_name.equals("default"))
329 { // not found, try the default interface
330 dict = new Dictionary("interface_default", lang);
331 result = dict.get(key, args);
332 }
333
334 if (result == null)
335 { // not found
336 return "_" + key + "_";
337 }
338
339 return result;
340 }
341
342 public static Node getCollectionText(String collection, String site_name, String lang, String key)
343 {
344 return getCollectionTextWithArgs(collection, site_name, lang, key, null);
345 }
346
347 public static Node getCollectionText(String collection, String site_name, String lang, String key, String args_str)
348 {
349
350 String[] args = null;
351 if (args_str != null && !args_str.equals(""))
352 {
353 args = StringUtils.split(args_str, ";");
354 }
355
356 return getCollectionTextWithArgs(collection, site_name, lang, key, args);
357 }
358
359 // xslt didn't like calling the function with Node varargs, so have this hack for now
360 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1)
361 {
362 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1);
363 }
364
365 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1, Node n2)
366 {
367 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1, n2);
368 }
369
370 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1, Node n2, Node n3)
371 {
372 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1, n2, n3);
373 }
374
375 public static Node getCollectionTextWithDOM(String collection, String site_name, String lang, String key, Node n1, Node n2, Node n3, Node n4)
376 {
377 return getCollectionTextWithDOMMulti(collection, site_name, lang, key, n1, n2, n3, n4);
378 }
379
380 public static Node getCollectionTextWithDOMMulti(String collection, String site_name, String lang, String key, Node... nodes)
381 {
382 int num_nodes = nodes.length;
383 String[] args = null;
384 if (num_nodes != 0)
385 {
386 args = new String[num_nodes];
387
388 for (int i = 0; i < num_nodes; i++)
389 {
390 String node_str = XMLConverter.getString(nodes[i]);
391 args[i] = node_str;
392 }
393 }
394 return getCollectionTextWithArgs(collection, site_name, lang, key, args);
395 }
396
397 public static Node getCollectionTextWithArgs(String collection, String site_name, String lang, String key, String[] args)
398 {
399 try
400 {
401 DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
402
403 CollectionClassLoader class_loader = new CollectionClassLoader(XSLTUtil.class.getClassLoader(), GSFile.siteHome(GlobalProperties.getGSDL3Home(), site_name), collection);
404 Dictionary dict = new Dictionary(collection, lang, class_loader);
405 String result = dict.get(key, args);
406 if (result != null)
407 {
408 return docBuilder.parse(new ByteArrayInputStream(("<fragment>" + result + "</fragment>").getBytes("UTF-8"))).getDocumentElement();
409 }
410 return docBuilder.parse(new ByteArrayInputStream(("<fragment>" + "text:" + collection + ":" + key + "</fragment>").getBytes())).getDocumentElement();
411 }
412 catch (Exception ex)
413 {
414 return null;
415 }
416 }
417
418 public static boolean isImage(String mimetype)
419 {
420 if (mimetype.startsWith("image/"))
421 {
422 return true;
423 }
424 return false;
425 }
426
427 // formatting /preprocessing functions
428 // some require a language, so we'll have a language param for all
429 public static String toLower(String orig, String lang)
430 {
431 return orig.toLowerCase();
432 }
433
434 public static String toUpper(String orig, String lang)
435 {
436 return orig.toUpperCase();
437 }
438
439 public static String tidyWhitespace(String original, String lang)
440 {
441
442 if (original == null || original.equals(""))
443 {
444 return original;
445 }
446 String new_s = original.replaceAll("\\s+", " ");
447 return new_s;
448 }
449
450 public static String stripWhitespace(String original, String lang)
451 {
452
453 if (original == null || original.equals(""))
454 {
455 return original;
456 }
457 String new_s = original.replaceAll("\\s+", "");
458 return new_s;
459 }
460
461 public static byte[] toUTF8(String orig, String lang)
462 {
463 try
464 {
465 byte[] utf8 = orig.getBytes("UTF-8");
466 return utf8;
467 }
468 catch (Exception e)
469 {
470 logger.error("unsupported encoding");
471 return orig.getBytes();
472 }
473 }
474
475 public static String formatDate(String date, String lang)
476 {
477 String in_pattern = "yyyyMMdd";
478 String out_pattern = "dd MMMM yyyy";
479 if (date.length() == 6)
480 {
481 in_pattern = "yyyyMM";
482 }
483
484 SimpleDateFormat formatter = new SimpleDateFormat(in_pattern, new Locale(lang));
485 try
486 {
487 Date d = formatter.parse(date);
488 formatter.applyPattern(out_pattern);
489 String new_date = formatter.format(d);
490 return new_date;
491 }
492 catch (Exception e)
493 {
494 return date;
495 }
496
497 }
498
499 public static String getDetailFromDate(String date, String detail, String lang)
500 {
501 String in_pattern = "yyyyMMdd";
502 if (date.length() == 6)
503 {
504 in_pattern = "yyyyMM";
505 }
506
507 SimpleDateFormat formatter = new SimpleDateFormat(in_pattern, new Locale(lang));
508 try
509 {
510 Date d = formatter.parse(date);
511 if (detail.toLowerCase().equals("day"))
512 {
513 formatter.applyPattern("dd");
514 }
515 else if (detail.toLowerCase().equals("month"))
516 {
517 formatter.applyPattern("MMMM");
518 }
519 else if (detail.toLowerCase().equals("year"))
520 {
521 formatter.applyPattern("yyyy");
522 }
523 else
524 {
525 return "";
526 }
527 return formatter.format(d);
528 }
529 catch (Exception ex)
530 {
531 return "";
532 }
533 }
534
535 public static String formatLanguage(String display_lang, String lang)
536 {
537
538 return new Locale(display_lang).getDisplayLanguage(new Locale(lang));
539 }
540
541 public static String cgiSafe(String original, String lang)
542 {
543
544 original = original.replace('&', ' ');
545 original = original.replaceAll(" ", "%20");
546 return original;
547 }
548
549 public static String formatBigNumber(String num, String lang)
550 {
551
552 String num_str = num;
553 char[] num_chars = num_str.toCharArray();
554 String zero_str = "";
555 String formatted_str = "";
556
557 for (int i = num_chars.length - 4; i >= 0; i--)
558 {
559 zero_str += '0';
560 }
561
562 String sig_str = "";
563 for (int i = 0; i < 3 && i < num_chars.length; i++)
564 {
565 sig_str = sig_str + num_chars[i];
566 if (i == 1 && i + 1 < num_chars.length)
567 {
568 sig_str = sig_str + ".";
569 }
570 }
571
572 int sig_int = Math.round(Float.parseFloat(sig_str));
573 String new_sig_str = sig_int + "";
574 if (sig_str.length() > 2)
575 {
576 new_sig_str = sig_int + "0";
577 }
578
579 char[] final_chars = (new_sig_str + zero_str).toCharArray();
580 int count = 1;
581 for (int i = final_chars.length - 1; i >= 0; i--)
582 {
583 formatted_str = final_chars[i] + formatted_str;
584 if (count == 3 && i != 0)
585 {
586 formatted_str = "," + formatted_str;
587 count = 1;
588 }
589 else
590 {
591 count++;
592 }
593 }
594 return formatted_str;
595 }
596
597 public static String hashToSectionId(String hashString)
598 {
599 if (hashString == null || hashString.length() == 0)
600 {
601 return "";
602 }
603
604 int firstDotIndex = hashString.indexOf(".");
605 if (firstDotIndex == -1)
606 {
607 return "";
608 }
609
610 String sectionString = hashString.substring(firstDotIndex + 1);
611
612 return sectionString;
613 }
614
615 public static String hashToDepthClass(String hashString)
616 {
617 if (hashString == null || hashString.length() == 0)
618 {
619 return "";
620 }
621
622 String sectionString = hashToSectionId(hashString);
623
624 int count = sectionString.split("\\.").length;
625
626 if (sectionString.equals(""))
627 {
628 return "sectionHeaderDepthTitle";
629 }
630 else
631 {
632 return "sectionHeaderDepth" + count;
633 }
634 }
635
636 public static String escapeNewLines(String str)
637 {
638 if (str == null || str.length() < 1)
639 {
640 return null;
641 }
642 return str.replace("\n", "\\\n");
643 }
644
645 public static String escapeQuotes(String str)
646 {
647 if (str == null || str.length() < 1)
648 {
649 return null;
650 }
651 return str.replace("\"", "\\\"");
652 }
653
654 public static String escapeNewLinesAndQuotes(String str)
655 {
656 if (str == null || str.length() < 1)
657 {
658 return null;
659 }
660 return escapeNewLines(escapeQuotes(str));
661 }
662
663 public static String getGlobalProperty(String name)
664 {
665 return GlobalProperties.getProperty(name);
666 }
667
668 public static void clearMetadataStorage()
669 {
670 _foundTableValues.clear();
671 }
672
673 public static boolean checkMetadataNotDuplicate(String name, String value)
674 {
675 if (_foundTableValues.containsKey(name))
676 {
677 for (String mapValue : _foundTableValues.get(name))
678 {
679 if (mapValue.equals(value))
680 {
681 return false;
682 }
683 }
684 _foundTableValues.get(name).add(value);
685 return true;
686 }
687
688 ArrayList<String> newList = new ArrayList<String>();
689 newList.add(value);
690
691 _foundTableValues.put(name, newList);
692
693 return true;
694 }
695
696 public static String reCAPTCHAimage(String publicKey, String privateKey)
697 {
698 ReCaptcha c = ReCaptchaFactory.newReCaptcha(publicKey, privateKey, false);
699 return c.createRecaptchaHtml(null, null);
700 }
701
702 public static String getInterfaceStringsAsJavascript(String interface_name, String lang, String prefix)
703 {
704 String prependToPrefix = "gs.text";
705 return XSLTUtil.getInterfaceStringsAsJavascript(interface_name, lang, prefix, prependToPrefix);
706 }
707
708 // generates javascript: 2 arrays are declared and populated with strings that declare variables and assign their values
709 // to be strings loaded from the interface_name.properties file for the language.
710 public static String getInterfaceStringsAsJavascript(String interface_name, String lang, String prefix, String prependToPrefix)
711 {
712 // 1. Generating Javascript of the form:
713 // if(!gs.text) { gs.text = new Array(); }
714 // if(!gs.text.dse) { gs.text.dse = new Array(); }
715 StringBuffer outputStr = new StringBuffer();
716 outputStr.append("if(!gs.text) { ");
717 outputStr.append(prependToPrefix + " = new Array(); ");
718 outputStr.append("}\n");
719 outputStr.append("if(!gs.text." + prefix + ") { ");
720 outputStr.append(prependToPrefix + "." + prefix + " = new Array(); ");
721 outputStr.append("}\n");
722
723 int foundCount = 0;
724
725 for (String dictName : new String[] { "interface_" + interface_name, "interface_default", "interface_default2" })
726 {
727 Dictionary dict = new Dictionary(dictName, lang);
728 Enumeration keys = dict.getKeys();
729 if (keys == null)
730 {
731 continue;
732 }
733
734 // Get all properties in the language-specific dictionary with the given key prefix
735 // Create Javascript strings of the form:
736 // prependToPrefix.key= "value";\n
737 while (keys.hasMoreElements())
738 {
739 String key = (String) keys.nextElement();
740 if (key.startsWith(prefix))
741 {
742 String value = getInterfaceText(interface_name, dictName, lang, key, null);
743
744 outputStr.append(prependToPrefix);
745 outputStr.append(".");
746 outputStr.append(key);
747 outputStr.append("=\"");
748 outputStr.append(value);
749 outputStr.append("\";\n");
750 }
751 }
752
753 if (foundCount > 0)
754 {
755 break;
756 }
757 }
758
759 return outputStr.toString();
760 }
761
762 public static String xmlNodeToString(Node node)
763 {
764 return GSXML.xmlNodeToString(node);
765 }
766
767 // Test from cmdline with:
768 // 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
769 public static void main(String args[])
770 {
771 System.out.println("\n@@@@@\n" + XSLTUtil.getInterfaceStringsAsJavascript("default", "en", "dse", "gs.text") + "@@@@@\n");
772 }
773}
Note: See TracBrowser for help on using the repository browser.