1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 /* 19 * $Id: TransformApplet.java 478660 2006-11-23 20:43:59Z minchau $ 20 */ 21 22 import java.applet.Applet; 23 24 import java.awt.BorderLayout; 25 import java.awt.Button; 26 import java.awt.Frame; 27 import java.awt.Label; 28 import java.awt.Panel; 29 import java.awt.event.ActionEvent; 30 import java.awt.event.ActionListener; 31 32 import java.io.PrintWriter; 33 import java.io.StringWriter; 34 35 import javax.xml.transform.Transformer; 36 import javax.xml.transform.TransformerFactory; 37 import javax.xml.transform.TransformerException; 38 import javax.xml.transform.ErrorListener; 39 import javax.xml.transform.stream.StreamResult; 40 import javax.xml.transform.stream.StreamSource; 41 42 /** 43 * This applet demonstrates how XSL transformations can be made to run in 44 * browsers without native XSLT support. 45 * 46 * Note that the XSLTC transformation engine is invoked through the JAXP 47 * interface, using the XSLTC "use-classpath" attribute. The 48 * "use-classpath" attribute specifies to the XSLTC TransformerFactory 49 * that a precompiled version of the stylesheet (translet) may be available, 50 * and that that should be used in preference to recompiling the stylesheet. 51 * @author Morten Jorgensen 52 * @author Jacek Ambroziak 53 */ 54 public final class TransformApplet extends Applet { 55 TransformerFactory tf; 56 TransformDelegate transformThread; 57 /** 58 * This class implements a dialog box used for XSL messages/comments 59 */ 60 public class MessageFrame extends Frame { 61 62 public Frame frame; 63 64 public class ButtonHandler implements ActionListener { actionPerformed(ActionEvent e)65 public void actionPerformed(ActionEvent e) { 66 frame.setVisible(false); 67 } 68 } 69 70 /** 71 * This method handles xml:message and xsl:comment by displaying 72 * the message/comment in a dialog box. 73 */ MessageFrame(String title, String message)74 public MessageFrame(String title, String message) { 75 super(title); 76 frame = this; // Make visible to ButtonHandler 77 setSize(320,200); 78 79 // Create a panel for the message itself 80 Panel center = new Panel(); 81 center.add(new Label(message)); 82 83 // Create a panel for the 'OK' button 84 Panel bottom = new Panel(); 85 Button okButton = new Button(" OK "); 86 okButton.addActionListener(new ButtonHandler()); 87 bottom.add(okButton); 88 89 // Add the two panels to the window/frame 90 add(center, BorderLayout.CENTER); 91 add(bottom,BorderLayout.SOUTH); 92 93 // Show the whole thing 94 setVisible(true); 95 } 96 97 } 98 99 /** 100 * The applet uses this method to display messages and comments 101 * generated by xsl:message and xsl:comment elements. 102 */ 103 public class AppletErrorListener implements ErrorListener { displayMessage(TransformerException e)104 public void displayMessage(TransformerException e) { 105 MessageFrame z = new MessageFrame("XSL transformation alert", 106 e.getMessageAndLocation()); 107 } 108 error(TransformerException e)109 public void error(TransformerException e) { 110 displayMessage(e); 111 } 112 fatalError(TransformerException e)113 public void fatalError(TransformerException e) { 114 displayMessage(e); 115 } 116 warning(TransformerException e)117 public void warning(TransformerException e) { 118 displayMessage(e); 119 } 120 } 121 122 /** 123 * This method is the main body of the applet. The method is called 124 * by some JavaScript code in an HTML document. 125 */ transform(Object arg1, Object arg2)126 public synchronized String transform(Object arg1, Object arg2) { 127 final String stylesheetURL = (String)arg1; 128 final String documentURL = (String)arg2; 129 130 transformThread.setStylesheetURL(stylesheetURL); 131 transformThread.setDocumentURL(documentURL); 132 transformThread.setWaiting(false); 133 transformThread.wakeUp(); 134 try{ 135 wait(); 136 } catch (InterruptedException e){} 137 return transformThread.getOutput(); 138 } 139 start()140 public void start() { 141 transform(getParameter("stylesheet-name"), 142 getParameter("input-document")); 143 } destroy()144 public void destroy() { 145 transformThread.destroy(); 146 } init()147 public void init() { 148 tf = TransformerFactory.newInstance(); 149 try { 150 tf.setAttribute("use-classpath", Boolean.TRUE); 151 } catch (IllegalArgumentException iae) { 152 System.err.println("Could not set XSLTC-specific TransformerFactory" 153 + " attributes. Transformation failed."); 154 } 155 // Another thread is created to keep the context class loader 156 // information. When use JDK 1.4 plugin for browser, to get around the 157 // problem with the bundled old version of xalan and endorsed class 158 // loading mechanism 159 transformThread = new TransformDelegate(true); 160 Thread t = new Thread(transformThread); 161 t.setName("transformThread"); 162 t.start(); 163 } getOutput()164 public String getOutput(){ 165 return transformThread.getOutput(); 166 } wakeUp()167 public synchronized void wakeUp() { 168 notifyAll(); 169 } 170 class TransformDelegate implements Runnable { 171 private boolean isRunning, isWaiting; 172 private String stylesheetURL, documentURL; 173 private String outPut; TransformDelegate(boolean arg)174 public TransformDelegate(boolean arg) { 175 isRunning = arg; 176 isWaiting = true; 177 } run()178 public synchronized void run() { 179 while(isRunning){ 180 while(isWaiting){ 181 try { 182 wait(); 183 } catch (InterruptedException e){} 184 } 185 transform(); 186 isWaiting = true; 187 TransformApplet.this.wakeUp(); 188 } 189 } 190 setStylesheetURL(String arg)191 public void setStylesheetURL(String arg){ 192 stylesheetURL = arg; 193 } setDocumentURL(String arg)194 public void setDocumentURL(String arg) { 195 documentURL = arg; 196 } getStylesheetURL()197 public String getStylesheetURL(){ 198 return stylesheetURL; 199 } getDocumentURL()200 public String getDocumentURL() { 201 return documentURL; 202 } setWaiting(boolean arg)203 public void setWaiting(boolean arg) { 204 isWaiting = arg; 205 } destroy()206 public void destroy() { 207 isRunning = false; 208 } wakeUp()209 public synchronized void wakeUp() { 210 notifyAll(); 211 } getOutput()212 public String getOutput(){ 213 return outPut; 214 } 215 transform()216 public void transform(){ 217 String xslURL = getStylesheetURL(); 218 String docURL = getDocumentURL(); 219 // Initialise the output stream 220 StringWriter sout = new StringWriter(); 221 PrintWriter out = new PrintWriter(sout); 222 // Check that the parameters are valid 223 try { 224 if (xslURL == null || docURL == null) { 225 out.println("<h1>Transformation error</h1>"); 226 out.println("The parameters <b><tt>stylesheetURL</tt></b> "+ 227 "and <b><tt>source</tt></b> must be specified"); 228 } else { 229 Transformer t = tf.newTransformer(new StreamSource(xslURL)); 230 t.setErrorListener(new AppletErrorListener()); 231 232 final long start = System.currentTimeMillis(); 233 234 t.transform(new StreamSource(docURL), 235 new StreamResult(out)); 236 237 final long done = System.currentTimeMillis() - start; 238 out.println("<!-- transformed by XSLTC in " + done 239 + "msecs -->"); 240 } 241 // Now close up the sink, and return the HTML output in the 242 // StringWrite object as a string. 243 out.close(); 244 System.err.println("Transformation complete!"); 245 System.err.println(sout.toString()); 246 outPut = sout.toString(); 247 sout.close(); 248 } catch (RuntimeException e) { 249 out.println("<h1>RTE</h1>"); 250 out.close(); 251 outPut = sout.toString(); 252 } catch (Exception e) { 253 out.println("<h1>exception</h1>"); 254 out.println(e.toString()); 255 out.close(); 256 outPut = sout.toString(); 257 } 258 } 259 } 260 } 261