Changeset 23794

Show
Ignore:
Timestamp:
15.03.2011 17:09:34 (8 years ago)
Author:
davidb
Message:

Code changes to take advantage of client-side XSLT capabilities and more efficient string processing.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java

    r23405 r23794  
    77import org.w3c.dom.Node;  
    88import org.w3c.dom.NodeList;  
     9import org.w3c.dom.Comment; 
     10import org.w3c.dom.Text; 
    911import org.w3c.dom.Document;  
    1012import org.w3c.dom.Element; 
    1113import org.xml.sax.InputSource; 
     14import org.w3c.dom.NamedNodeMap; 
    1215 
    1316// other java classes 
     
    2629import org.apache.xerces.dom.*; 
    2730import org.apache.xerces.parsers.DOMParser; 
     31 
     32import org.apache.commons.lang3.StringUtils; 
    2833 
    2934/** A receptionist that uses xslt to transform the page_data before returning it. . Receives requests consisting 
     
    8186  public boolean configure() { 
    8287     
    83     if (this.config_params==null) { 
     88   if (this.config_params==null) { 
    8489      logger.error(" config variables must be set before calling configure"); 
    8590      return false; 
     
    279284   * before transforming */ 
    280285  protected Node transformPage(Element page) { 
    281  
     286     
     287     boolean allowsClientXSLT = (Boolean)config_params.get(GSConstants.ALLOW_CLIENT_SIDE_XSLT); 
     288     //System.out.println("Client side transforms allowed? " + allowsClientXSLT); 
     289      
     290     // Force it back to traditional 
     291     if(!allowsClientXSLT) 
     292        config_params.put(GSConstants.INTERFACE_NAME, "traditional"); 
     293     
     294     Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM); 
     295     String output = request.getAttribute(GSXML.OUTPUT_ATT);     
     296      
     297     String currentInterface = (String)config_params.get(GSConstants.INTERFACE_NAME); 
     298     //System.out.println("Current output mode is: " + output + ", current interface name is: " + currentInterface); 
     299      
     300     if(allowsClientXSLT) { 
     301         if((currentInterface.equals("default") && output.equals("html")) || output.equals("server")) 
     302           // Switch the interface 
     303           config_params.put(GSConstants.INTERFACE_NAME, "traditional"); 
     304         else if(currentInterface.equals("traditional") && !output.equals("html")) 
     305           // The reverse needs to happen too 
     306           config_params.put(GSConstants.INTERFACE_NAME, "default"); 
     307    } 
     308     
     309    // DocType defaults in case the skin doesn't have an "xsl:output" element 
     310    String qualifiedName = "html"; 
     311    String publicID = "-//W3C//DTD HTML 4.01 Transitional//EN"; 
     312    String systemID = "http://www.w3.org/TR/html4/loose.dtd"; 
     313         
     314    // We need to create an empty document with a predefined DocType, 
     315    // that will then be used for the transformation by the DOMResult 
     316    Document docWithDoctype = converter.newDOM(qualifiedName, publicID, systemID);       
     317         
     318    if(output.equals("xsltclient")) { 
     319    // If you're just getting the client-side transform page, why bother with the rest of this? 
     320    Element html = docWithDoctype.createElement("html"); 
     321     Element img = docWithDoctype.createElement("img"); 
     322     img.setAttribute("src", "interfaces/default/images/loading.gif"); // Make it dynamic 
     323     img.setAttribute("alt", "Please wait..."); 
     324     Text title_text = docWithDoctype.createTextNode("Please wait..."); // Make this language dependent 
     325     Element head = docWithDoctype.createElement("head"); 
     326     Element title = docWithDoctype.createElement("title"); 
     327     title.appendChild(title_text); 
     328     Element body = docWithDoctype.createElement("body"); 
     329     Element script = docWithDoctype.createElement("script"); 
     330     Element jquery = docWithDoctype.createElement("script"); 
     331     jquery.setAttribute("src", "jquery.js"); 
     332     jquery.setAttribute("type", "text/javascript"); 
     333     Comment jquery_comment = docWithDoctype.createComment("jQuery"); 
     334     Comment script_comment = docWithDoctype.createComment("Filler for browser"); 
     335     script.setAttribute("src", "test.js"); 
     336     script.setAttribute("type", "text/javascript"); 
     337     Element pagevar = docWithDoctype.createElement("script"); 
     338     Element style = docWithDoctype.createElement("style"); 
     339     style.setAttribute("type", "text/css"); 
     340     Text style_text = docWithDoctype.createTextNode("body { text-align: center; padding: 50px; font: 14pt Arial, sans-serif; font-weight: bold; }"); 
     341     pagevar.setAttribute("type", "text/javascript"); 
     342     Text page_var_text = docWithDoctype.createTextNode("var placeholder = true;"); 
     343      
     344     html.appendChild(head); 
     345     head.appendChild(title); 
     346     head.appendChild(style); 
     347     style.appendChild(style_text); 
     348     html.appendChild(body); 
     349     head.appendChild(pagevar); 
     350     head.appendChild(jquery); 
     351     head.appendChild(script); 
     352     pagevar.appendChild(page_var_text); 
     353     jquery.appendChild(jquery_comment); 
     354     script.appendChild(script_comment); 
     355     body.appendChild(img); 
     356     docWithDoctype.appendChild(html); 
     357      
     358     return (Node)docWithDoctype; 
     359     } 
     360 
     361    // Passing in the pretty string here means it needs to be generated even when not debugging; so use custom function to return blank when debug is off 
    282362    logger.debug("page before transforming:"); 
    283     logger.debug(this.converter.getPrettyString(page)); 
    284  
    285     Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM); 
     363    logger.debug(this.converter.getPrettyStringLogger(page, logger)); 
     364 
    286365    String action = request.getAttribute(GSXML.ACTION_ATT); 
    287366    String subaction = request.getAttribute(GSXML.SUBACTION_ATT); 
    288          
    289     String output = request.getAttribute(GSXML.OUTPUT_ATT); 
     367 
    290368    // we should choose how to transform the data based on output, eg diff 
    291369    // choice for html, and wml?? 
    292370    // for now, if output=xml, we don't transform the page, we just return  
    293371    // the page xml 
    294     if (output.equals("xml")) { 
    295       return page; 
     372    Document theXML = null; 
     373     
     374    if (output.equals("xml") || output.equals("clientside")) { 
     375      // Append some bits and pieces first... 
     376      theXML = converter.newDOM(); 
     377      // Import into new document first! 
     378      Node newPage = theXML.importNode(page, true); 
     379      theXML.appendChild(newPage); 
     380      Element root = theXML.createElement("xsltparams"); 
     381      newPage.appendChild(root); 
     382       
     383      Element libname = theXML.createElement("param"); 
     384      libname.setAttribute("name", "library_name"); 
     385      Text libnametext = theXML.createTextNode((String)config_params.get(GSConstants.LIBRARY_NAME)); 
     386      libname.appendChild(libnametext); 
     387       
     388      Element intname = theXML.createElement("param"); 
     389      intname.setAttribute("name", "interface_name"); 
     390      Text intnametext = theXML.createTextNode((String)config_params.get(GSConstants.INTERFACE_NAME)); 
     391      intname.appendChild(intnametext); 
     392       
     393      Element filepath = theXML.createElement("param"); 
     394      filepath.setAttribute("name", "filepath"); 
     395      Text filepathtext = theXML.createTextNode(GlobalProperties.getGSDL3Home()); 
     396      filepath.appendChild(filepathtext); 
     397       
     398      root.appendChild(libname); 
     399      root.appendChild(intname);    
     400      root.appendChild(filepath); 
     401       
     402      if(output.equals("xml")) 
     403      return theXML.getDocumentElement(); 
    296404    } 
    297405         
     
    300408    String collection = ""; 
    301409    if (cgi_param_list != null) { 
    302       HashMap params = GSXML.extractParams(cgi_param_list, false); 
     410      // Don't waste time getting all the parameters 
     411      HashMap params = GSXML.extractParams(cgi_param_list, false, GSParams.COLLECTION); 
    303412      collection = (String)params.get(GSParams.COLLECTION); 
    304413      if (collection == null) collection = ""; 
     
    314423    String errorPage = this.converter.getParseErrorMessage(); 
    315424    if(errorPage != null) { 
    316       return XMLTransformer.constructErrorXHTMLPage( 
    317                             "Cannot parse the xslt file: " + xslt_file + "\n" + errorPage); 
     425      return XMLTransformer.constructErrorXHTMLPage("Cannot parse the xslt file: " + xslt_file + "\n" + errorPage); 
    318426    } 
    319427    if (style_doc == null) { 
     
    335443    if (format_elem != null) { 
    336444      //page_response.removeChild(format_elem); 
    337       logger.debug("format elem="+this.converter.getPrettyString(format_elem)); 
     445      logger.debug("format elem="+this.converter.getPrettyStringLogger(format_elem, logger)); 
    338446      // need to transform the format info 
    339447      String configStylesheet_file = GSFile.stylesheetFile(GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.SITE_NAME), collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME), base_interfaces,   "config_format.xsl"); 
    340448      Document configStylesheet_doc = this.converter.getDOM(new File(configStylesheet_file)); 
     449 
    341450      if (configStylesheet_doc != null) { 
    342451    Document format_doc = this.converter.newDOM(); 
    343452    format_doc.appendChild(format_doc.importNode(format_elem, true)); 
    344     Node result = this.transformer.transform(configStylesheet_doc, format_doc); 
     453    Node result = this.transformer.transform(configStylesheet_doc, format_doc); // Needs addressing <- 
    345454                 
    346455    // Since we started creating documents with DocTypes, we can end up with  
     
    353462      new_format = (Element)result; 
    354463    } 
    355     logger.debug("new format elem="+this.converter.getPrettyString(new_format)); 
     464    logger.debug("new format elem="+this.converter.getPrettyStringLogger(new_format, logger)); 
    356465    if (output.equals("newformat")) { 
    357466      return new_format; 
     
    370479      } 
    371480      logger.debug("the converted stylesheet is:"); 
    372       logger.debug(this.converter.getPrettyString(style_doc.getDocumentElement())); 
     481      logger.debug(this.converter.getPrettyStringLogger(style_doc.getDocumentElement(), logger)); 
    373482    } 
    374483         
     
    377486 
    378487 
    379     Document preprocessingXsl  ; 
     488    Document preprocessingXsl; 
    380489    try { 
    381490      preprocessingXsl = getPreprocessDoc(); 
     
    537646      return converter.getDOM(getStringFromDocument(skinAndLibraryXsl)); 
    538647    } 
    539     if (output.equals("skinandlibdoc")) { 
    540       return converter.getDOM(getStringFromDocument(skinAndLibraryDoc)); 
     648    if (output.equals("skinandlibdoc") || output.equals("clientside")) {     
     649         
     650        Node skinAndLib = converter.getDOM(getStringFromDocument(skinAndLibraryDoc)); 
     651         
     652        if(output.equals("skinandlibdoc")) { 
     653      return skinAndLib; 
     654       } else { 
     655        // Send XML and skinandlibdoc down the line together 
     656        Document finalDoc = converter.newDOM(); 
     657        Node finalDocSkin = finalDoc.importNode(skinAndLibraryDoc.getDocumentElement(), true); 
     658        Node finalDocXML = finalDoc.importNode(theXML.getDocumentElement(), true); 
     659        Element root = finalDoc.createElement("skinlibPlusXML"); 
     660        root.appendChild(finalDocSkin); 
     661        root.appendChild(finalDocXML); 
     662        finalDoc.appendChild(root); 
     663        return (Node)finalDoc.getDocumentElement(); 
     664       } 
    541665    } 
    542666    if (output.equals("oldskindoc")) { 
    543667      return converter.getDOM(getStringFromDocument(oldStyle_doc)); 
    544668    } 
    545  
    546     // DocType defaults in case the skin doesn't have an "xsl:output" element 
    547     String qualifiedName = "html"; 
    548     String publicID = "-//W3C//DTD HTML 4.01 Transitional//EN"; 
    549     String systemID = "http://www.w3.org/TR/html4/loose.dtd"; 
    550669 
    551670    // Try to get the system and public ID from the current skin xsl document 
     
    571690    } 
    572691         
    573     // We need to create an empty document with a predefined DocType, 
    574     // that will then be used for the transformation by the DOMResult 
    575     Document docWithDoctype = converter.newDOM(qualifiedName, publicID, systemID); 
    576          
    577692    //System.out.println(converter.getPrettyString(docWithDoctype)); 
    578693    //System.out.println("Doctype vals: " + qualifiedName + " " + publicID + " " + systemID) ; 
    579694         
     695     docWithDoctype = converter.newDOM(qualifiedName, publicID, systemID);           
    580696         
    581697    //System.out.println("Generate final HTML from current skin") ; 
    582698    //Transformation of the XML message from the receptionist to HTML with doctype 
    583     return this.transformer.transform(skinAndLibraryDoc, doc, config_params, docWithDoctype); 
    584          
    585          
     699 
     700    return this.transformer.transform(skinAndLibraryDoc, doc, config_params, docWithDoctype); // The default 
     701     
    586702    // The line below will do the transformation like we use to do before having Skin++ implemented, 
    587703    // it will not contain any GS-Lib statements expanded, and the result will not contain any doctype. 
    588704 
    589705    //return (Element)this.transformer.transform(style_doc, doc, config_params);   
    590  
     706    //return null; // For now - change later 
    591707  } 
    592708     
     
    606722    content = writer.toString(); 
    607723    System.out.println("Change the & to &Amp; for proper debug dispay") ; 
    608     content = content.replaceAll("&", "&amp;"); 
     724    content = StringUtils.replace(content, "&", "&amp;"); 
    609725    writer.flush(); 
    610726      }