1 19 package org.netbeans.modules.xsl.utils; 20 21 import java.io.File ; 22 import java.io.InputStream ; 23 import java.io.IOException ; 24 import java.net.URL ; 25 import java.net.MalformedURLException ; 26 import java.security.*; 27 28 import org.xml.sax.*; 29 import javax.xml.parsers.*; 30 import javax.xml.transform.*; 31 import javax.xml.transform.sax.*; 32 import javax.xml.transform.stream.*; 33 34 import org.openide.filesystems.*; 35 import org.openide.loaders.DataObject; 36 import org.openide.execution.*; 37 38 import org.netbeans.api.xml.cookies.*; 39 import org.netbeans.api.xml.services.UserCatalog; 40 import org.netbeans.spi.xml.cookies.*; 41 42 import org.netbeans.modules.xml.core.XMLDataObject; 43 44 import org.netbeans.modules.xsl.XSLDataObject; 45 46 52 public class TransformUtil { 53 54 private static final String SAX_FEATURES_NAMESPACES = "http://xml.org/sax/features/namespaces"; 56 public static final String DEFAULT_OUTPUT_EXT = "html"; 57 private static TransformerFactory transformerFactory; 58 private static SAXParserFactory saxParserFactory; 59 60 61 public static boolean isXSLTransformation (DataObject dataObject) { 62 return ( dataObject instanceof XSLDataObject ); 63 } 65 66 public static String getURLName (FileObject fileObject) throws MalformedURLException , FileStateInvalidException { 67 URL fileURL = null; 68 File file = FileUtil.toFile (fileObject); 69 70 if ( file != null ) { 71 if ( Util.THIS.isLoggable() ) { 72 try { 73 Util.THIS.debug ("[TransformUtil.getURLName]"); 74 Util.THIS.debug (" file = " + file); 75 Util.THIS.debug (" file.getCanonicalPath = " + file.getCanonicalPath()); 76 Util.THIS.debug (" file.getAbsolutePath = " + file.getAbsolutePath()); 77 Util.THIS.debug (" file.toString = " + file.toString()); 78 Util.THIS.debug (" file.toURL = " + file.toURL()); 79 } catch (Exception exc) { 80 Util.THIS.debug ("DEBUG Exception", exc); 81 } 82 } 83 84 fileURL = file.toURL(); 85 } else { 86 fileURL = fileObject.getURL(); 87 } 88 89 return fileURL.toExternalForm(); 90 } 91 92 public static URL createURL (URL baseURL, String fileName) throws MalformedURLException , FileStateInvalidException { 93 if ( Util.THIS.isLoggable() ) { 94 Util.THIS.debug ("TransformUtil.createURL:"); 95 Util.THIS.debug (" baseURL = " + baseURL); 96 Util.THIS.debug (" fileName = " + fileName); 97 } 98 99 URL url = new URL (baseURL, fileName); 100 101 if ( Util.THIS.isLoggable() ) Util.THIS.debug (" return URL = " + url); 102 103 return url; 104 } 105 106 public static Source createSource (URL baseURL, String fileName) throws IOException , MalformedURLException , FileStateInvalidException, ParserConfigurationException, SAXException { 107 URL url = createURL (baseURL, fileName); 108 InputStream is = url.openStream(); 110 is.close(); 111 112 XMLReader reader = TransformUtil.newXMLReader(); 113 114 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TransformUtil.createSource: XMLReader (http://xml.org/sax/features/namespaces) : " 115 + reader.getFeature (SAX_FEATURES_NAMESPACES)); 116 117 reader.setEntityResolver (TransformUtil.getEntityResolver()); 118 Source source = new SAXSource (reader, new InputSource (url.toExternalForm())); 119 120 return source; 121 } 122 123 public static URIResolver getURIResolver () { 124 UserCatalog catalog = UserCatalog.getDefault(); 125 URIResolver res = (catalog == null ? null : catalog.getURIResolver()); 126 return res; 127 } 128 129 public static EntityResolver getEntityResolver () { 130 UserCatalog catalog = UserCatalog.getDefault(); 131 EntityResolver res = (catalog == null ? null : catalog.getEntityResolver()); 132 return res; 133 } 134 135 136 private static TransformerFactory getTransformerFactory () { 137 if ( transformerFactory == null ) { 138 transformerFactory = TransformerFactory.newInstance(); 139 transformerFactory.setURIResolver (getURIResolver()); } 141 return transformerFactory; 142 } 143 144 private static SAXParserFactory getSAXParserFactory () throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { 145 if ( saxParserFactory == null ) { 146 saxParserFactory = SAXParserFactory.newInstance(); 147 saxParserFactory.setFeature (SAX_FEATURES_NAMESPACES, true); 148 } 149 return saxParserFactory; 150 } 151 152 153 public static Transformer newTransformer (Source xsl) throws TransformerConfigurationException { 154 Transformer transformer = getTransformerFactory().newTransformer (xsl); 155 156 if ( Util.THIS.isLoggable() ) transformer.setParameter ("transformer", xsl); 158 return transformer; 159 } 160 161 public static XMLReader newXMLReader () throws ParserConfigurationException, SAXException { 162 SAXParser parser = getSAXParserFactory().newSAXParser(); 163 return parser.getXMLReader(); 164 } 165 166 167 169 public static Source getAssociatedStylesheet (URL baseURL) { 170 if ( Util.THIS.isLoggable() ) { 171 Util.THIS.debug ("TransformUtil.getAssociatedStylesheet:"); 172 Util.THIS.debug (" baseURL = " + baseURL); 173 } 174 175 Source xml_stylesheet = null; 176 177 try { 178 XMLReader reader = newXMLReader(); 179 reader.setEntityResolver (getEntityResolver()); 180 SAXSource source = new SAXSource (reader, new InputSource (baseURL.toExternalForm())); 181 182 xml_stylesheet = getTransformerFactory().getAssociatedStylesheet (source, null, null, null); 183 184 if ( Util.THIS.isLoggable() ) { 185 Util.THIS.debug (" source = " + source.getSystemId()); 186 Util.THIS.debug (" xml_stylesheet = " + xml_stylesheet); 187 } 188 } catch (Exception exc) { if ( Util.THIS.isLoggable() ) Util.THIS.debug ("TransformUtil.getAssociatedStylesheet: !!!", exc); } 192 193 return xml_stylesheet; 194 } 195 196 public static String guessOutputExt (Source source) { 197 String ext = DEFAULT_OUTPUT_EXT; 198 199 try { 200 Transformer transformer = newTransformer (source); 201 String method = transformer.getOutputProperty (OutputKeys.METHOD); 202 203 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("[TransformUtil] guessOutputExt: method = " + method); 204 205 if ( "text".equals (method) ) { ext = "txt"; } else if ( method != null ) { 208 ext = method; 209 } 210 } catch (Exception exc) { 211 213 if ( Util.THIS.isLoggable() ) Util.THIS.debug (exc); 214 } 215 216 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("[TransformUtil] guessOutputExt: extension = " + ext); 217 218 return ext; 219 } 220 221 224 public static void transform (Source xml, TransformableCookie transformable, Source xsl, Result output, CookieObserver notifier) throws TransformerException { 225 if ( Util.THIS.isLoggable() ) { 226 Util.THIS.debug ("TransformUtil.transform"); 227 Util.THIS.debug (" XML source = " + xml.getSystemId()); 228 Util.THIS.debug (" TransformableCookie = " + transformable); 229 Util.THIS.debug (" XSL source = " + xsl.getSystemId()); 230 Util.THIS.debug (" Output Result = " + output.getSystemId()); 231 Util.THIS.debug (" CookieObserver = " + notifier); 232 } 233 234 if ( transformable != null ) { 235 236 transformable.transform (xsl, output, notifier); 237 238 } else { 239 240 try { 241 Transformer transformer = TransformUtil.newTransformer (xsl); 242 243 if (notifier != null) { 244 245 247 ProtectionDomain domain = transformer.getClass().getProtectionDomain(); 248 CodeSource codeSource = domain.getCodeSource(); 249 if (codeSource == null) { 250 notifier.receive(new CookieMessage(Util.THIS.getString("BK000", transformer.getClass().getName()))); 251 } else { 252 URL location = codeSource.getLocation(); 253 notifier.receive(new CookieMessage(Util.THIS.getString("BK001", location, transformer.getClass().getName()))); 254 } 255 256 Proxy proxy = new Proxy (notifier); 257 transformer.setErrorListener (proxy); 258 } 259 260 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("\n==> transform: param [transformer] = " + transformer.getParameter ("transformer")); 262 transformer.transform (xml, output); 263 264 } catch (Exception exc) { if ( Util.THIS.isLoggable() ) { 266 Util.THIS.debug (" EXCEPTION during transformation: " + exc.getClass().getName(), exc); 267 Util.THIS.debug (" exception's message = " + exc.getLocalizedMessage()); 268 269 Throwable tempExc = unwrapException (exc); 270 Util.THIS.debug (" wrapped exception = " + tempExc.getLocalizedMessage()); 271 } 272 273 TransformerException transExcept = null; 274 Object detail = null; 275 276 if ( exc instanceof TransformerException ) { 277 transExcept = (TransformerException)exc; 278 if ( ( notifier != null ) && 279 ( exc instanceof TransformerConfigurationException ) ) { 280 detail = new DefaultXMLProcessorDetail (transExcept); 281 } 282 } else if ( exc instanceof SAXParseException ) { 283 transExcept = new TransformerException (exc); 284 if ( notifier != null ) { 285 detail = new DefaultXMLProcessorDetail ((SAXParseException)exc); 286 } 287 } else { 288 transExcept = new TransformerException (exc); 289 if ( notifier != null ) { 290 detail = new DefaultXMLProcessorDetail (transExcept); 291 } 292 } 293 294 if ( ( notifier != null ) && 295 ( detail != null ) ) { 296 CookieMessage message = new CookieMessage 297 (unwrapException(exc).getLocalizedMessage(), 298 CookieMessage.FATAL_ERROR_LEVEL, 299 detail); 300 notifier.receive (message); 301 } 302 303 if ( Util.THIS.isLoggable() ) Util.THIS.debug ("--> throw transExcept: " + transExcept); 304 305 throw transExcept; 306 } 307 } 308 } 309 310 312 public static Throwable unwrapException (Throwable exc) { 313 Throwable wrapped = null; 314 if (exc instanceof TransformerException) { 315 wrapped = ((TransformerException) exc).getException(); 316 } else if (exc instanceof SAXException) { 317 wrapped = ((SAXException) exc).getException(); 318 } else { 319 return exc; 320 } 321 322 if ( wrapped == null ) { 323 return exc; 324 } 325 326 return unwrapException (wrapped); 327 } 328 329 330 334 private static class Proxy implements ErrorListener { 335 336 private final CookieObserver peer; 337 338 public Proxy (CookieObserver peer) { 339 if (peer == null) { 340 throw new NullPointerException (); 341 } 342 this.peer = peer; 343 } 344 345 public void error (TransformerException tex) throws TransformerException { 346 report (CookieMessage.ERROR_LEVEL, tex); 347 } 348 349 public void fatalError (TransformerException tex) throws TransformerException { 350 report (CookieMessage.FATAL_ERROR_LEVEL, tex); 351 352 throw tex; 353 } 354 355 public void warning (TransformerException tex) throws TransformerException { 356 report (CookieMessage.WARNING_LEVEL, tex); 357 } 358 359 private void report (int level, TransformerException tex) throws TransformerException { 360 if ( Util.THIS.isLoggable() ) { 361 Util.THIS.debug ("[TransformableSupport::Proxy]: report [" + level + "]: ", tex); 362 Util.THIS.debug (" exception's message = " + tex.getLocalizedMessage()); 363 364 Throwable tempExc = unwrapException (tex); 365 Util.THIS.debug (" wrapped exception = " + tempExc.getLocalizedMessage()); 366 } 367 368 Throwable unwrappedExc = unwrapException (tex); 369 CookieMessage message = new CookieMessage ( 370 unwrappedExc.getLocalizedMessage(), 371 level, 372 new DefaultXMLProcessorDetail (tex) 373 ); 374 peer.receive (message); 375 } 376 377 } 379 } 380 | Popular Tags |