- Timestamp:
- 2012-04-19T22:09:50+12:00 (12 years ago)
- Location:
- main/trunk/greenstone3/src/java/org/greenstone/gsdl3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/TransformingReceptionist.java
r25423 r25445 593 593 Document skinAndLibraryXsl = null; 594 594 Document skinAndLibraryDoc = converter.newDOM(); 595 try 595 596 // Applying the preprocessing XSLT - in its own block {} to allow use of non-unique variable names 596 597 { 597 598 … … 615 616 //In other words, apply the preProcess.xsl to 'skinAndLibraryXsl' in order to 616 617 //expand all GS-Lib statements into complete XSL statements and also to create 617 //a valid xsl style sheet document. 618 619 Transformer preProcessor = transformerFactory.newTransformer(new DOMSource(preprocessingXsl)); 620 preProcessor.setErrorListener(new XMLTransformer.TransformErrorListener(preprocessingXsl)); 621 DOMResult result = new DOMResult(); 622 result.setNode(skinAndLibraryDoc); 623 preProcessor.transform(new DOMSource(skinAndLibraryXsl), result); 624 //System.out.println("GS-Lib statements are now expanded") ; 625 626 } 627 catch (TransformerException e) 628 { 629 e.printStackTrace(); 630 System.out.println("TransformerException while preprocessing the skin xslt"); 631 return XMLTransformer.constructErrorXHTMLPage(e.getMessage()); 632 } 633 catch (Exception e) 634 { 635 e.printStackTrace(); 636 System.out.println("Error while preprocessing the skin xslt"); 637 return XMLTransformer.constructErrorXHTMLPage(e.getMessage()); 638 } 618 //a valid xsl style sheet document. 619 620 XMLTransformer preProcessor = new XMLTransformer(); 621 // Perform the transformation, by passing in: 622 // preprocess-stylesheet, source-xsl (skinAndLibraryXsl), and the node that should 623 // be in the result (skinAndLibraryDoc) 624 preProcessor.transform_withResultNode(preprocessingXsl, skinAndLibraryXsl, skinAndLibraryDoc); 625 //System.out.println("GS-Lib statements are now expanded") ; 626 } 627 639 628 640 629 //The following code is to be uncommented if we need to append the extracted GSF statements -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/GSXML.java
r25423 r25445 1244 1244 public static String elementToString(Element e, boolean indent) 1245 1245 { 1246 String str = "**********START*************\n";1247 1246 try { 1248 1247 TransformerFactory tf = TransformerFactory.newInstance(); … … 1261 1260 } 1262 1261 finally { 1263 str += "\n***********************\n";1264 1262 return str; 1265 1263 } -
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/util/XMLTransformer.java
r25423 r25445 19 19 package org.greenstone.gsdl3.util; 20 20 21 import org.greenstone.util.GlobalProperties; 22 21 23 // XML classes 22 24 import javax.xml.transform.Transformer; … … 28 30 import javax.xml.transform.stream.StreamSource; 29 31 import javax.xml.transform.dom.DOMSource; 32 import javax.xml.transform.Source; 30 33 import javax.xml.transform.stream.StreamResult; 31 34 import javax.xml.transform.dom.DOMResult; … … 44 47 import java.io.BufferedReader; 45 48 import java.io.FileReader; 49 import java.io.FileWriter; 46 50 import java.io.File; 47 51 import java.util.HashMap; … … 62 66 */ 63 67 public class XMLTransformer { 68 private static int debugFileCount = 0; // for unique filenames when debugging XML transformations with physical files 64 69 65 70 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.util.XMLTransformer.class.getName()); … … 118 123 // Use the TransformerFactory to process the stylesheet Source and generate a Transformer. 119 124 Transformer transformer = this.t_factory.newTransformer(new StreamSource(stylesheet)); 120 transformer.setErrorListener(new TransformErrorListener(stylesheet));121 125 122 126 // Use the Transformer to transform an XML Source and send the output to a Result object. 123 127 StringWriter output = new StringWriter(); 124 125 transformer.transform(new StreamSource(new StringReader(xml_in)), new StreamResult(output)); 128 StreamSource streamSource = new StreamSource(new StringReader(xml_in)); 129 transformer.setErrorListener(new TransformErrorListener(stylesheet, streamSource)); 130 transformer.transform(streamSource, new StreamResult(output)); 126 131 return output.toString(); 127 132 } catch (TransformerConfigurationException e) { … … 139 144 } 140 145 146 141 147 public String transformToString(Document stylesheet, Document source, HashMap parameters) { 142 148 … … 144 150 // Use the TransformerFactory to process the stylesheet Source and generate a Transformer. 145 151 Transformer transformer = this.t_factory.newTransformer(new DOMSource(stylesheet)); 146 transformer.setErrorListener(new TransformErrorListener(stylesheet));147 152 if (parameters != null) { 148 153 Set params = parameters.entrySet(); … … 158 163 // Use the Transformer to transform an XML Source and send the output to a Result object. 159 164 StringWriter output = new StringWriter(); 160 161 transformer.transform(new DOMSource(source), new StreamResult(output)); 165 DOMSource domSource = new DOMSource(source); 166 167 transformer.setErrorListener(new TransformErrorListener(stylesheet, domSource)); 168 transformer.transform(domSource, new StreamResult(output)); 162 169 return output.toString(); 163 170 } catch (TransformerConfigurationException e) { … … 171 178 } 172 179 180 181 182 /** 183 * Transform an XML document using a XSLT stylesheet, 184 * but using a DOMResult whose node should be set to the Document donated by resultNode 185 */ 186 public Node transform_withResultNode(Document stylesheet, Document source, Document resultNode) { 187 return transform(stylesheet, source, null, null, resultNode); 188 } 189 173 190 public Node transform(Document stylesheet, Document source) { 174 return transform(stylesheet, source, null, null );191 return transform(stylesheet, source, null, null, null); 175 192 } 176 193 177 194 public Node transform(Document stylesheet, Document source, HashMap parameters) { 178 return transform(stylesheet, source, parameters, null );195 return transform(stylesheet, source, parameters, null, null); 179 196 } 180 197 181 198 public Node transform(Document stylesheet, Document source, HashMap parameters, Document docDocType) { 199 return transform(stylesheet, source, parameters, docDocType, null); 200 } 201 202 protected Node transform(Document stylesheet, Document source, HashMap parameters, Document docDocType, Document resultNode) { 182 203 try { 183 204 // Use the TransformerFactory to process the stylesheet Source and generate a Transformer. 184 205 Transformer transformer = this.t_factory.newTransformer(new DOMSource(stylesheet)); 185 206 logger.info("XMLTransformer transformer is " + transformer); 186 transformer.setErrorListener(new TransformErrorListener(stylesheet));187 207 if (parameters != null) { 188 208 Set params = parameters.entrySet(); … … 200 220 // that does not contain any doctype (like we use to do before). 201 221 DOMResult result = docDocType == null ? new DOMResult() : new DOMResult(docDocType); 202 transformer.transform(new DOMSource(source), result); 222 if(resultNode != null) { 223 result.setNode(resultNode); 224 } 225 DOMSource domSource = new DOMSource(source); 226 transformer.setErrorListener(new TransformErrorListener(stylesheet, domSource)); 227 transformer.transform(domSource, result); 203 228 return result.getNode(); // pass the entire document 204 229 } … … 214 239 215 240 public Node transform(File stylesheet, File source) { 241 return transform(stylesheet, source, null); 242 } 243 244 // debugAsFile is only to be set to true when either the stylesheet or source parameters 245 // are not objects of type File. The debugAsFile variable is passed into the 246 // TransformErrorListener. When set to true, the TransformErrorListener will itself create 247 // two files containing the stylesheet and source XML, and try to transform the new source 248 // file with the stylesheet file for debugging purposes. 249 protected Node transform(File stylesheet, File source, Document docDocType) { 216 250 try { 217 251 Transformer transformer = this.t_factory.newTransformer(new StreamSource(stylesheet)); 218 transformer.setErrorListener(new TransformErrorListener(stylesheet)); 219 DOMResult result = new DOMResult(); 220 transformer.transform(new StreamSource(source), result); 252 DOMResult result = (docDocType == null) ? new DOMResult() : new DOMResult(docDocType); 253 StreamSource streamSource = new StreamSource(source); 254 255 transformer.setErrorListener(new TransformErrorListener(stylesheet, streamSource)); 256 257 transformer.transform(streamSource, result); 221 258 return result.getNode().getFirstChild(); 222 259 } catch (TransformerConfigurationException e) { … … 230 267 + stylesheet + "\n" + source, e); 231 268 } 232 } 233 234 public Node transform(File stylesheet, File source, Document docDocType) { 235 try { 236 Transformer transformer = this.t_factory.newTransformer(new StreamSource(stylesheet)); 237 transformer.setErrorListener(new TransformErrorListener(stylesheet)); 238 DOMResult result = new DOMResult(docDocType); 239 transformer.transform(new StreamSource(source), result); 240 return result.getNode().getFirstChild(); 241 } catch (TransformerConfigurationException e) { 242 return transformError("XMLTransformer.transform(File, File, Doc)" 243 + "\ncouldn't create transformer object for files\n" 244 + stylesheet + "\n" + source, e); 245 } 246 catch (TransformerException e) { 247 return transformError("XMLTransformer.transform(File, File, Doc)" 248 + "\ncouldn't transform the source for files\n" 249 + stylesheet + "\n" + source, e); 250 } 251 } 252 269 } 270 253 271 // Given a heading string on the sort of transformation error that occurred and the exception object itself, 254 272 // this method prints the exception to the tomcat window (system.err) and the greenstone log and then returns … … 317 335 } 318 336 319 // ErrorListener class that can be used to register a handler for any fatal errors, errors and warnings that may 320 // occur when transforming an xml file with an xslt stylesheet. The errors are printed both to the greenstone.log and 321 // to the tomcat console (System.err), and the error message is stored in the errorMessage variable so that it can 322 // be retrieved and be used to generate an xhtml error page. 323 static public class TransformErrorListener implements ErrorListener { 337 // ErrorListener class that can be used to register a handler for any fatal errors, errors and warnings 338 // that may occur when transforming an xml file with an xslt stylesheet using the XMLTransformer. 339 // The errors are printed both to the greenstone.log and to the tomcat console (System.err), and the 340 // error message is stored in the errorMessage variable so that it can be retrieved and be used to 341 // generate an xhtml error page. 342 public class TransformErrorListener implements ErrorListener { 324 343 protected String errorMessage = null; 325 344 protected String stylesheet = null; 326 protected String file = null; 345 protected Source source = null; // can be DOMSource or StreamSource 346 protected boolean debugAsFile = true; // true if xslt or source are not real physical files 327 347 328 public TransformErrorListener(String xslt ) {348 public TransformErrorListener(String xslt, Source source) { 329 349 this.stylesheet = xslt; 330 } 331 332 public TransformErrorListener(Document xslt) { 333 //this.stylesheet = GSXML.xmlNodeToString(xslt); 350 this.source = source; 351 XMLTransformer.debugFileCount++; 352 } 353 354 public TransformErrorListener(Document xslt, Source source) { 334 355 this.stylesheet = GSXML.elementToString(xslt.getDocumentElement(), true); 335 } 336 337 public TransformErrorListener(File xslt) { 338 stylesheet = ""; 339 file = xslt.getAbsolutePath(); 340 String error = "Can't locate stylesheet file: " + xslt; 341 342 if(!xslt.exists()) { 343 stylesheet = error; 344 System.err.println("@@@@@@@ " + error); 345 return; 346 } 347 try { 348 BufferedReader in = new BufferedReader(new FileReader(xslt)); 349 String line = ""; 350 while((line = in.readLine()) != null) { 351 stylesheet = stylesheet + line + "\n"; 352 } 353 in.close(); 354 in = null; 355 } catch(Exception e) { 356 stylesheet = error; 357 System.err.println("Exception reading file: " + xslt.getAbsolutePath()); 358 e.printStackTrace(); 359 } 356 this.source = source; 357 XMLTransformer.debugFileCount++; 358 } 359 360 public TransformErrorListener(File xslt, Source source) { 361 this.debugAsFile = false; // if this constructor is called, we're dealing with physical files for both xslt and source 362 this.source = source; 363 this.stylesheet = xslt.getAbsolutePath(); // not necessary to get the string from the file 364 // all we were going to do with it *on error* was write it out to a file anyway 360 365 } 361 366 … … 383 388 } 384 389 385 // clears the errorPage variable after first call to this method390 // clears the errorPage variable after the first call to this method 386 391 public String getErrorMessage() { 387 392 String errMsg = this.errorMessage; … … 395 400 // and writes the errorMessage to the logger and tomcat's System.err 396 401 protected void handleError(String errorType, TransformerException exception) { 397 this.errorMessage = errorType + toString(exception); 398 if(file != null) { 399 this.errorMessage = this.errorMessage + "\nfilename: " + file; 400 } 401 this.errorMessage += "\nException CAUSE:\n" + exception.getCause(); 402 System.err.println("\n****Error transforming xml:\n" + this.errorMessage + "\n****\n"); 403 System.err.println("Stylesheet was:\n" + this.stylesheet + "\n\n"); 404 logger.error(this.errorMessage); 402 403 this.errorMessage = errorType + toString(exception); 404 405 // If either the stylesheet or the source to be transformed with it were not files, 406 // so that the transformation was performed in-memory, then the "location" information 407 // during the error handling (if any) wouldn't have been helpful. 408 // To allow proper debugging, we write both stylesheet and source out as physical files 409 // and perform the same transformation again, so that when a transformation error does 410 // occur, the files are not in-memory but can be viewed, and any location information 411 // for the error given by the ErrorListener will be sensible (instead of the unhelpful 412 // "line#0 column#0 in file://somewhere/dummy.xsl"). 413 // Note that if the stylesheet and the source it is to transform were both physical 414 // files to start off with, we will not need to perform the same transformation again 415 // since the error reporting would have provided accurate locations for those. 416 if(debugAsFile) { 417 418 performTransformWithPhysicalFiles(); // will give accurate line numbers 419 420 // No need to print out the current error message (seen in the Else statement below), 421 // as the recursive call to XMLTransformer.transform(File, File, false) in method 422 // performTransformWithPhysicalFiles() will do this for us. 423 } 424 else { 425 // printing out the error message 426 // since !debugAsFile, we are dealing with physical files, 427 // variable stylesheet would have stored the filename instead of contents 428 this.errorMessage = this.errorMessage + "\nstylesheet filename: " + stylesheet; 429 430 this.errorMessage += "\nException CAUSE:\n" + exception.getCause(); 431 System.err.println("\n****Error transforming xml:\n" + this.errorMessage + "\n****\n"); 432 //System.err.println("Stylesheet was:\n + this.stylesheet + "************END STYLESHEET***********\n\n"); 433 434 logger.error(this.errorMessage); 435 436 // now print out the source to a file, and run the stylesheet on it using a transform() 437 // then any error will be referring to one of these two input files. 438 } 439 } 440 441 // This method will redo the transformation that went wrong with *real* files: 442 // it writes out the stylesheet and source XML to files first, then performs the transformation 443 // to get the actual line location of where things went wrong (instead of "line#0 column#0 in dummy.xsl") 444 protected void performTransformWithPhysicalFiles() { 445 File webLogsTmpFolder = new File(GlobalProperties.getGSDL3Home() + File.separator + "logs" + File.separator + "tmp"); 446 File styleFile = new File(webLogsTmpFolder + File.separator + "stylesheet" + XMLTransformer.debugFileCount + ".xml"); 447 File sourceFile = new File(webLogsTmpFolder + File.separator + "source" + XMLTransformer.debugFileCount + ".xml"); 448 449 try { 450 // write stylesheet to a file called stylesheet_systemID in tmp 451 FileWriter styleSheetWriter = new FileWriter(styleFile); 452 styleSheetWriter.write(stylesheet, 0, stylesheet.length()); 453 styleSheetWriter.flush(); 454 styleSheetWriter.close(); 455 } catch(Exception e) { 456 System.err.println("*** Exception when trying to write out stylesheet to " + styleFile.getAbsolutePath()); 457 } 458 459 try { 460 FileWriter srcWriter = new FileWriter(sourceFile); 461 String contents = ""; 462 if(source instanceof DOMSource) { 463 DOMSource domSource = (DOMSource)source; 464 Document doc = (Document)domSource.getNode(); 465 contents = GSXML.elementToString(doc.getDocumentElement(), true); 466 //contents = GSXML.xmlNodeToXMLString(domSource.getNode()); 467 } else if (source instanceof StreamSource) { 468 StreamSource streamSource = (StreamSource)source; 469 BufferedReader reader = new BufferedReader(streamSource.getReader()); 470 String line = ""; 471 while((line = reader.readLine()) != null) { 472 contents = contents + line + "\n"; 473 } 474 } 475 srcWriter.write(contents, 0, contents.length()); 476 srcWriter.flush(); 477 srcWriter.close(); 478 } catch(Exception e) { 479 System.err.println("*** Exception when trying to write out stylesheet to " + sourceFile.getAbsolutePath()); 480 } 481 482 System.err.println("*****************************************"); 483 System.err.println("Look for stylesheet in: " + styleFile.getAbsolutePath()); 484 System.err.println("Look for source XML in: " + sourceFile.getAbsolutePath()); 485 486 // now perform the transform again, which will assign another TransformErrorListener 487 // but since debuggingAsFile is turned off, we won't recurse into this section of 488 // handling the error again 489 XMLTransformer.this.transform(styleFile, sourceFile); // calls the File, File version, so debugAsFile will be false 490 405 491 } 406 492 }
Note:
See TracChangeset
for help on using the changeset viewer.