1 10 package org.mmbase.util; 11 12 import java.io.*; 13 import java.util.*; 14 import java.net.URL ; 15 16 import javax.xml.transform.*; 17 import javax.xml.parsers.*; 18 import javax.xml.transform.stream.StreamResult ; 19 import javax.xml.transform.stream.StreamSource ; 20 import javax.xml.transform.dom.DOMSource ; 21 22 import org.mmbase.bridge.*; 23 import org.mmbase.bridge.util.xml.Generator; 24 25 26 import org.mmbase.cache.xslt.*; 27 28 import org.mmbase.util.xml.URIResolver; 29 import org.mmbase.util.logging.Logger; 30 import org.mmbase.util.logging.Logging; 31 32 33 42 public class XSLTransformer { 43 private static final Logger log = Logging.getLoggerInstance(XSLTransformer.class); 44 48 public XSLTransformer() {} 49 50 57 public static String transform(String xmlPath, String xslPath) { 58 return transform(xmlPath, xslPath, false); 59 } 60 61 75 public static String transform(String xmlPath, String xslPath, boolean cutXML) { 76 try { 77 StringWriter res = new StringWriter(); 78 transform(new File(xmlPath), new File(xslPath), new StreamResult (res), null, true); 79 String s = res.toString(); 80 int n = s.indexOf("\n"); 81 if (cutXML && s.length() > n) { 82 s = s.substring(n + 1); 83 } 84 return s; 85 } catch (Exception e) { 86 log.error(e.getMessage()); 87 log.error(Logging.stackTrace(e)); 88 return "Error during XSLT tranformation: "+e.getMessage(); 89 } 90 } 91 92 100 public static void transform(Source xml, File xslFile, Result result, Map params) throws TransformerException { 101 transform(xml, xslFile, result, params, true); 102 } 103 104 116 public static void transform(Source xml, File xslFile, Result result, Map params, boolean considerDir) throws TransformerException { 117 try { 118 transform(xml, xslFile.toURL(), result, params, considerDir); 119 } catch (java.net.MalformedURLException mfe) { 120 throw new TransformerException(mfe.getMessage(), mfe); 121 } 122 } 123 124 127 public static void transform(Source xml, URL xslFile, Result result, Map params) throws TransformerException { 128 transform(xml, xslFile, result, params, true); 129 } 130 131 134 public static void transform(Source xml, URL xslFile, Result result, Map params, boolean considerDir) throws TransformerException { 135 TemplateCache cache= TemplateCache.getCache(); 136 Source xsl; 137 try { 138 xsl = new StreamSource (xslFile.openStream()); 139 } catch (IOException ioe) { 140 throw new TransformerException(ioe.getMessage(), ioe); 141 } 142 try { 143 xsl.setSystemId(xslFile.toString()); 144 } catch (Exception e) { 145 } 146 URIResolver uri; 147 if (considerDir) { 148 try { 149 uri = new URIResolver(new URL (xslFile, ".")); 150 } catch (java.net.MalformedURLException mfe) { 151 throw new TransformerException(mfe.getMessage(), mfe); 153 } 154 } else { 155 uri = new URIResolver(); 156 } 157 Templates cachedXslt = cache.getTemplates(xsl, uri); 158 if (log.isDebugEnabled()) { 159 log.debug("Size of URIResolver " + SizeOf.getByteSize(uri) + " bytes"); 161 log.debug("template cache sze " + cache.size() + " entries"); 162 } 163 if (cachedXslt == null) { 164 TransformerFactory tf = FactoryCache.getCache().getFactory(uri); 165 cachedXslt = tf.newTemplates(xsl); 166 cache.put(xsl, cachedXslt, uri); 167 } else { 168 if (log.isDebugEnabled()) log.debug("Used xslt from cache with " + xsl.getSystemId()); 169 } 170 Transformer transformer = cachedXslt.newTransformer(); 171 if (log.isDebugEnabled()) { 173 log.debug("Size of transformer " + SizeOf.getByteSize(transformer) + " bytes"); 174 } 175 if (params != null) { 176 Iterator i = params.entrySet().iterator(); 177 while (i.hasNext()){ 178 Map.Entry entry = (Map.Entry) i.next(); 179 if (log.isDebugEnabled()) log.debug("setting param " + entry.getKey() + " to " + entry.getValue()); 180 transformer.setParameter((String ) entry.getKey(), entry.getValue()); 181 } 182 } 183 transformer.transform(xml, result); 184 } 185 186 193 public static void transform(File xmlFile, File xslFile, Result result, Map params, boolean considerDir) throws TransformerException, ParserConfigurationException, java.io.IOException , org.xml.sax.SAXException { 194 DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); 196 197 XMLEntityResolver resolver = new XMLEntityResolver(true); 199 dfactory.setNamespaceAware(true); 200 DocumentBuilder db = dfactory.newDocumentBuilder(); 201 202 XMLErrorHandler handler = new XMLErrorHandler(); 203 db.setErrorHandler(handler); 204 db.setEntityResolver(resolver); 205 org.w3c.dom.Document xmlDoc = db.parse(xmlFile); 206 Source s = new DOMSource (xmlDoc); 207 s.setSystemId(xmlFile.toURL().toString()); 208 transform(s, xslFile, result, params, considerDir); 209 } 210 211 212 223 public static void transform(File xmlDir, File xslFile, File resultDir, boolean recurse, Map params, boolean considerDir) throws TransformerException, ParserConfigurationException, java.io.IOException , org.xml.sax.SAXException { 224 if (! xmlDir.isDirectory()) { 225 throw new TransformerException("" + xmlDir + " is not a directory"); 226 } 227 if (! resultDir.exists()) { 228 resultDir.mkdir(); 229 } 230 if (! resultDir.isDirectory()) { 231 throw new TransformerException("" + resultDir + " is not a directory"); 232 } 233 if (params == null) params = new HashMap(); 234 235 List exclude = (List) params.get("exclude"); 236 237 File[] files = xmlDir.listFiles(); 238 for (int i = 0; i < files.length; i++) { 239 if (exclude.contains(files[i].getName())) continue; 240 241 if (recurse && files[i].isDirectory()) { 242 if ("CVS".equals(files[i].getName())) continue; 243 File resultSubDir = new File(resultDir, files[i].getName()); 244 Map myParams; 245 if (params == null) { 246 myParams = new HashMap(); 247 } else { 248 myParams = new HashMap(params); 249 } 250 251 if (myParams.get("root") == null) { 252 myParams.put("root", "../"); 253 } else { 254 if ("./".equals(myParams.get("root"))) { 255 myParams.put("root", "../"); 256 } else { 257 myParams.put("root", myParams.get("root") + "../"); 258 } 259 } 260 log.info("Transforming directory " + files[i] + " (root is " + myParams.get("root") + ")"); 261 transform(files[i], xslFile, resultSubDir, recurse, myParams, considerDir); 262 } else { 263 if (! files[i].getName().endsWith(".xml")) continue; 264 String fileName = files[i].getName(); 265 fileName = fileName.substring(0, fileName.length() - 4); 266 params.put("filename", fileName); 267 String extension = (String ) params.get("extension"); 268 if (extension == null) extension = "html"; 269 File resultFile = new File(resultDir, fileName + "." + extension); 270 if (resultFile.lastModified() > files[i].lastModified()) { 271 log.info("Not transforming " + files[i] + " because " + resultFile + " is up to date"); 272 } else { 273 log.info("Transforming file " + files[i] + " to " + resultFile); 274 try { 275 Result res; 276 if ("true".equals(params.get("dontopenfile"))) { 277 res = new StreamResult (System.out); 278 } else { 279 res = new StreamResult (resultFile); 280 } 281 transform(files[i], xslFile, res, params, considerDir); 282 } catch (Exception e) { 283 log.error(e.toString()); 284 log.error(Logging.stackTrace(e)); 285 } 286 } 287 } 288 } 289 } 290 291 292 public static Result getResult(String [] argv) throws Exception { 293 if (argv.length > 2) { 294 FileOutputStream stream = new FileOutputStream(argv[2]); 295 Writer f = new OutputStreamWriter(stream,"utf-8"); 296 return new StreamResult (f); 297 } else { 298 return new StreamResult (new OutputStreamWriter(System.out, "utf-8")); 299 } 300 } 301 302 303 306 public static void main(String [] argv) { 307 308 if (argv.length < 2) { 310 log.info("Use with two arguments: <xslt-file>|SER <xml-inputfile|node-number> [xml-outputfile]"); 311 log.info("Use with tree arguments: xslt-file xml-inputdir xml-outputdir [key=value options]"); 312 log.info("special options can be:"); 313 log.info(" usecache=true: Use the Template cache or not (to speed up)"); 314 log.info(" exclude=<filename>: File/directory name to exclude (can be used multiple times"); 315 log.info(" extension=<file extensions>: File extensions to use in transformation results (defaults to html)"); 316 317 log.info("Other options are passed to XSL-stylesheet as parameters."); 318 319 } else { 320 Map params = new HashMap(); 321 if (argv.length > 3) { 322 for (int i = 3; i<argv.length; i++) { 323 String key = argv[i]; 324 String value = ""; 325 int p = key.indexOf("="); 326 if (p > 0) { 327 if (p<key.length()-1) value = key.substring(p+1); 328 key = key.substring(0, p); 329 } 330 if (key.equals("usecache")) { 331 TemplateCache.getCache().setActive(value.equals("true")); 332 } else if (key.equals("exclude")) { 333 if (params.get("exclude") == null) { 334 params.put("exclude", new ArrayList()); 335 } 336 List excludes = (List) params.get("exclude"); 337 excludes.add(value); 338 } else { 339 params.put(key, value); 340 } 341 } 342 } 343 try { 344 File in = new File(argv[1]); 345 if (in.exists()) { 346 if (in.isDirectory()) { 347 log.info("Transforming directory " + in); 348 long start = System.currentTimeMillis(); 349 try { 350 transform(in, new File(argv[0]), new File(argv[2]), true, params, true); 351 } catch (Exception e) { 352 log.error("Error: " + e.toString()); 353 } 354 log.info("Transforming took " + (System.currentTimeMillis() - start) / 1000.0 + " seconds"); 355 } else { 356 log.info("Transforming file " + argv[1]); 357 transform(new File(argv[1]), new File(argv[0]), getResult(argv), params, true); 358 } 359 } else { 360 log.debug("" + in + " does not exist, interpreting it as a node, connecting using RMMCI"); 361 Result result = getResult(argv); 362 String nodeNumber = argv[1]; 363 CloudContext cc = ContextProvider.getDefaultCloudContext(); 364 Cloud cloud = cc.getCloud("mmbase", "anonymous", null); 365 params.put("cloud", cloud); 366 Node node = cloud.getNode(nodeNumber); 367 DocumentBuilder documentBuilder = org.mmbase.util.xml.DocumentReader.getDocumentBuilder(); 368 Generator generator = new Generator(documentBuilder, cloud); 369 generator.setNamespaceAware(true); 370 generator.add(node, node.getNodeManager().getField("body")); 371 generator.add(node.getRelations("idrel")); 374 NodeList relatedNodes = node.getRelatedNodes("object", "idrel", "both"); 375 generator.add(relatedNodes); 376 log.debug("transforming"); 377 transform(new DOMSource (generator.getDocument()), new File(argv[0]), result, params, true); 378 } 379 } catch (Exception ex) { 380 log.error(ex.getMessage(), ex); 381 Throwable cause = ex.getCause(); 382 while (cause != null) { 383 log.error("CAUSE" + cause.getMessage(), cause); 384 cause = cause.getCause(); 385 } 386 } 387 } 388 } 389 } 390 | Popular Tags |