Changeset 30477 for main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java
- Timestamp:
- 2016-04-20T22:50:52+12:00 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java
r29997 r30477 8 8 import java.util.HashMap; 9 9 import java.util.HashSet; 10 import java.util.regex.Pattern; 11 import java.util.regex.Matcher; 10 12 11 13 import javax.xml.transform.Transformer; … … 27 29 import org.greenstone.gsdl3.util.XMLConverter; 28 30 import org.greenstone.gsdl3.util.XMLTransformer; 31 import org.greenstone.gsdl3.util.XSLTUtil; 29 32 import org.greenstone.util.GlobalProperties; 30 33 import org.w3c.dom.Comment; … … 200 203 for (File currentFile : xslFiles) 201 204 { 205 206 String full_filename = currentFile.getPath(); 207 int sep_pos = full_filename.lastIndexOf(File.separator)+1; 208 String local_filename = full_filename.substring(sep_pos); 209 if (local_filename.startsWith(".")) { 210 logger.warn("Greenstone does not normally rely on 'dot' files for XSL transformations.\n Is the following file intended to be part of the digital library installation?\n XSL File being read in:\n " + currentFile.getPath()); 211 } 212 202 213 Document currentDoc = this.converter.getDOM(currentFile); 203 214 if (currentDoc == null) … … 401 412 } 402 413 } 403 414 } 404 415 request.appendChild(request.getOwnerDocument().importNode(extraMetadataList, true)); 405 416 } … … 409 420 // might need to add some data to the page 410 421 addExtraInfo(page); 422 423 411 424 // transform the page using xslt 412 Node transformed_page = transformPage(page); 413 425 426 String currentInterface = (String) config_params.get(GSConstants.INTERFACE_NAME); 427 428 Element request = (Element) GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM); 429 String output = request.getAttribute(GSXML.OUTPUT_ATT); 430 431 boolean useClientXSLT = (Boolean) config_params.get(GSConstants.USE_CLIENT_SIDE_XSLT); 432 //logger.info("Client side transforms allowed? " + allowsClientXSLT); 433 434 if (useClientXSLT) 435 { 436 // if not specified, output defaults to 'html', but this isn't what we want when useClientXSLT is on 437 if (output.equals("html")) { 438 output = "xsltclient"; 439 } 440 } 441 Node transformed_page = transformPage(page,currentInterface,output); 442 443 if (useClientXSLT) { 444 return transformed_page; 445 } 414 446 // if the user has specified they want only a part of the full page then subdivide it 415 447 boolean subdivide = false; 416 448 String excerptID = null; 417 449 String excerptTag = null; 418 Element request = (Element) GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM);419 450 Element cgi_param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 420 451 if (cgi_param_list != null) … … 517 548 } 518 549 550 protected void replaceNodeWithInterfaceText(Document doc, String interface_name, String lang, 551 Element elem, String attr_name, String attr_val) 552 { 553 String pattern_str_3arg = "util:getInterfaceText\\([^,]+,[^,]+,\\s*'(.+?)'\\s*\\)"; 554 String pattern_str_4arg = "util:getInterfaceText\\([^,]+,[^,]+,\\s*'(.+?)'\\s*,\\s*(.+?)\\s*\\)$"; 555 556 Pattern pattern3 = Pattern.compile(pattern_str_3arg); 557 Matcher matcher3 = pattern3.matcher(attr_val); 558 if (matcher3.find()) { 559 String dict_key = matcher3.group(1); 560 String dict_val = XSLTUtil.getInterfaceText(interface_name,lang,dict_key); 561 562 Node parent_node = elem.getParentNode(); 563 564 Text replacement_text_node = doc.createTextNode(dict_val); 565 parent_node.replaceChild(replacement_text_node,elem); 566 } 567 else { 568 Pattern pattern4 = Pattern.compile(pattern_str_4arg); 569 Matcher matcher4 = pattern4.matcher(attr_val); 570 StringBuffer string_buffer4 = new StringBuffer(); 571 572 if (matcher4.find()) { 573 String dict_key = matcher4.group(1); 574 String args = matcher4.group(2); 575 args = args.replaceAll("\\$","\\\\\\$"); 576 577 String dict_val = XSLTUtil.getInterfaceText(interface_name,lang,dict_key); 578 579 matcher4.appendReplacement(string_buffer4, "js:getInterfaceTextSubstituteArgs('"+dict_val+"',string("+args+"))"); 580 matcher4.appendTail(string_buffer4); 581 582 attr_val = string_buffer4.toString(); 583 elem.setAttribute(attr_name,attr_val); 584 } 585 else { 586 logger.error("Failed to find match in attribute: " + attr_name + "=\"" + attr_val + "\""); 587 attr_val = attr_val.replaceAll("util:getInterfaceText\\(.+?,.+?,\\s*(.+?)\\s*\\)","$1"); 588 elem.setAttribute(attr_name,attr_val); 589 } 590 } 591 592 } 593 594 protected void resolveExtendedNamespaceAttributesXSLT(Document doc, String interface_name, String lang) 595 { 596 String[] attr_list = new String[] {"select","test"}; 597 598 // http://stackoverflow.com/questions/13220520/javascript-replace-child-loop-issue 599 // go through nodeList in reverse to avoid the 'skipping' problem, due to 600 // replaceChild() calls removing items from the "live" nodeList 601 602 NodeList nodeList = doc.getElementsByTagName("*"); 603 for (int i=nodeList.getLength()-1; i>=0; i--) { 604 Node node = nodeList.item(i); 605 if (node.getNodeType() == Node.ELEMENT_NODE) { 606 Element elem = (Element)node; 607 for (String attr_name : attr_list) { 608 if (elem.hasAttribute(attr_name)) { 609 String attr_val = elem.getAttribute(attr_name); 610 611 if (attr_val.startsWith("util:getInterfaceText(")) { 612 // replace the node with dictionary lookup 613 replaceNodeWithInterfaceText(doc, interface_name,lang, elem,attr_name,attr_val); 614 } 615 else if (attr_val.contains("util:")) { 616 617 attr_val = attr_val.replaceAll("util:getInterfaceStringsAsJavascript\\(.+?,.+?,\\s*(.+?)\\)","$1"); 618 619 //attr_val = attr_val.replaceAll("util:escapeNewLinesAndQuotes\\(\\s*(.+?)\\s*\\)","'escapeNLandQ $1'"); 620 //attr_val = attr_val.replaceAll("util:escapeNewLinesAndQuotes\\(\\s*(.+?)\\s*\\)","$1"); 621 622 // 'contains()' supported in XSLT 1.0, so OK to change any util:contains() into contains() 623 attr_val = attr_val.replaceAll("util:(contains\\(.+?\\))","$1"); 624 625 elem.setAttribute(attr_name,attr_val); 626 } 627 628 if (attr_val.contains("java:")) { 629 if (attr_val.indexOf("getInterfaceTextSubstituteArgs")>=4) { 630 631 attr_val = attr_val.replaceAll("java:.+?\\.(\\w+)\\((.*?)\\)$","js:$1($2)"); 632 } 633 634 elem.setAttribute(attr_name,attr_val); 635 } 636 } 637 } 638 639 } 640 } 641 } 642 643 644 protected void resolveExtendedNamespaceAttributesXML(Document doc, String interface_name, String lang) 645 { 646 String[] attr_list = new String[] {"src", "href"}; 647 648 // http://stackoverflow.com/questions/13220520/javascript-replace-child-loop-issue 649 // go through nodeList in reverse to avoid the 'skipping' problem, due to 650 // replaceChild() calls removing items from the "live" nodeList 651 652 NodeList nodeList = doc.getElementsByTagName("*"); 653 for (int i=nodeList.getLength()-1; i>=0; i--) { 654 Node node = nodeList.item(i); 655 if (node.getNodeType() == Node.ELEMENT_NODE) { 656 Element elem = (Element)node; 657 for (String attr_name : attr_list) { 658 if (elem.hasAttribute(attr_name)) { 659 String attr_val = elem.getAttribute(attr_name); 660 661 if (attr_val.contains("util:getInterfaceText(")) { 662 String pattern_str_3arg = "util:getInterfaceText\\([^,]+,[^,]+,\\s*'(.+?)'\\s*\\)"; 663 Pattern pattern3 = Pattern.compile(pattern_str_3arg); 664 Matcher matcher3 = pattern3.matcher(attr_val); 665 666 StringBuffer string_buffer3 = new StringBuffer(); 667 668 boolean found_match = false; 669 670 while (matcher3.find()) { 671 found_match = true; 672 String dict_key = matcher3.group(1); 673 String dict_val = XSLTUtil.getInterfaceText(interface_name,lang,dict_key); 674 675 matcher3.appendReplacement(string_buffer3, dict_val); 676 } 677 matcher3.appendTail(string_buffer3); 678 679 if (found_match) { 680 attr_val = string_buffer3.toString(); 681 elem.setAttribute(attr_name,attr_val); 682 } 683 else { 684 logger.error("Failed to find match in attribute: " + attr_name + "=\"" + attr_val + "\""); 685 attr_val = attr_val.replaceAll("util:getInterfaceText\\(.+?,.+?,\\s*(.+?)\\s*\\)","$1"); 686 elem.setAttribute(attr_name,attr_val); 687 } 688 } 689 else if (attr_val.contains("util:")) { 690 691 logger.error("Encountered unexpected 'util:' prefix exension: " + attr_name + "=\"" + attr_val + "\""); 692 } 693 694 if (attr_val.contains("java:")) { 695 // make anything java: safe from the point of an XSLT without extensions 696 logger.error("Encountered unexpected 'java:' prefix exension: " + attr_name + "=\"" + attr_val + "\""); 697 698 } 699 } 700 } 701 702 } 703 } 704 } 705 706 707 519 708 /** 520 709 * overwrite this to add any extra info that might be needed in the page … … 529 718 * the page and add it to the xslt before transforming 530 719 */ 531 protected Node transformPage(Element page)720 protected Node transformPage(Element page,String currentInterface,String output) 532 721 { 533 722 _debug = false; 534 723 535 boolean allowsClientXSLT = (Boolean) config_params.get(GSConstants.ALLOW_CLIENT_SIDE_XSLT);536 //System.out.println("Client side transforms allowed? " + allowsClientXSLT);537 538 String currentInterface = (String) config_params.get(GSConstants.INTERFACE_NAME);539 540 724 Element request = (Element) GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM); 541 String output = request.getAttribute(GSXML.OUTPUT_ATT); 542 543 //System.out.println("Current output mode is: " + output + ", current interface name is: " + currentInterface); 544 545 if (allowsClientXSLT) 546 { 547 if (!currentInterface.endsWith(GSConstants.CLIENT_SIDE_XSLT_INTERFACE_SUFFIX) && output.equals("html")) 548 { 549 System.out.println("output is html and we are not currently using a client side version, switching"); 550 // Switch the interface 551 config_params.put(GSConstants.INTERFACE_NAME, currentInterface.concat(GSConstants.CLIENT_SIDE_XSLT_INTERFACE_SUFFIX)); 552 } 553 else if ((currentInterface.endsWith(GSConstants.CLIENT_SIDE_XSLT_INTERFACE_SUFFIX) && !output.equals("html")) || output.equals("server")) 554 { 555 // The reverse needs to happen too 556 config_params.put(GSConstants.INTERFACE_NAME, currentInterface.substring(0, currentInterface.length() - GSConstants.CLIENT_SIDE_XSLT_INTERFACE_SUFFIX.length())); 557 } 558 } 559 else if (currentInterface.endsWith(GSConstants.CLIENT_SIDE_XSLT_INTERFACE_SUFFIX)) 560 { 561 config_params.put(GSConstants.INTERFACE_NAME, currentInterface.substring(0, currentInterface.length() - GSConstants.CLIENT_SIDE_XSLT_INTERFACE_SUFFIX.length())); 562 } 563 725 726 //logger.info("Current output mode is: " + output + ", current interface name is: " + currentInterface); 727 564 728 // DocType defaults in case the skin doesn't have an "xsl:output" element 565 729 String qualifiedName = "html"; … … 573 737 if (output.equals("xsltclient")) 574 738 { 739 String baseURL = request.getAttribute(GSXML.BASE_URL); 740 575 741 // If you're just getting the client-side transform page, why bother with the rest of this? 576 742 Element html = docWithDoctype.createElement("html"); 577 743 Element img = docWithDoctype.createElement("img"); 578 img.setAttribute("src", " interfaces/default/images/loading.gif"); // Make it dynamic744 img.setAttribute("src", "loading.gif"); // Make it dynamic 579 745 img.setAttribute("alt", "Please wait..."); 580 746 Text title_text = docWithDoctype.createTextNode("Please wait..."); // Make this language dependent 581 747 Element head = docWithDoctype.createElement("head"); 748 749 // e.g., <base href="http://localhost:8383/greenstone3/" /><!-- [if lte IE 6]></base><![endif] --> 750 Element base = docWithDoctype.createElement("base"); 751 base.setAttribute("href",baseURL); 752 Comment opt_end_base = docWithDoctype.createComment("[if lte IE 6]></base><![endif]"); 753 582 754 Element title = docWithDoctype.createElement("title"); 583 755 title.appendChild(title_text); 756 584 757 Element body = docWithDoctype.createElement("body"); 758 759 Element jquery_script = docWithDoctype.createElement("script"); 760 jquery_script.setAttribute("src", "jquery-1.10-min.js"); 761 jquery_script.setAttribute("type", "text/javascript"); 762 Comment jquery_comment = docWithDoctype.createComment("jQuery"); 763 jquery_script.appendChild(jquery_comment); 764 765 Element saxonce_script = docWithDoctype.createElement("script"); 766 saxonce_script.setAttribute("src", "Saxonce/Saxonce.nocache.js"); 767 saxonce_script.setAttribute("type", "text/javascript"); 768 Comment saxonce_comment = docWithDoctype.createComment("SaxonCE"); 769 saxonce_script.appendChild(saxonce_comment); 770 771 Element xsltutil_script = docWithDoctype.createElement("script"); 772 xsltutil_script.setAttribute("src", "xslt-util.js"); 773 xsltutil_script.setAttribute("type", "text/javascript"); 774 Comment xsltutil_comment = docWithDoctype.createComment("JavaScript version of XSLTUtil.java"); 775 xsltutil_script.appendChild(xsltutil_comment); 776 585 777 Element script = docWithDoctype.createElement("script"); 586 Element jquery = docWithDoctype.createElement("script");587 jquery.setAttribute("src", "jquery.js");588 jquery.setAttribute("type", "text/javascript");589 Comment jquery_comment = docWithDoctype.createComment("jQuery");590 778 Comment script_comment = docWithDoctype.createComment("Filler for browser"); 591 script.setAttribute("src", " test.js");779 script.setAttribute("src", "client-side-xslt.js"); 592 780 script.setAttribute("type", "text/javascript"); 781 script.appendChild(script_comment); 782 593 783 Element pagevar = docWithDoctype.createElement("script"); 594 784 Element style = docWithDoctype.createElement("style"); … … 599 789 600 790 html.appendChild(head); 791 head.appendChild(base); head.appendChild(opt_end_base); 601 792 head.appendChild(title); 602 793 head.appendChild(style); … … 604 795 html.appendChild(body); 605 796 head.appendChild(pagevar); 606 head.appendChild(jquery); 797 head.appendChild(jquery_script); 798 head.appendChild(saxonce_script); 799 head.appendChild(xsltutil_script); 607 800 head.appendChild(script); 608 801 pagevar.appendChild(page_var_text); 609 jquery.appendChild(jquery_comment); 610 script.appendChild(script_comment); 802 611 803 body.appendChild(img); 612 804 docWithDoctype.appendChild(html); … … 653 845 siteName.appendChild(siteNameText); 654 846 847 Element clientSideXSLTName = theXML.createElement("param"); 848 clientSideXSLTName.setAttribute("name", "use_client_side_xslt"); 849 Boolean useClientXSLT = (Boolean) config_params.get(GSConstants.USE_CLIENT_SIDE_XSLT); 850 Text clientSideXSLTNameText = theXML.createTextNode(useClientXSLT.toString()); 851 clientSideXSLTName.appendChild(clientSideXSLTNameText); 852 655 853 Element filepath = theXML.createElement("param"); 656 854 filepath.setAttribute("name", "filepath"); … … 661 859 root.appendChild(intname); 662 860 root.appendChild(siteName); 861 root.appendChild(clientSideXSLTName); 663 862 root.appendChild(filepath); 664 863 … … 916 1115 return converter.getDOM(getStringFromDocument(skinAndLibraryXsl)); 917 1116 } 918 if (output.equals("skinandlibdoc") || output.equals("clientside"))1117 if (output.equals("skinandlibdoc")) 919 1118 { 920 1119 921 1120 Node skinAndLib = converter.getDOM(getStringFromDocument(skinAndLibraryDoc)); 922 923 if (output.equals("skinandlibdoc")) 924 { 925 return skinAndLib; 926 } 927 else 928 { 929 // Send XML and skinandlibdoc down the line together 930 Document finalDoc = converter.newDOM(); 931 Node finalDocSkin = finalDoc.importNode(skinAndLibraryDoc.getDocumentElement(), true); 932 Node finalDocXML = finalDoc.importNode(theXML.getDocumentElement(), true); 933 Element root = finalDoc.createElement("skinlibPlusXML"); 934 root.appendChild(finalDocSkin); 935 root.appendChild(finalDocXML); 936 finalDoc.appendChild(root); 937 return (Node) finalDoc.getDocumentElement(); 938 } 1121 return skinAndLib; 939 1122 } 940 1123 if (output.equals("oldskindoc")) … … 1018 1201 } 1019 1202 1020 if (output.equals("skinandlibdocfinal")) 1021 { 1022 return converter.getDOM(getStringFromDocument(skinAndLibraryDoc)); 1203 if (output.equals("skinandlibdocfinal") || output.equals("clientside")) 1204 { 1205 if (output.equals("skinandlibdocfinal")) 1206 { 1207 Node skinAndLibFinal = converter.getDOM(getStringFromDocument(skinAndLibraryDoc)); 1208 return skinAndLibFinal; 1209 } 1210 else 1211 { 1212 // Go through and 'fix up' any 'util:...' or 'java:...' attributes the skinAndLibraryDoc has 1213 String lang = (String)config_params.get("lang"); 1214 resolveExtendedNamespaceAttributesXSLT(skinAndLibraryDoc,currentInterface,lang); // test= and select= attributes 1215 resolveExtendedNamespaceAttributesXML(skinAndLibraryDoc,currentInterface,lang); // href= and src= attributes 1216 Node skinAndLibFinal = converter.getDOM(getStringFromDocument(skinAndLibraryDoc)); 1217 1218 // Send XML and skinandlibdoc down the line together 1219 Document finalDoc = converter.newDOM(); 1220 Node finalDocSkin = finalDoc.importNode(skinAndLibraryDoc.getDocumentElement(), true); 1221 Node finalDocXML = finalDoc.importNode(theXML.getDocumentElement(), true); 1222 Element root = finalDoc.createElement("skinlibfinalPlusXML"); 1223 root.appendChild(finalDocSkin); 1224 root.appendChild(finalDocXML); 1225 finalDoc.appendChild(root); 1226 return (Node) finalDoc.getDocumentElement(); 1227 } 1228 1229 1230 1231 1023 1232 } 1024 1233
Note:
See TracChangeset
for help on using the changeset viewer.