Changeset 18433

Show
Ignore:
Timestamp:
30.01.2009 16:50:57 (11 years ago)
Author:
max
Message:

1. Using high-level language (gslib elements coming from a library) that can be used in transformations (skins) so that people creating skins will find it less complicated to understand what to do now.
2. gsf statements are now processed before gslib elements so we can call gslib element from a gsf element.
3. We're adding the DOCTYPE to the final page (that will result from transformations) in the proper way, since DOCTYPE is now defined in the stylesheet file itself instead of fixing it programmatically afterwards.
4. Added some errorhandling (which makes use of new additions to XMLConverter and XMLTransformer classes) so that we don't get null pages on parsing, transforming and file not found exceptions and errors.

Files:
1 modified

Legend:

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

    r16374 r18433  
    77import org.w3c.dom.NodeList;  
    88import org.w3c.dom.Document;  
    9 import org.w3c.dom.Element;  
     9import org.w3c.dom.Element; 
     10import org.xml.sax.InputSource; 
    1011 
    1112// other java classes 
    1213import java.io.File; 
     14import java.io.StringWriter; 
     15import java.io.FileReader; 
     16import java.io.FileNotFoundException; 
    1317import java.util.HashMap; 
    1418import java.util.Enumeration; 
    1519 
     20import javax.xml.parsers.*; 
     21import javax.xml.transform.*; 
     22import javax.xml.transform.dom.*; 
     23import javax.xml.transform.stream.*; 
    1624import org.apache.log4j.*; 
     25import org.apache.xerces.dom.*; 
     26import org.apache.xerces.parsers.DOMParser; 
    1727 
    1828/** A receptionist that uses xslt to transform the page_data before returning it. . Receives requests consisting 
     
    2434public class TransformingReceptionist extends Receptionist{ 
    2535     
    26      static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.TransformingReceptionist.class.getName()); 
    27  
     36    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.TransformingReceptionist.class.getName()); 
     37     
     38    /** The preprocess.xsl file is in a fixed location */ 
     39    static final String preprocess_xsl_filename = GlobalProperties.getGSDL3Home() + File.separatorChar  
     40        + "ui" + File.separatorChar + "xslt" + File.separatorChar + "preProcess.xsl";    
     41         
    2842    /** the list of xslt to use for actions */ 
    2943    protected HashMap xslt_map = null; 
     
    3246    protected XMLTransformer transformer=null; 
    3347 
     48    protected TransformerFactory transformerFactory=null; 
     49    protected DOMParser parser = null; 
    3450    public TransformingReceptionist() { 
    3551    super(); 
    3652    this.xslt_map = new HashMap(); 
    3753    this.transformer = new XMLTransformer(); 
     54        try { 
     55            transformerFactory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance(); 
     56            this.converter = new XMLConverter(); 
     57            //transformerFactory.setURIResolver(new MyUriResolver()) ; 
     58 
     59            parser = new DOMParser(); 
     60            parser.setFeature("http://xml.org/sax/features/validation", false); 
     61            // don't try and load external DTD - no need if we are not validating, and may cause connection errors if a proxy is not set up. 
     62            parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); 
     63            // a performance test showed that having this on lead to increased  
     64            // memory use for small-medium docs, and not much gain for large  
     65            // docs. 
     66            // http://www.sosnoski.com/opensrc/xmlbench/conclusions.html 
     67            parser.setFeature("http://apache.org/xml/features/dom/defer-node-expansion", false); 
     68            parser.setFeature("http://apache.org/xml/features/continue-after-fatal-error", true); 
     69            // setting a handler for when fatal errors, errors or warnings happen during xml parsing 
     70            // call XMLConverter's getParseErrorMessage() to get the errorstring that can be rendered as web page 
     71            this.parser.setErrorHandler(new XMLConverter.ParseErrorHandler()); 
     72        } 
     73        catch (Exception e) { 
     74            e.printStackTrace(); 
     75        } 
     76 
    3877    } 
    3978     
     
    4180    public boolean configure() { 
    4281     
    43     if (this.config_params==null) { 
    44         logger.error(" config variables must be set before calling configure"); 
    45         return false; 
    46     } 
    47     if (this.mr==null) {        
    48         logger.error(" message router must be set  before calling configure"); 
    49         return false; 
    50     } 
    51      
    52     // find the config file containing a list of actions 
    53     File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.INTERFACE_NAME)))); 
    54     if (!interface_config_file.exists()) { 
    55         logger.error(" interface config file: "+interface_config_file.getPath()+" not found!"); 
    56         return false; 
    57     } 
    58     Document config_doc = this.converter.getDOM(interface_config_file, "utf-8"); 
    59     if (config_doc == null) { 
    60         logger.error(" could not parse interface config file: "+interface_config_file.getPath()); 
    61         return false; 
    62     } 
    63     Element config_elem = config_doc.getDocumentElement(); 
    64     String base_interface = config_elem.getAttribute("baseInterface"); 
    65     setUpBaseInterface(base_interface); 
    66     setUpInterfaceOptions(config_elem); 
    67  
    68     Element action_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER); 
    69     NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM); 
    70  
    71     for (int i=0; i<actions.getLength(); i++) { 
    72         Element action = (Element) actions.item(i); 
    73         String class_name = action.getAttribute("class"); 
    74         String action_name = action.getAttribute("name"); 
    75         Action ac = null; 
    76         try { 
    77         ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance(); 
    78         } catch (Exception e) { 
    79         logger.error(" couldn't load in action "+class_name); 
    80         e.printStackTrace(); 
    81         continue; 
    82         } 
    83         ac.setConfigParams(this.config_params); 
    84         ac.setMessageRouter(this.mr); 
    85         ac.configure(); 
    86         ac.getActionParameters(this.params); 
    87         this.action_map.put(action_name, ac); 
    88  
    89         // now do the xslt map 
    90         String xslt = action.getAttribute("xslt"); 
    91         if (!xslt.equals("")) { 
    92         this.xslt_map.put(action_name, xslt); 
    93         } 
    94         NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM); 
    95         for (int j=0; j<subactions.getLength(); j++) { 
    96         Element subaction = (Element)subactions.item(j); 
    97         String subname = subaction.getAttribute(GSXML.NAME_ATT); 
    98         String subxslt = subaction.getAttribute("xslt"); 
    99          
    100         String map_key = action_name+":"+subname; 
    101         logger.debug("adding in to xslt map, "+map_key+"->"+subxslt); 
    102         this.xslt_map.put(map_key, subxslt); 
    103         } 
    104          
    105         
    106     } 
    107     Element lang_list = (Element)GSXML.getChildByTagName(config_elem, "languageList"); 
    108     if (lang_list == null) { 
    109         logger.error(" didn't find a language list in the config file!!"); 
    110     } else { 
    111         this.language_list = (Element) this.doc.importNode(lang_list, true); 
    112     } 
    113  
    114     return true; 
     82        if (this.config_params==null) { 
     83            logger.error(" config variables must be set before calling configure"); 
     84            return false; 
     85        } 
     86        if (this.mr==null) {        
     87            logger.error(" message router must be set  before calling configure"); 
     88            return false; 
     89        } 
     90         
     91        // find the config file containing a list of actions 
     92        File interface_config_file = new File(GSFile.interfaceConfigFile(GSFile.interfaceHome(GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.INTERFACE_NAME)))); 
     93        if (!interface_config_file.exists()) { 
     94            logger.error(" interface config file: "+interface_config_file.getPath()+" not found!"); 
     95            return false; 
     96        } 
     97        Document config_doc = this.converter.getDOM(interface_config_file, "utf-8"); 
     98        if (config_doc == null) { 
     99            logger.error(" could not parse interface config file: "+interface_config_file.getPath()); 
     100            return false; 
     101        } 
     102        Element config_elem = config_doc.getDocumentElement(); 
     103        String base_interface = config_elem.getAttribute("baseInterface"); 
     104        setUpBaseInterface(base_interface); 
     105        setUpInterfaceOptions(config_elem); 
     106 
     107        Element action_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.ACTION_ELEM+GSXML.LIST_MODIFIER); 
     108        NodeList actions = action_list.getElementsByTagName(GSXML.ACTION_ELEM); 
     109 
     110        for (int i=0; i<actions.getLength(); i++) { 
     111            Element action = (Element) actions.item(i); 
     112            String class_name = action.getAttribute("class"); 
     113            String action_name = action.getAttribute("name"); 
     114            Action ac = null; 
     115            try { 
     116                ac = (Action)Class.forName("org.greenstone.gsdl3.action."+class_name).newInstance(); 
     117            } catch (Exception e) { 
     118                logger.error(" couldn't load in action "+class_name); 
     119                e.printStackTrace(); 
     120                continue; 
     121            } 
     122            ac.setConfigParams(this.config_params); 
     123            ac.setMessageRouter(this.mr); 
     124            ac.configure(); 
     125            ac.getActionParameters(this.params); 
     126            this.action_map.put(action_name, ac); 
     127 
     128            // now do the xslt map 
     129            String xslt = action.getAttribute("xslt"); 
     130            if (!xslt.equals("")) { 
     131                this.xslt_map.put(action_name, xslt); 
     132            } 
     133            NodeList subactions = action.getElementsByTagName(GSXML.SUBACTION_ELEM); 
     134            for (int j=0; j<subactions.getLength(); j++) { 
     135                Element subaction = (Element)subactions.item(j); 
     136                String subname = subaction.getAttribute(GSXML.NAME_ATT); 
     137                String subxslt = subaction.getAttribute("xslt"); 
     138                 
     139                String map_key = action_name+":"+subname; 
     140                logger.debug("adding in to xslt map, "+map_key+"->"+subxslt); 
     141                this.xslt_map.put(map_key, subxslt); 
     142            } 
     143        } 
     144        Element lang_list = (Element)GSXML.getChildByTagName(config_elem, "languageList"); 
     145        if (lang_list == null) { 
     146            logger.error(" didn't find a language list in the config file!!"); 
     147        } else { 
     148            this.language_list = (Element) this.doc.importNode(lang_list, true); 
     149        } 
     150 
     151        return true; 
    115152    } 
    116153 
    117154 
    118155    protected Node postProcessPage(Element page) { 
    119      
    120     // might need to add some data to the page 
    121     addExtraInfo(page); 
    122     // transform the page using xslt 
    123     Node transformed_page = transformPage(page); 
    124      
    125     return transformed_page; 
     156        // might need to add some data to the page 
     157        addExtraInfo(page); 
     158        // transform the page using xslt 
     159        Node transformed_page = transformPage(page); 
     160         
     161        return transformed_page; 
    126162    } 
    127163     
     
    130166 
    131167    /** transform the page using xslt 
    132      * we need to get any format element out of the page and add it to the xslt 
    133      * before transforming */ 
     168         * we need to get any format element out of the page and add it to the xslt 
     169         * before transforming */ 
    134170    protected Node transformPage(Element page) { 
    135171 
    136     logger.debug("page before transfomring:"); 
    137     logger.debug(this.converter.getPrettyString(page)); 
    138  
    139     Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM); 
    140     String action = request.getAttribute(GSXML.ACTION_ATT); 
    141     String subaction = request.getAttribute(GSXML.SUBACTION_ATT); 
    142      
    143     String output = request.getAttribute(GSXML.OUTPUT_ATT); 
    144     // we should choose how to transform the data based on output, eg diff 
    145     // choice for html, and wml?? 
    146     // for now, if output=xml, we don't transform the page, we just return  
    147     // the page xml 
    148     if (output.equals("xml")) { 
    149         return page; 
    150     } 
    151  
    152     Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 
    153     String collection = ""; 
    154     if (cgi_param_list != null) { 
    155         HashMap params = GSXML.extractParams(cgi_param_list, false); 
    156         collection = (String)params.get(GSParams.COLLECTION); 
    157         if (collection == null) collection = ""; 
    158     } 
    159      
    160     String xslt_file = getXSLTFileName(action, subaction, collection); 
    161     if (xslt_file==null) { 
    162         // cant transform the page - return null or the original? 
    163         logger.error(" cant find the xslt file needed, so returning the original page!"); 
    164         return page; 
    165     } 
    166     Document style_doc = this.converter.getDOM(new File(xslt_file), "UTF-8"); 
    167     if (style_doc == null) { 
    168         logger.error(" cant parse the xslt file needed, so returning the original page!"); 
    169         return page; 
    170          
    171     } 
    172  
    173     // look for the format element in the page response 
    174     Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM); 
    175     Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM); 
    176     if (format_elem != null) { 
    177         //page_response.removeChild(format_elem); 
    178         logger.debug("format elem="+this.converter.getPrettyString(format_elem)); 
    179         // need to transform the format info 
    180         String stylesheet_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"); 
    181         Document stylesheet_doc = this.converter.getDOM(new File(stylesheet_file)); 
    182         if (stylesheet_doc != null) { 
    183         Document format_doc = this.converter.newDOM(); 
    184         format_doc.appendChild(format_doc.importNode(format_elem, true)); 
    185         Element new_format = (Element)this.transformer.transform(stylesheet_doc, format_doc); 
    186         logger.debug("new format elem="+this.converter.getPrettyString(new_format)); 
    187          
    188         // add it in to the main stylesheet 
    189         GSXSLT.mergeStylesheets(style_doc, new_format); 
    190         } else { 
    191         logger.error(" couldn't parse the config_format stylesheet, adding the format info as is"); 
    192         GSXSLT.mergeStylesheets(style_doc, format_elem); 
    193         } 
    194         logger.debug("the converted stylesheet is:"); 
    195         logger.debug(this.converter.getPrettyString(style_doc.getDocumentElement())); 
    196     } 
     172        logger.debug("page before transfomring:"); 
     173        logger.debug(this.converter.getPrettyString(page)); 
     174 
     175        Element request = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_REQUEST_ELEM); 
     176        String action = request.getAttribute(GSXML.ACTION_ATT); 
     177        String subaction = request.getAttribute(GSXML.SUBACTION_ATT); 
     178         
     179        String output = request.getAttribute(GSXML.OUTPUT_ATT); 
     180        // we should choose how to transform the data based on output, eg diff 
     181        // choice for html, and wml?? 
     182        // for now, if output=xml, we don't transform the page, we just return  
     183        // the page xml 
     184        if (output.equals("xml")) { 
     185            return page; 
     186        } 
     187         
     188 
     189        Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 
     190        String collection = ""; 
     191        if (cgi_param_list != null) { 
     192            HashMap params = GSXML.extractParams(cgi_param_list, false); 
     193            collection = (String)params.get(GSParams.COLLECTION); 
     194            if (collection == null) collection = ""; 
     195        } 
     196         
     197        String xslt_file = getXSLTFileName(action, subaction, collection); 
     198        if (xslt_file==null) { 
     199            // returning file not found error page to indicate which file is missing 
     200            return fileNotFoundErrorPage(xslt_file); 
     201        } 
     202         
     203        Document style_doc = this.converter.getDOM(new File(xslt_file), "UTF-8"); 
     204        String errorPage = this.converter.getParseErrorMessage(); 
     205        if(errorPage != null) { 
     206            return XMLTransformer.constructErrorXHTMLPage( 
     207                "Cannot parse the xslt file: " + xslt_file + "\n" + errorPage); 
     208        } 
     209        if (style_doc == null) { 
     210            logger.error(" cant parse the xslt file needed, so returning the original page!"); 
     211            return page; 
     212        } 
     213         
     214        // put the page into a document - this is necessary for xslt to get 
     215        // the paths right if you have paths relative to the document root 
     216        // eg /page. 
     217        Document doc = this.converter.newDOM(); 
     218        doc.appendChild(doc.importNode(page, true)); 
     219        Element page_response = (Element)GSXML.getChildByTagName(page, GSXML.PAGE_RESPONSE_ELEM); 
     220        Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM); 
     221        if (output.equals("formatelem")) { 
     222            return format_elem; 
     223        } 
     224        if (format_elem != null) { 
     225            //page_response.removeChild(format_elem); 
     226            logger.debug("format elem="+this.converter.getPrettyString(format_elem)); 
     227            // need to transform the format info 
     228            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"); 
     229            Document configStylesheet_doc = this.converter.getDOM(new File(configStylesheet_file)); 
     230            if (configStylesheet_doc != null) { 
     231                Document format_doc = this.converter.newDOM(); 
     232                format_doc.appendChild(format_doc.importNode(format_elem, true)); 
     233                Node result = this.transformer.transform(configStylesheet_doc, format_doc); 
     234                 
     235                // Since we started creating documents with DocTypes, we can end up with  
     236                // Document objects here. But we will be working with an Element instead,  
     237                // so we grab the DocumentElement() of the Document object in such a case. 
     238                Element new_format; 
     239                if(result.getNodeType() == Node.DOCUMENT_NODE) { 
     240                    new_format = ((Document)result).getDocumentElement(); 
     241                } else { 
     242                    new_format = (Element)result; 
     243                } 
     244                logger.debug("new format elem="+this.converter.getPrettyString(new_format)); 
     245                if (output.equals("newformat")) { 
     246                    return new_format; 
     247                } 
     248                 
     249                // add extracted GSF statements in to the main stylesheet 
     250                GSXSLT.mergeStylesheets(style_doc, new_format); 
     251                //System.out.println("added extracted GSF statements into the main stylesheet") ; 
     252                 
     253                // add extracted GSF statements in to the debug test stylesheet 
     254                //GSXSLT.mergeStylesheets(oldStyle_doc, new_format); 
     255            } else { 
     256                logger.error(" couldn't parse the config_format stylesheet, adding the format info as is"); 
     257                GSXSLT.mergeStylesheets(style_doc, format_elem); 
     258            //  GSXSLT.mergeStylesheets(oldStyle_doc, format_elem); 
     259            } 
     260            logger.debug("the converted stylesheet is:"); 
     261            logger.debug(this.converter.getPrettyString(style_doc.getDocumentElement())); 
     262        } 
     263        //for debug purposes only 
     264        Document oldStyle_doc = style_doc; 
     265 
     266 
     267        Document preprocessingXsl  ; 
     268        try { 
     269            preprocessingXsl = getPreprocessDoc(); 
     270            String errMsg = ((XMLConverter.ParseErrorHandler)parser.getErrorHandler()).getErrorMessage(); 
     271            if(errMsg != null) { 
     272                return XMLTransformer.constructErrorXHTMLPage("error loading preprocess xslt file: "  
     273                + preprocess_xsl_filename + "\n" + errMsg); 
     274            }  
     275        } catch (java.io.FileNotFoundException e) { 
     276            return fileNotFoundErrorPage(e.getMessage()); 
     277        } catch (Exception e) { 
     278            e.printStackTrace() ; 
     279            System.out.println("error loading preprocess xslt") ; 
     280            return XMLTransformer.constructErrorXHTMLPage("error loading preprocess xslt\n" + e.getMessage()); 
     281        } 
     282 
     283        Document libraryXsl = null; 
     284        try { 
     285            libraryXsl = getLibraryDoc() ; 
     286            String errMsg = ((XMLConverter.ParseErrorHandler)parser.getErrorHandler()).getErrorMessage(); 
     287            if(errMsg != null) { 
     288                return XMLTransformer.constructErrorXHTMLPage("Error loading xslt file: "  
     289                + this.getLibraryXSLFilename() + "\n" + errMsg); 
     290            }  
     291        } catch (java.io.FileNotFoundException e) { 
     292            return fileNotFoundErrorPage(e.getMessage()); 
     293        } catch (Exception e) { 
     294            e.printStackTrace() ; 
     295            System.out.println("error loading library xslt") ; 
     296            return constructErrorXHTMLPage("error loading library xslt\n" + e.getMessage()) ; 
     297        } 
     298         
     299        //   Combine the skin file and library variables/templates into one document.  
     300        //   Please note: We dont just use xsl:import because the preprocessing stage   
     301        //   needs to know what's available in the library. 
     302 
     303        Document skinAndLibraryXsl = null ; 
     304        Document skinAndLibraryDoc = converter.newDOM(); 
     305        try { 
     306             
     307            skinAndLibraryXsl = converter.newDOM(); 
     308            Element root = skinAndLibraryXsl.createElement("skinAndLibraryXsl") ; 
     309            skinAndLibraryXsl.appendChild(root) ; 
     310             
     311            Element s = skinAndLibraryXsl.createElement("skinXsl") ; 
     312            s.appendChild(skinAndLibraryXsl.importNode(style_doc.getDocumentElement(), true)) ; 
     313            root.appendChild(s) ; 
     314             
     315            Element l = skinAndLibraryXsl.createElement("libraryXsl") ; 
     316            Element libraryXsl_el = libraryXsl.getDocumentElement(); 
     317            l.appendChild(skinAndLibraryXsl.importNode(libraryXsl_el, true)) ; 
     318            root.appendChild(l) ; 
     319            //System.out.println("Skin and Library XSL are now together") ; 
     320             
     321             
     322            //System.out.println("Pre-processing the skin file...") ; 
     323             
     324            //pre-process the skin style sheet 
     325            //In other words, apply the preProcess.xsl to 'skinAndLibraryXsl' in order to 
     326            //expand all GS-Lib statements into complete XSL statements and also to create 
     327            //a valid  xsl style sheet document. 
     328 
     329            Transformer preProcessor = transformerFactory.newTransformer(new DOMSource(preprocessingXsl)); 
     330            preProcessor.setErrorListener(new XMLTransformer.TransformErrorListener()); 
     331            DOMResult result = new DOMResult(); 
     332            result.setNode(skinAndLibraryDoc); 
     333            preProcessor.transform(new DOMSource(skinAndLibraryXsl), result); 
     334            System.out.println("GS-Lib statements are now expanded") ;       
     335             
     336        }    
     337        catch (TransformerException e) { 
     338            e.printStackTrace() ; 
     339            System.out.println("TransformerException while preprocessing the skin xslt") ; 
     340            return XMLTransformer.constructErrorXHTMLPage(e.getMessage()) ; 
     341        } 
     342        catch (Exception e) { 
     343            e.printStackTrace() ; 
     344            System.out.println("Error while preprocessing the skin xslt") ; 
     345            return XMLTransformer.constructErrorXHTMLPage(e.getMessage()) ; 
     346        } 
    197347     
    198348    // there is a thing called a URIResolver which you can set for a 
     
    200350    // instead of this absoluteIncludepaths hack 
    201351 
    202     GSXSLT.absoluteIncludePaths(style_doc, GlobalProperties.getGSDL3Home(),  
    203                     (String)this.config_params.get(GSConstants.SITE_NAME),  
    204                     collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME),  
    205                     base_interfaces); 
    206  
    207     // put the page into a document - this is necessary for xslt to get 
    208     // the paths right if you have paths relative to the document root 
    209     // eg /page. 
    210  
    211     Document doc = this.converter.newDOM(); 
    212     doc.appendChild(doc.importNode(page, true)); 
    213     return (Element)this.transformer.transform(style_doc, doc, config_params);           
    214     } 
    215  
    216     protected String getXSLTFileName(String action, String subaction, 
    217                      String collection) { 
     352        GSXSLT.absoluteIncludePaths(skinAndLibraryDoc, GlobalProperties.getGSDL3Home(),  
     353                (String)this.config_params.get(GSConstants.SITE_NAME),  
     354                collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME),  
     355                base_interfaces); 
     356 
     357 
     358        //Same but for the debug version when we want the do the transformation like we use to do 
     359        //without any gslib elements. 
     360        GSXSLT.absoluteIncludePaths(oldStyle_doc, GlobalProperties.getGSDL3Home(),  
     361                (String)this.config_params.get(GSConstants.SITE_NAME),  
     362                collection, (String)this.config_params.get(GSConstants.INTERFACE_NAME),  
     363                base_interfaces); 
     364                 
     365        //Send different stages of the skin xslt to the browser for debug purposes only 
     366        //using &o=skindoc or &o=skinandlib etc... 
     367        if (output.equals("skindoc")) { 
     368            return converter.getDOM(getStringFromDocument(style_doc)); 
     369        } 
     370        if (output.equals("skinandlib")) { 
     371            return converter.getDOM(getStringFromDocument(skinAndLibraryXsl)); 
     372        } 
     373        if (output.equals("skinandlibdoc")) { 
     374            return converter.getDOM(getStringFromDocument(skinAndLibraryDoc)); 
     375        } 
     376        if (output.equals("oldskindoc")) { 
     377            return converter.getDOM(getStringFromDocument(oldStyle_doc)); 
     378        } 
     379 
     380        // DocType defaults in case the skin doesn't have an "xsl:output" element 
     381        String qualifiedName = "html"; 
     382        String publicID = "-//W3C//DTD HTML 4.01 Transitional//EN"; 
     383        String systemID = "http://www.w3.org/TR/html4/loose.dtd"; 
     384         
     385        // Try to get the system and public ID from the current skin xsl document 
     386        // otherwise keep the default values. 
     387        Element root = skinAndLibraryDoc.getDocumentElement(); 
     388        NodeList nodes = root.getElementsByTagName("xsl:output"); 
     389        // If there is at least one "xsl:output" command in the final xsl then... 
     390        if(nodes.getLength() != 0) { 
     391            // There should be only one element called xsl:output,  
     392            // but if this is not the case get the last one 
     393            Element xsl_output = (Element)nodes.item(nodes.getLength()-1); 
     394            if (xsl_output != null) { 
     395                // Qualified name will always be html even for xhtml pages 
     396                //String attrValue = xsl_output.getAttribute("method"); 
     397                //qualifiedName = attrValue.equals("") ? qualifiedName : attrValue; 
     398                 
     399                String attrValue = xsl_output.getAttribute("doctype-system"); 
     400                systemID = attrValue.equals("") ? systemID : attrValue; 
     401                 
     402                attrValue = xsl_output.getAttribute("doctype-public"); 
     403                publicID = attrValue.equals("") ? publicID : attrValue; 
     404            } 
     405        } 
     406         
     407        // We need to create an empty document with a predefined DocType, 
     408        // that will then be used for the transformation by the DOMResult 
     409        Document docWithDoctype = converter.newDOM(qualifiedName, publicID, systemID); 
     410         
     411        //System.out.println(converter.getPrettyString(docWithDoctype)); 
     412        //System.out.println("Doctype vals: " + qualifiedName + " " + publicID + " " + systemID) ; 
     413         
     414        //System.out.println("Generate final HTML from current skin") ; 
     415        //Transformation of the XML message from the receptionist to HTML with doctype 
     416        return this.transformer.transform(skinAndLibraryDoc, doc, config_params, docWithDoctype); 
     417         
     418         
     419        // The line below will do the transformation like we use to do before having Skin++ implemented, 
     420        // it will not contain any GS-Lib statements expanded, and the result will not contain any doctype. 
     421 
     422        //return (Element)this.transformer.transform(style_doc, doc, config_params);   
     423 
     424    } 
     425     
     426     
     427    // method to convert Document to a proper XML string for debug purposes only 
     428    protected String getStringFromDocument(Document doc) 
     429    { 
     430        String content = ""; 
     431        try 
     432        { 
     433           DOMSource domSource = new DOMSource(doc); 
     434           StringWriter writer = new StringWriter(); 
     435           StreamResult result = new StreamResult(writer); 
     436           TransformerFactory tf = TransformerFactory.newInstance(); 
     437           Transformer transformer = tf.newTransformer(); 
     438           transformer.transform(domSource, result); 
     439           content = writer.toString(); 
     440           System.out.println("Change the & to &Amp; for proper debug dispay") ; 
     441           content = content.replaceAll("&", "&amp;"); 
     442           writer.flush(); 
     443        } 
     444        catch(TransformerException ex) 
     445        { 
     446           ex.printStackTrace(); 
     447           return null; 
     448        } 
     449        return content; 
     450    }  
     451 
     452 
     453    protected Document getPreprocessDoc() throws Exception { 
     454 
     455        File xslt_file = new File(preprocess_xsl_filename) ; 
     456 
     457        FileReader reader = new FileReader(xslt_file); 
     458        InputSource xml_source = new InputSource(reader); 
     459        this.parser.parse(xml_source); 
     460        Document doc = this.parser.getDocument(); 
     461 
     462        return doc ;         
     463    } 
     464 
     465    protected Document getLibraryDoc() throws Exception { 
     466        Document doc = null; 
     467        File xslt_file = new File(this.getLibraryXSLFilename()) ; 
     468 
     469        FileReader reader = new FileReader(xslt_file); 
     470        InputSource xml_source = new InputSource(reader); 
     471        this.parser.parse(xml_source); 
     472         
     473        doc = this.parser.getDocument(); 
     474        return doc ;         
     475    }    
     476 
     477    protected String getXSLTFileName(String action, String subaction, 
     478                    String collection) { 
    218479 
    219480    String name = null; 
     
    234495    } 
    235496 
     497    // returns the library.xsl path of the library file that is applicable for the current interface 
     498    protected String getLibraryXSLFilename() { 
     499        return GSFile.xmlTransformDir(GSFile.interfaceHome( 
     500            GlobalProperties.getGSDL3Home(), (String)this.config_params.get(GSConstants.INTERFACE_NAME))) 
     501            + File.separatorChar + "library.xsl"; 
     502    } 
     503     
     504    // Call this when a FileNotFoundException could be thrown when loading an xsl (xml) file. 
     505    // Returns an error xhtml page indicating which xsl (or other xml) file is missing. 
     506    protected Document fileNotFoundErrorPage(String filenameMessage) { 
     507        String errorMessage = "ERROR missing file: " + filenameMessage; 
     508        Element errPage = XMLTransformer.constructErrorXHTMLPage(errorMessage); 
     509        logger.error(errorMessage); 
     510        System.err.println("****" + errorMessage); 
     511        return errPage.getOwnerDocument(); 
     512    } 
    236513}