Changeset 25613 for main/trunk


Ignore:
Timestamp:
2012-05-16T20:04:02+12:00 (12 years ago)
Author:
ak19
Message:

The formatting changes in 25602 and 25603 undone so that actual differences between earlier versions (revision 25501) become clear

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLTransformer.java

    r25604 r25613  
    5858import org.apache.log4j.*;
    5959
    60 /**
    61  * XMLTransformer - utility class for greenstone
    62  *
     60/** XMLTransformer - utility class for greenstone
     61 *
    6362 * transforms xml using xslt
    64  * 
     63 *
    6564 * @author <a href="mailto:[email protected]">Katherine Don</a>
    6665 * @version $Revision$
    6766 */
    68 public class XMLTransformer
    69 {
    70     private static int debugFileCount = 0; // for unique filenames when debugging XML transformations with physical files
    71 
    72     static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.XMLTransformer.class.getName());
    73 
    74     /** The transformer factory we're using */
    75     TransformerFactory t_factory = null;
    76 
    77     /**
    78      * The no-arguments constructor.
    79      *
    80      * Any exceptions thrown are caught internally
    81      *
    82      * @see javax.xml.transform.TransformerFactory
    83      */
    84     public XMLTransformer()
    85     {
    86         // http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/index.html?javax/xml/transform/TransformerFactory.html states that
    87         // TransformerFactory.newInstance() looks in jar files for a Factory specified in META-INF/services/javax.xml.transform.TransformerFactory,
    88         // else it will use the "platform default"
    89         // In this case: xalan.jar's META-INF/services/javax.xml.transform.TransformerFactory contains org.apache.xalan.processor.TransformerFactoryImpl
    90         // as required.
    91 
    92         // This means we no longer have to do a System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
    93         // followed by a this.t_factory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance();
    94         // The System.setProperty step to force the TransformerFactory implementation that gets used, conflicts with
    95         // Fedora (visiting the Greenstone server pages breaks the Greenstone-tomcat hosted Fedora pages) as Fedora
    96         // does not include the xalan.jar and therefore can't then find the xalan TransformerFactory explicitly set.
    97 
    98         // Gone back to forcing use of xalan transformer, since other jars like crimson.jar, which may be on some
    99         // classpaths, could be be chosen as the TransformerFactory implementation over xalan. This is what used to
    100         // give problems before. Instead, have placed copies of the jars that Fedora needs (xalan.jar and serializer.jar
    101         // and the related xsltc.jar which it may need) into packages/tomcat/lib so that it's on the server's classpath
    102         // and will be found by Fedora.
    103 
    104         // make sure we are using the xalan transformer
    105         System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
    106         try
    107         {
    108             this.t_factory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance();
    109             //this.t_factory = TransformerFactory.newInstance();
    110             this.t_factory.setErrorListener(new TransformErrorListener()); // handle errors in the xml Source used to instantiate transformers
    111         }
    112         catch (Exception e)
    113         {
    114             logger.error("exception creating t_factory " + e.getMessage());
    115         }
     67public class XMLTransformer {
     68    private static int debugFileCount = 0; // for unique filenames when debugging XML transformations with physical files
     69
     70    static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.XMLTransformer.class.getName());
     71   
     72  /** The transformer factory we're using */
     73    TransformerFactory t_factory=null;
     74 
     75  /**
     76   * The no-arguments constructor.
     77   *
     78   * Any exceptions thrown are caught internally
     79   *
     80   * @see javax.xml.transform.TransformerFactory
     81   */
     82    public XMLTransformer() {
     83    // http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/index.html?javax/xml/transform/TransformerFactory.html states that
     84    // TransformerFactory.newInstance() looks in jar files for a Factory specified in META-INF/services/javax.xml.transform.TransformerFactory,
     85    // else it will use the "platform default"
     86    // In this case: xalan.jar's META-INF/services/javax.xml.transform.TransformerFactory contains org.apache.xalan.processor.TransformerFactoryImpl
     87    // as required.
     88
     89    // This means we no longer have to do a System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
     90    // followed by a this.t_factory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance();
     91    // The System.setProperty step to force the TransformerFactory implementation that gets used, conflicts with
     92    // Fedora (visiting the Greenstone server pages breaks the Greenstone-tomcat hosted Fedora pages) as Fedora
     93    // does not include the xalan.jar and therefore can't then find the xalan TransformerFactory explicitly set.
     94
     95    // Gone back to forcing use of xalan transformer, since other jars like crimson.jar, which may be on some
     96    // classpaths, could be be chosen as the TransformerFactory implementation over xalan. This is what used to
     97    // give problems before. Instead, have placed copies of the jars that Fedora needs (xalan.jar and serializer.jar
     98    // and the related xsltc.jar which it may need) into packages/tomcat/lib so that it's on the server's classpath
     99    // and will be found by Fedora.
     100
     101    // make sure we are using the xalan transformer
     102    System.setProperty("javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl");
     103    try {
     104        this.t_factory = org.apache.xalan.processor.TransformerFactoryImpl.newInstance();
     105        //this.t_factory = TransformerFactory.newInstance();
     106        this.t_factory.setErrorListener(new TransformErrorListener()); // handle errors in the xml Source used to instantiate transformers
     107    } catch (Exception e) {
     108        logger.error("exception creating t_factory "+e.getMessage());
    116109    }
    117 
    118     /**
    119      * Transform an XML document using a XSLT stylesheet
    120      *
    121      * @param stylesheet
    122      *            a filename for an XSLT stylesheet
    123      * @param xml_in
    124      *            the XML to be transformed
    125      * @return the transformed XML
    126      */
    127     public String transform(String stylesheet, String xml_in)
    128     {
    129 
    130         try
    131         {
    132             TransformErrorListener transformerErrorListener = (TransformErrorListener) this.t_factory.getErrorListener();
    133             transformerErrorListener.setStylesheet(stylesheet);
    134             // Use the TransformerFactory to process the stylesheet Source and generate a Transformer.
    135             Transformer transformer = this.t_factory.newTransformer(new StreamSource(stylesheet));
    136 
    137             // Use the Transformer to transform an XML Source and send the output to a Result object.
    138             StringWriter output = new StringWriter();
    139             StreamSource streamSource = new StreamSource(new StringReader(xml_in));
    140             transformer.setErrorListener(new TransformErrorListener(stylesheet, streamSource));
    141             transformer.transform(streamSource, new StreamResult(output));
    142             return output.toString();
    143         }
    144         catch (TransformerConfigurationException e)
    145         {
    146             logger.error("couldn't create transformer object: " + e.getMessageAndLocation());
    147             logger.error(e.getLocationAsString());
    148             return "";
    149         }
    150         catch (TransformerException e)
    151         {
    152             logger.error("couldn't transform the source: " + e.getMessageAndLocation());
    153             return "";
    154         }
     110    }
     111   
     112  /**
     113   * Transform an XML document using a XSLT stylesheet
     114   *
     115   * @param stylesheet a filename for an XSLT stylesheet
     116   * @param xml_in the XML to be transformed
     117   * @return the transformed XML
     118   */
     119    public String transform(String stylesheet, String xml_in) {
     120   
     121    try {
     122        TransformErrorListener transformerErrorListener = (TransformErrorListener) this.t_factory.getErrorListener();
     123        transformerErrorListener.setStylesheet(stylesheet);
     124        // Use the TransformerFactory to process the stylesheet Source and generate a Transformer.
     125        Transformer transformer = this.t_factory.newTransformer(new StreamSource(stylesheet));
     126
     127        // Use the Transformer to transform an XML Source and send the output to a Result object.
     128        StringWriter output = new StringWriter();
     129        StreamSource streamSource = new StreamSource(new StringReader(xml_in));
     130        transformer.setErrorListener(new TransformErrorListener(stylesheet, streamSource));
     131        transformer.transform(streamSource, new StreamResult(output));
     132        return output.toString();
     133    } catch (TransformerConfigurationException e) {
     134        logger.error("couldn't create transformer object: "+e.getMessageAndLocation());
     135        logger.error(e.getLocationAsString()); 
     136        return "";
     137    } catch (TransformerException e) {
     138        logger.error("couldn't transform the source: " + e.getMessageAndLocation());
     139        return "";
     140    }   
     141    }
     142
     143    public String transformToString(Document stylesheet, Document source) {
     144    return transformToString(stylesheet, source, null);
     145    }
     146   
     147    public String transformToString(Document stylesheet, Document source, HashMap parameters) {
     148   
     149    try {
     150        TransformErrorListener transformerErrorListener = (TransformErrorListener) this.t_factory.getErrorListener();
     151        transformerErrorListener.setStylesheet(stylesheet);
     152        // Use the TransformerFactory to process the stylesheet Source and generate a Transformer.
     153        Transformer transformer = this.t_factory.newTransformer(new DOMSource(stylesheet));
     154        if (parameters != null) {
     155        Set params = parameters.entrySet();
     156        Iterator i = params.iterator();
     157        while (i.hasNext()) {
     158            Map.Entry m = (Map.Entry)i.next();
     159            transformer.setParameter((String)m.getKey(), m.getValue());
     160        }
     161        }
     162        //transformer.setParameter("page_lang", source.getDocumentElement().getAttribute(GSXML.LANG_ATT));
     163
     164        // Use the Transformer to transform an XML Source and send the output to a Result object.
     165        StringWriter output = new StringWriter();
     166        DOMSource domSource = new DOMSource(source);
     167
     168        transformer.setErrorListener(new TransformErrorListener(stylesheet, domSource));
     169        transformer.transform(domSource, new StreamResult(output));
     170        return output.toString();
     171    } catch (TransformerConfigurationException e) {
     172        logger.error("couldn't create transformer object: "+e.getMessageAndLocation());
     173        logger.error(e.getLocationAsString()); 
     174        return "";
     175    } catch (TransformerException e) {
     176        logger.error("couldn't transform the source: " + e.getMessageAndLocation());
     177        return "";
    155178    }
    156 
    157     public String transformToString(Document stylesheet, Document source)
    158     {
    159         return transformToString(stylesheet, source, null);
    160     }
    161 
    162     public String transformToString(Document stylesheet, Document source, HashMap parameters)
    163     {
    164 
    165         try
    166         {
    167             TransformErrorListener transformerErrorListener = (TransformErrorListener) this.t_factory.getErrorListener();
    168             transformerErrorListener.setStylesheet(stylesheet);
    169             // Use the TransformerFactory to process the stylesheet Source and generate a Transformer.
    170             Transformer transformer = this.t_factory.newTransformer(new DOMSource(stylesheet));
    171             if (parameters != null)
    172             {
    173                 Set params = parameters.entrySet();
    174                 Iterator i = params.iterator();
    175                 while (i.hasNext())
    176                 {
    177                     Map.Entry m = (Map.Entry) i.next();
    178                     transformer.setParameter((String) m.getKey(), m.getValue());
    179                 }
    180             }
    181             //transformer.setParameter("page_lang", source.getDocumentElement().getAttribute(GSXML.LANG_ATT));
    182 
    183             // Use the Transformer to transform an XML Source and send the output to a Result object.
    184             StringWriter output = new StringWriter();
    185             DOMSource domSource = new DOMSource(source);
    186 
    187             transformer.setErrorListener(new TransformErrorListener(stylesheet, domSource));
    188             transformer.transform(domSource, new StreamResult(output));
    189             return output.toString();
    190         }
    191         catch (TransformerConfigurationException e)
    192         {
    193             logger.error("couldn't create transformer object: " + e.getMessageAndLocation());
    194             logger.error(e.getLocationAsString());
    195             return "";
    196         }
    197         catch (TransformerException e)
    198         {
    199             logger.error("couldn't transform the source: " + e.getMessageAndLocation());
    200             return "";
    201         }
    202     }
     179    }
    203180
    204181    /**
     
    206183     * whose node should be set to the Document donated by resultNode
    207184     */
    208     public Node transform_withResultNode(Document stylesheet, Document source, Document resultNode)
    209     {
    210         return transform(stylesheet, source, null, null, resultNode);
    211     }
    212 
    213     public Node transform(Document stylesheet, Document source)
    214     {
    215         return transform(stylesheet, source, null, null, null);
    216     }
    217 
    218     public Node transform(Document stylesheet, Document source, HashMap parameters)
    219     {
    220         return transform(stylesheet, source, parameters, null, null);
    221     }
    222 
    223     public Node transform(Document stylesheet, Document source, HashMap parameters, Document docDocType)
    224     {
    225         return transform(stylesheet, source, parameters, docDocType, null);
    226     }
    227 
    228     protected Node transform(Document stylesheet, Document source, HashMap parameters, Document docDocType, Document resultNode)
    229     {
    230         try
    231         {
     185    public Node transform_withResultNode(Document stylesheet, Document source, Document resultNode) {
     186        return transform(stylesheet, source, null, null, resultNode);
     187    }
     188
     189    public Node transform(Document stylesheet, Document source) {
     190        return transform(stylesheet, source, null, null, null);
     191    }
     192   
     193    public Node transform(Document stylesheet, Document source, HashMap parameters) {
     194        return transform(stylesheet, source, parameters, null, null);
     195    }
     196
     197    public Node transform(Document stylesheet, Document source, HashMap parameters, Document docDocType) {
     198    return transform(stylesheet, source, parameters, docDocType, null);
     199    }
     200
     201    protected Node transform(Document stylesheet, Document source, HashMap parameters, Document docDocType, Document resultNode) {
     202        try {
    232203            // Use the TransformerFactory to process the stylesheet Source and generate a Transformer.
    233204            TransformErrorListener transformerErrorListener = (TransformErrorListener) this.t_factory.getErrorListener();
    234205            transformerErrorListener.setStylesheet(stylesheet);
    235206            Transformer transformer = this.t_factory.newTransformer(new DOMSource(stylesheet));
    236 
    237             //logger.info("XMLTransformer transformer is " + transformer); //done in ErrorListener
    238             if (parameters != null)
    239             {
     207            //logger.info("XMLTransformer transformer is " + transformer); //done in ErrorListener
     208           
     209            if (parameters != null) {
    240210                Set params = parameters.entrySet();
    241211                Iterator i = params.iterator();
    242                 while (i.hasNext())
    243                 {
    244                     Map.Entry m = (Map.Entry) i.next();
    245                     transformer.setParameter((String) m.getKey(), m.getValue());
     212                while (i.hasNext()) {
     213                    Map.Entry m = (Map.Entry)i.next();
     214                    transformer.setParameter((String)m.getKey(), m.getValue());
    246215                }
    247216            }
     
    253222            // that does not contain any doctype (like we use to do before).
    254223            DOMResult result = docDocType == null ? new DOMResult() : new DOMResult(docDocType);
    255             if (resultNode != null)
    256             {
    257                 result.setNode(resultNode);
     224            if(resultNode != null) {
     225                result.setNode(resultNode);
    258226            }
    259227            DOMSource domSource = new DOMSource(source);
     
    261229            transformer.transform(domSource, result);
    262230            return result.getNode(); // pass the entire document
    263         }
    264         catch (TransformerConfigurationException e)
    265         {
    266             return transformError("XMLTransformer.transform(Doc, Doc, HashMap, Doc)" + "\ncouldn't create transformer object", e);
    267         }
    268         catch (TransformerException e)
    269         {
    270             return transformError("XMLTransformer.transform(Doc, Doc, HashMap, Doc)" + "\ncouldn't transform the source", e);
    271         }
    272     }
    273 
    274     public Node transform(File stylesheet, File source)
    275     {
    276         return transform(stylesheet, source, null);
    277     }
    278 
    279     // debugAsFile is only to be set to true when either the stylesheet or source parameters
    280     // are not objects of type File. The debugAsFile variable is passed into the
    281     // TransformErrorListener. When set to true, the TransformErrorListener will itself create
    282     // two files containing the stylesheet and source XML, and try to transform the new source
    283     // file with the stylesheet file for debugging purposes.
    284     protected Node transform(File stylesheet, File source, Document docDocType)
    285     {
    286         try
    287         {
    288             TransformErrorListener transformerErrorListener = (TransformErrorListener) this.t_factory.getErrorListener();
    289             transformerErrorListener.setStylesheet(stylesheet);
    290             Transformer transformer = this.t_factory.newTransformer(new StreamSource(stylesheet));
    291             DOMResult result = (docDocType == null) ? new DOMResult() : new DOMResult(docDocType);
    292             StreamSource streamSource = new StreamSource(source);
    293 
    294             transformer.setErrorListener(new TransformErrorListener(stylesheet, streamSource));
    295 
    296             transformer.transform(streamSource, result);
    297             return result.getNode().getFirstChild();
    298         }
    299         catch (TransformerConfigurationException e)
    300         {
    301             return transformError("XMLTransformer.transform(File, File)" + "\ncouldn't create transformer object for files\n" + stylesheet + "\n" + source, e);
    302         }
    303         catch (TransformerException e)
    304         {
    305             return transformError("XMLTransformer.transform(File, File)" + "\ncouldn't transform the source for files\n" + stylesheet + "\n" + source, e);
    306         }
    307     }
    308 
     231        }
     232        catch (TransformerConfigurationException e) {
     233            return transformError("XMLTransformer.transform(Doc, Doc, HashMap, Doc)"
     234                + "\ncouldn't create transformer object", e);
     235        }
     236        catch (TransformerException e) {
     237            return transformError("XMLTransformer.transform(Doc, Doc, HashMap, Doc)"
     238                + "\ncouldn't transform the source", e);
     239        }
     240    }
     241
     242    public Node transform(File stylesheet, File source) {
     243    return transform(stylesheet, source, null);
     244    }
     245
     246    // debugAsFile is only to be set to true when either the stylesheet or source parameters
     247    // are not objects of type File. The debugAsFile variable is passed into the
     248    // TransformErrorListener. When set to true, the TransformErrorListener will itself create
     249    // two files containing the stylesheet and source XML, and try to transform the new source
     250    // file with the stylesheet file for debugging purposes.
     251    protected Node transform(File stylesheet, File source, Document docDocType) {
     252    try {
     253        TransformErrorListener transformerErrorListener = (TransformErrorListener) this.t_factory.getErrorListener();
     254        transformerErrorListener.setStylesheet(stylesheet);
     255        Transformer transformer = this.t_factory.newTransformer(new StreamSource(stylesheet));
     256        DOMResult result = (docDocType == null) ? new DOMResult() : new DOMResult(docDocType);
     257        StreamSource streamSource = new StreamSource(source);
     258
     259        transformer.setErrorListener(new TransformErrorListener(stylesheet, streamSource));
     260
     261        transformer.transform(streamSource, result);
     262        return result.getNode().getFirstChild();
     263    } catch (TransformerConfigurationException e) {
     264            return transformError("XMLTransformer.transform(File, File)"
     265                + "\ncouldn't create transformer object for files\n"
     266                + stylesheet + "\n" + source, e);
     267    }
     268    catch (TransformerException e) {
     269        return transformError("XMLTransformer.transform(File, File)"
     270                + "\ncouldn't transform the source for files\n"
     271                + stylesheet + "\n" + source, e);
     272    }   
     273    }
     274     
    309275    // Given a heading string on the sort of transformation error that occurred and the exception object itself,
    310276    // this method prints the exception to the tomcat window (system.err) and the greenstone log and then returns
    311277    // an xhtml error page that is constructed from it.
    312     protected Node transformError(String heading, TransformerException e)
    313     {
     278    protected Node transformError(String heading, TransformerException e) {
    314279        String message = heading + "\n" + e.getMessage();
    315280        logger.error(heading + ": " + e.getMessage());
    316 
    317         String location = e.getLocationAsString();
    318         if (location != null)
    319         {
     281       
     282        String location = e.getLocationAsString();     
     283        if(location != null) {
    320284            logger.error(location);
    321285            message = message + "\n" + location;
     
    324288        return constructErrorXHTMLPage(message);
    325289    }
    326 
     290   
    327291    // Given an error message, splits it into separate lines based on any newlines present and generates an xhtml page
    328292    // (xml Element)  with paragraphs for each line. This is then returned so that it can be displayed in the browser.
    329     public static Element constructErrorXHTMLPage(String message)
    330     {
    331         try
    332         {
     293    public static Element constructErrorXHTMLPage(String message) {
     294        try{
    333295            String[] lines = message.split("\n");
    334 
    335             Document xhtmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
    336             // <html></html>
    337             Node htmlNode = xhtmlDoc.createElement("html");
    338             xhtmlDoc.appendChild(htmlNode);
    339             // <head></head>
    340             Node headNode = xhtmlDoc.createElement("head");
    341             htmlNode.appendChild(headNode);
    342             // <title></title>
    343             Node titleNode = xhtmlDoc.createElement("title");
    344             headNode.appendChild(titleNode);
    345             Node titleString = xhtmlDoc.createTextNode("Error occurred");
    346             titleNode.appendChild(titleString);
    347 
    348             // <body></body>
    349             Node bodyNode = xhtmlDoc.createElement("body");
    350             htmlNode.appendChild(bodyNode);
    351 
    352             // finally put the message in the body
    353             Node h1Node = xhtmlDoc.createElement("h1");
    354             bodyNode.appendChild(h1Node);
    355             Node headingString = xhtmlDoc.createTextNode("The following error occurred:");
    356             h1Node.appendChild(headingString);
    357 
    358             //Node textNode = xhtmlDoc.createTextNode(message);
    359             //bodyNode.appendChild(textNode);
    360 
    361             for (int i = 0; i < lines.length; i++)
    362             {
     296       
     297            Document xhtmlDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
     298            // <html></html>
     299            Node htmlNode = xhtmlDoc.createElement("html");
     300            xhtmlDoc.appendChild(htmlNode);
     301            // <head></head>
     302            Node headNode = xhtmlDoc.createElement("head");
     303            htmlNode.appendChild(headNode);
     304            // <title></title>
     305            Node titleNode = xhtmlDoc.createElement("title");
     306            headNode.appendChild(titleNode);
     307            Node titleString = xhtmlDoc.createTextNode("Error occurred");
     308            titleNode.appendChild(titleString);
     309           
     310            // <body></body>
     311            Node bodyNode = xhtmlDoc.createElement("body");
     312            htmlNode.appendChild(bodyNode);
     313           
     314            // finally put the message in the body
     315            Node h1Node = xhtmlDoc.createElement("h1");
     316            bodyNode.appendChild(h1Node);
     317            Node headingString = xhtmlDoc.createTextNode("The following error occurred:");
     318            h1Node.appendChild(headingString);
     319           
     320            //Node textNode = xhtmlDoc.createTextNode(message);
     321            //bodyNode.appendChild(textNode);
     322           
     323            for (int i = 0; i < lines.length; i++) {
    363324                Node pNode = xhtmlDoc.createElement("p");
    364325                Node textNode = xhtmlDoc.createTextNode(lines[i]);
     
    366327                bodyNode.appendChild(pNode);
    367328            }
    368 
    369             return xhtmlDoc.getDocumentElement();
    370 
    371         }
    372         catch (Exception e)
    373         {
    374             String errmsg = "Exception trying to construct error xhtml page from message: " + message + "\n" + e.getMessage();
    375             System.err.println(errmsg);
    376             logger.error(errmsg);
    377             return null;
    378         }
    379     }
    380 
     329           
     330            return xhtmlDoc.getDocumentElement();
     331           
     332        }catch(Exception e) {
     333            String errmsg = "Exception trying to construct error xhtml page from message: " + message
     334                + "\n" + e.getMessage();
     335            System.err.println(errmsg);
     336            logger.error(errmsg);
     337            return null;
     338        }
     339    }
     340   
    381341    // ErrorListener class for both Transformer objects and TransformerFactory objects.
    382342    // This class can be used to register a handler for any fatal errors, errors and warnings that
     
    391351    // tomcat console (System.err), and the error message is stored in the errorMessage variable so that
    392352    // it can be retrieved and be used to generate an xhtml error page.
    393     public class TransformErrorListener implements ErrorListener
    394     {
    395         protected String errorMessage = null;
    396         protected String stylesheet = null;
    397         protected Source source = null; // can be DOMSource or StreamSource
    398         protected boolean debugAsFile = true; // true if xslt or source are not real physical files
    399 
     353    public class TransformErrorListener implements ErrorListener {
     354        protected String errorMessage = null;
     355        protected String stylesheet = null;
     356        protected Source source = null; // can be DOMSource or StreamSource
     357        protected boolean debugAsFile = true; // true if xslt or source are not real physical files
     358       
    400359        // *********** METHODS TO BE CALLED WHEN SETTING AN ERROR LISTENER ON TRANSFORMERFACTORY OBJECTS
    401360        // The default constructor is only for when setting an ErrorListener on TransformerFactory objects
     
    429388
    430389        // *********** METHODS TO BE CALLED WHEN SETTING AN ERROR LISTENER ON TRANSFORMERFACTORY OBJECTS
    431         // When setting an ErrorListener on Transformer object, the ErrorListener takes a Stylesheet xslt and a Source
    432         public TransformErrorListener(String xslt, Source source)
    433         {
    434             this.stylesheet = xslt;
    435             this.source = source;
    436             XMLTransformer.debugFileCount++;
    437         }
    438 
    439         public TransformErrorListener(Document xslt, Source source)
    440         {
    441             this.stylesheet = GSXML.elementToString(xslt.getDocumentElement(), true);
    442             this.source = source;
    443             XMLTransformer.debugFileCount++;
    444         }
    445 
    446         public TransformErrorListener(File xslt, Source source)
    447         {
    448             this.debugAsFile = false; // if this constructor is called, we're dealing with physical files for both xslt and source
    449             this.source = source;
    450             this.stylesheet = xslt.getAbsolutePath(); // not necessary to get the string from the file
    451             // all we were going to do with it *on error* was write it out to a file anyway     
    452         }
     390        // When setting an ErrorListener on Transformer object, the ErrorListener takes a Stylesheet xslt and a Source     
     391        public TransformErrorListener(String xslt, Source source) {
     392        this.stylesheet = xslt;
     393        this.source = source;
     394        XMLTransformer.debugFileCount++;
     395        }
     396
     397        public TransformErrorListener(Document xslt, Source source) {       
     398        this.stylesheet = GSXML.elementToString(xslt.getDocumentElement(), true);
     399        this.source = source;
     400        XMLTransformer.debugFileCount++;
     401        }
     402
     403        public TransformErrorListener(File xslt, Source source) {
     404        this.debugAsFile = false; // if this constructor is called, we're dealing with physical files for both xslt and source
     405        this.source = source;
     406        this.stylesheet = xslt.getAbsolutePath(); // not necessary to get the string from the file
     407                   // all we were going to do with it *on error* was write it out to a file anyway     
     408        }
    453409
    454410        // *********** METHODS CALLED AUTOMATICALLY ON ERROR
    455 
    456         //  Receive notification of a recoverable error.
    457         public void error(TransformerException exception)
    458         {
    459             handleError("Error:\n", exception);
    460         }
    461 
    462         // Receive notification of a non-recoverable error.
    463         public void fatalError(TransformerException exception)
    464         {
    465             handleError("Fatal Error:\n", exception);
    466         }
    467 
    468         // Receive notification of a warning.
    469         public void warning(TransformerException exception)
    470         {
    471             handleError("Warning:\n", exception);
    472         }
    473 
    474         public String toString(TransformerException e)
    475         {
    476             String msg = "Exception encountered was:\n\t";
    477             String location = e.getLocationAsString();
    478             if (location != null)
    479             {
    480                 msg = msg + "Location: " + location + "\n\t";
    481             }
    482 
    483             return msg + "Message: " + e.getMessage();
    484         }
    485 
    486         // clears the errorPage variable after the first call to this method
    487         public String getErrorMessage()
    488         {
    489             String errMsg = this.errorMessage;
    490             if (this.errorMessage != null)
    491             {
    492                 this.errorMessage = null;
    493             }
    494             return errMsg;
    495         }
    496 
    497         // sets the errorMessage member variable to the data stored in the exception
    498         // and writes the errorMessage to the logger and tomcat's System.err
    499         protected void handleError(String errorType, TransformerException exception)
    500         {
    501 
    502             this.errorMessage = errorType + toString(exception);
    503 
    504             // If either the stylesheet or the source to be transformed with it were not files,
    505             // so that the transformation was performed in-memory, then the "location" information
    506             // during the error handling (if any) wouldn't have been helpful.
    507             // To allow proper debugging, we write both stylesheet and source out as physical files
    508             // and perform the same transformation again, so that when a transformation error does
    509             // occur, the files are not in-memory but can be viewed, and any location information
    510             // for the error given by the ErrorListener will be sensible (instead of the unhelpful
    511             // "line#0 column#0 in file://somewhere/dummy.xsl").
    512             // Note that if the stylesheet and the source it is to transform were both physical
    513             // files to start off with, we will not need to perform the same transformation again
    514             // since the error reporting would have provided accurate locations for those.
    515             if (debugAsFile)
    516             {
    517 
    518                 performTransformWithPhysicalFiles(); // will give accurate line numbers
    519 
    520                 // No need to print out the current error message (seen in the Else statement below),
    521                 // as the recursive call to XMLTransformer.transform(File, File, false) in method
    522                 // performTransformWithPhysicalFiles() will do this for us.
    523             }
    524             else
    525             {
    526                 // printing out the error message
    527                 // since !debugAsFile, we are dealing with physical files,
    528                 // variable stylesheet would have stored the filename instead of contents
    529                 this.errorMessage = this.errorMessage + "\nstylesheet filename: " + stylesheet;
    530 
    531                 this.errorMessage += "\nException CAUSE:\n" + exception.getCause();
    532                 System.err.println("\n****Error transforming xml:\n" + this.errorMessage + "\n****\n");
    533                 //System.err.println("Stylesheet was:\n + this.stylesheet + "************END STYLESHEET***********\n\n");           
    534 
    535                 logger.error(this.errorMessage);
    536 
    537                 // now print out the source to a file, and run the stylesheet on it using a transform()
    538                 // then any error will be referring to one of these two input files.
    539             }
    540         }
    541 
    542         // This method will redo the transformation that went wrong with *real* files:
    543         // it writes out the stylesheet and source XML to files first, then performs the transformation
    544         // to get the actual line location of where things went wrong (instead of "line#0 column#0 in dummy.xsl")
    545         protected void performTransformWithPhysicalFiles()
    546         {
    547             File webLogsTmpFolder = new File(GlobalProperties.getGSDL3Home() + File.separator + "logs" + File.separator + "tmp");
    548             if (!webLogsTmpFolder.exists())
    549             {
    550                 webLogsTmpFolder.mkdirs(); // create any necessary folders
    551             }
    552             File styleFile = new File(webLogsTmpFolder + File.separator + "stylesheet" + XMLTransformer.debugFileCount + ".xml");
    553             File sourceFile = new File(webLogsTmpFolder + File.separator + "source" + XMLTransformer.debugFileCount + ".xml");
    554 
    555             try
    556             {
    557                 // write stylesheet to a file called stylesheet_systemID in tmp
    558                 FileWriter styleSheetWriter = new FileWriter(styleFile);
    559                 styleSheetWriter.write(stylesheet, 0, stylesheet.length());
    560                 styleSheetWriter.flush();
    561                 styleSheetWriter.close();
    562             }
    563             catch (Exception e)
    564             {
    565                 System.err.println("*** Exception when trying to write out stylesheet to " + styleFile.getAbsolutePath());
    566             }
    567 
    568             if (this.source != null)
    569             { // ErrorListener was set on a Transformer object
    570                 try
     411       
     412        //  Receive notification of a recoverable error.
     413        public void error(TransformerException exception) {
     414        handleError("Error:\n", exception);
     415        }
     416       
     417        // Receive notification of a non-recoverable error.
     418        public void fatalError(TransformerException exception) {
     419        handleError("Fatal Error:\n", exception);
     420        }
     421       
     422        // Receive notification of a warning.
     423        public void warning(TransformerException exception) {
     424        handleError("Warning:\n", exception);
     425        }
     426       
     427        public String toString(TransformerException e) {
     428        String msg = "Exception encountered was:\n\t";
     429        String location = e.getLocationAsString();
     430        if(location != null) {         
     431            msg = msg + "Location: " + location + "\n\t";
     432        }
     433
     434        return msg + "Message: " + e.getMessage();
     435        }
     436       
     437        // clears the errorPage variable after the first call to this method
     438        public String getErrorMessage() {
     439        String errMsg = this.errorMessage;
     440        if(this.errorMessage != null) {
     441            this.errorMessage = null;
     442        }
     443        return errMsg;
     444        }
     445       
     446        // sets the errorMessage member variable to the data stored in the exception
     447        // and writes the errorMessage to the logger and tomcat's System.err
     448        protected void handleError(String errorType, TransformerException exception) {
     449
     450        this.errorMessage = errorType + toString(exception);
     451
     452        // If either the stylesheet or the source to be transformed with it were not files,
     453        // so that the transformation was performed in-memory, then the "location" information
     454        // during the error handling (if any) wouldn't have been helpful.
     455        // To allow proper debugging, we write both stylesheet and source out as physical files
     456        // and perform the same transformation again, so that when a transformation error does
     457        // occur, the files are not in-memory but can be viewed, and any location information
     458        // for the error given by the ErrorListener will be sensible (instead of the unhelpful
     459        // "line#0 column#0 in file://somewhere/dummy.xsl").
     460        // Note that if the stylesheet and the source it is to transform were both physical
     461        // files to start off with, we will not need to perform the same transformation again
     462        // since the error reporting would have provided accurate locations for those.
     463        if(debugAsFile) {
     464           
     465            performTransformWithPhysicalFiles(); // will give accurate line numbers
     466       
     467            // No need to print out the current error message (seen in the Else statement below),
     468            // as the recursive call to XMLTransformer.transform(File, File, false) in method
     469            // performTransformWithPhysicalFiles() will do this for us.
     470        }
     471        else {
     472            // printing out the error message
     473            // since !debugAsFile, we are dealing with physical files,
     474            // variable stylesheet would have stored the filename instead of contents
     475            this.errorMessage = this.errorMessage + "\nstylesheet filename: " + stylesheet;
     476           
     477            this.errorMessage += "\nException CAUSE:\n" + exception.getCause();
     478            System.err.println("\n****Error transforming xml:\n" + this.errorMessage + "\n****\n");
     479            //System.err.println("Stylesheet was:\n + this.stylesheet + "************END STYLESHEET***********\n\n");           
     480           
     481            logger.error(this.errorMessage);
     482           
     483            // now print out the source to a file, and run the stylesheet on it using a transform()
     484            // then any error will be referring to one of these two input files.
     485        }
     486        }
     487
     488        // This method will redo the transformation that went wrong with *real* files:
     489        // it writes out the stylesheet and source XML to files first, then performs the transformation
     490        // to get the actual line location of where things went wrong (instead of "line#0 column#0 in dummy.xsl")
     491        protected void performTransformWithPhysicalFiles() {
     492        File webLogsTmpFolder = new File(GlobalProperties.getGSDL3Home() + File.separator + "logs" + File.separator + "tmp");
     493        if(!webLogsTmpFolder.exists()) {
     494            webLogsTmpFolder.mkdirs(); // create any necessary folders
     495        }
     496        File styleFile = new File(webLogsTmpFolder + File.separator + "stylesheet" + XMLTransformer.debugFileCount + ".xml");
     497        File sourceFile = new File(webLogsTmpFolder + File.separator + "source" + XMLTransformer.debugFileCount + ".xml");
     498       
     499        try {
     500            // write stylesheet to a file called stylesheet_systemID in tmp
     501            FileWriter styleSheetWriter = new FileWriter(styleFile);
     502            styleSheetWriter.write(stylesheet, 0, stylesheet.length());
     503            styleSheetWriter.flush();
     504            styleSheetWriter.close();
     505        } catch(Exception e) {
     506            System.err.println("*** Exception when trying to write out stylesheet to " + styleFile.getAbsolutePath());
     507        }   
     508       
     509        if (this.source != null) { // ErrorListener was set on a Transformer object
     510        try {
     511            FileWriter srcWriter = new FileWriter(sourceFile);
     512            String contents = "";
     513            if(source instanceof DOMSource) {
     514            DOMSource domSource = (DOMSource)source;
     515            Document doc = (Document)domSource.getNode();
     516            contents = GSXML.elementToString(doc.getDocumentElement(), true);
     517            //contents = GSXML.xmlNodeToXMLString(domSource.getNode());
     518            } else if (source instanceof StreamSource) {
     519            StreamSource streamSource = (StreamSource)source;
     520            BufferedReader reader = new BufferedReader(streamSource.getReader());
     521            String line = "";
     522            while((line = reader.readLine()) != null) {
     523                contents = contents + line + "\n";
     524            }           
     525            }
     526            srcWriter.write(contents, 0, contents.length());
     527            srcWriter.flush();
     528            srcWriter.close();     
     529        } catch(Exception e) {
     530            System.err.println("*** Exception when trying to write out stylesheet to " + sourceFile.getAbsolutePath());
     531        }
     532        }
     533       
     534        System.err.println("*****************************************");
     535        System.err.println("Look for stylesheet in: " + styleFile.getAbsolutePath());
     536        if (this.source != null) { // ErrorListener was set on a Transformer object
     537            System.err.println("Look for source XML in: " + sourceFile.getAbsolutePath());
     538        }   
     539       
     540        // now perform the transform again, which will assign another TransformErrorListener
     541        // but since debuggingAsFile is turned off, we won't recurse into this section of
     542        // handling the error again
     543        if (this.source != null) { // ErrorListener was set on a Transformer object
     544            XMLTransformer.this.transform(styleFile, sourceFile); // calls the File, File version, so debugAsFile will be false     
     545        }
     546       
     547        else { // ErrorListener was set on a TransformerFactory object
     548
     549            // The recursive step in this case is to perform the instantiation
     550            // of the Transformer object again.
     551            // Only one TransformerFactory object per XMLTransformer,
     552            // and only one TransformerHandler object set on any TransformerFactory
     553            // But the stylesheet used to create a Transformer from that TransformerFactory
     554            // object changes each time, by calls to setStylesheet(),
     555            // Therefore, the debugAsFile state for the single TransformerFactory's
     556            // TransformerHandler changes each time also.
     557
     558            try {
     559                debugAsFile = false;
     560                this.stylesheet = styleFile.getAbsolutePath();
     561                //TransformErrorListener transformerErrorListener = (TransformErrorListener)XMLTransformer.this.t_factory.getErrorListener();
     562                //transformerErrorListener.setStylesheet(styleFile);
     563                Transformer transformer = XMLTransformer.this.t_factory.newTransformer(new StreamSource(styleFile));
     564                if (transformer == null)
    571565                {
    572                     FileWriter srcWriter = new FileWriter(sourceFile);
    573                     String contents = "";
    574                     if (source instanceof DOMSource)
    575                     {
    576                         DOMSource domSource = (DOMSource) source;
    577                         Document doc = (Document) domSource.getNode();
    578                         contents = GSXML.elementToString(doc.getDocumentElement(), true);
    579                         //contents = GSXML.xmlNodeToXMLString(domSource.getNode());
    580                     }
    581                     else if (source instanceof StreamSource)
    582                     {
    583                         StreamSource streamSource = (StreamSource) source;
    584                         BufferedReader reader = new BufferedReader(streamSource.getReader());
    585                         String line = "";
    586                         while ((line = reader.readLine()) != null)
    587                         {
    588                             contents = contents + line + "\n";
    589                         }
    590                     }
    591                     srcWriter.write(contents, 0, contents.length());
    592                     srcWriter.flush();
    593                     srcWriter.close();
    594                 }
    595                 catch (Exception e)
    596                 {
    597                     System.err.println("*** Exception when trying to write out stylesheet to " + sourceFile.getAbsolutePath());
     566                    String msg = "XMLTransformer transformer is " + transformer;
     567                    logger.info(msg);
     568                    System.out.println(msg + "\n****\n");
    598569                }
    599570            }
    600 
    601             System.err.println("*****************************************");
    602             System.err.println("Look for stylesheet in: " + styleFile.getAbsolutePath());
    603             if (this.source != null)
    604             { // ErrorListener was set on a Transformer object
    605                 System.err.println("Look for source XML in: " + sourceFile.getAbsolutePath());
     571            catch (TransformerConfigurationException e)
     572            {
     573                String message = "Couldn't create transformer object: " + e.getMessageAndLocation();
     574                logger.error(message);
     575                logger.error(e.getLocationAsString());
     576                System.out.println(message);
    606577            }
    607 
    608             // now perform the transform again, which will assign another TransformErrorListener
    609             // but since debuggingAsFile is turned off, we won't recurse into this section of
    610             // handling the error again
    611             if (this.source != null)
    612             { // ErrorListener was set on a Transformer object
    613                 XMLTransformer.this.transform(styleFile, sourceFile); // calls the File, File version, so debugAsFile will be false
     578            catch (TransformerException e)
     579            {
     580                String message = "Couldn't transform the source: " + e.getMessageAndLocation();
     581                logger.error(message);
     582                System.out.println(message);
    614583            }
    615 
    616             else
    617             { // ErrorListener was set on a TransformerFactory object
    618 
    619                 // The recursive step in this case is to perform the instantiation
    620                 // of the Transformer object again.
    621                 // Only one TransformerFactory object per XMLTransformer,
    622                 // and only one TransformerHandler object set on any TransformerFactory
    623                 // But the stylesheet used to create a Transformer from that TransformerFactory
    624                 // object changes each time, by calls to setStylesheet(),
    625                 // Therefore, the debugAsFile state for the single TransformerFactory's
    626                 // TransformerHandler changes each time also.
    627 
    628                 try
    629                 {
    630                     debugAsFile = false;
    631                     this.stylesheet = styleFile.getAbsolutePath();
    632                     //TransformErrorListener transformerErrorListener = (TransformErrorListener)XMLTransformer.this.t_factory.getErrorListener();
    633                     //transformerErrorListener.setStylesheet(styleFile);
    634                     Transformer transformer = XMLTransformer.this.t_factory.newTransformer(new StreamSource(styleFile));
    635                     if (transformer == null)
    636                     {
    637                         String msg = "XMLTransformer transformer is " + transformer;
    638                         logger.info(msg);
    639                         System.out.println(msg + "\n****\n");
    640                     }
    641                 }
    642                 catch (TransformerConfigurationException e)
    643                 {
    644                     String message = "Couldn't create transformer object: " + e.getMessageAndLocation();
    645                     logger.error(message);
    646                     logger.error(e.getLocationAsString());
    647                     System.out.println(message);
    648                 }
    649                 catch (TransformerException e)
    650                 {
    651                     String message = "Couldn't transform the source: " + e.getMessageAndLocation();
    652                     logger.error(message);
    653                     System.out.println(message);
    654                 }
    655             }
    656 
    657         }
     584        }
     585       
     586        }
    658587    }
    659588}
Note: See TracChangeset for help on using the changeset viewer.