/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id$
 */

import java.applet.Applet;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.Label;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerException;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

/**
 * This applet demonstrates how XSL transformations can be made to run in
 * browsers without native XSLT support.
 *
 * Note that the XSLTC transformation engine is invoked through the JAXP
 * interface, using the XSLTC "use-classpath" attribute.  The
 * "use-classpath" attribute specifies to the XSLTC TransformerFactory
 * that a precompiled version of the stylesheet (translet) may be available,
 * and that that should be used in preference to recompiling the stylesheet.
 * @author Morten Jorgensen
 * @author Jacek Ambroziak
 */
public final class TransformApplet extends Applet {
    TransformerFactory tf;
    TransformDelegate transformThread;
    /**
     * This class implements a dialog box used for XSL messages/comments
     */
    public class MessageFrame extends Frame {

        public Frame frame;

        public class ButtonHandler implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                frame.setVisible(false);
            }
        }

        /**
         * This method handles xml:message and xsl:comment by displaying
         * the message/comment in a dialog box.
         */
        public MessageFrame(String title, String message) {
            super(title);
            frame = this; // Make visible to ButtonHandler
            setSize(320,200);

            // Create a panel for the message itself
            Panel center = new Panel();
            center.add(new Label(message));

            // Create a panel for the 'OK' button
            Panel bottom = new Panel();
            Button okButton = new Button("   OK   ");
            okButton.addActionListener(new ButtonHandler());
            bottom.add(okButton);

            // Add the two panels to the window/frame
            add(center, BorderLayout.CENTER);
            add(bottom,BorderLayout.SOUTH);

            // Show the whole thing
            setVisible(true);
        }

    }

    /**
     * The applet uses this method to display messages and comments
     * generated by xsl:message and xsl:comment elements.
     */
    public class AppletErrorListener implements ErrorListener {
        public void displayMessage(TransformerException e) {
            MessageFrame z = new MessageFrame("XSL transformation alert",
                                              e.getMessageAndLocation());
        }

        public void error(TransformerException e) {
            displayMessage(e);
        }

        public void fatalError(TransformerException e) {
            displayMessage(e);
        }

        public void warning(TransformerException e) {
                    displayMessage(e);
        }
    }

    /**
     * This method is the main body of the applet. The method is called
     * by some JavaScript code in an HTML document.
     */
    public synchronized String transform(Object arg1, Object arg2) {
        final String stylesheetURL = (String)arg1;
        final String documentURL = (String)arg2;

        transformThread.setStylesheetURL(stylesheetURL);
        transformThread.setDocumentURL(documentURL);
        transformThread.setWaiting(false);
        transformThread.wakeUp();
        try{
            wait();
        } catch (InterruptedException e){}
        return transformThread.getOutput();
    }

    public void start() {
        transform(getParameter("stylesheet-name"),
                  getParameter("input-document"));
    }
    public void destroy() {
        transformThread.destroy();
    }
    public void init() {
        tf = TransformerFactory.newInstance();
        try {
            tf.setAttribute("use-classpath", Boolean.TRUE);
        } catch (IllegalArgumentException iae) {
            System.err.println("Could not set XSLTC-specific TransformerFactory"
                               + " attributes.  Transformation failed.");
        }
        // Another thread is created to keep the context class loader
        // information.  When use JDK 1.4 plugin for browser, to get around the
        // problem with the bundled old version of xalan and endorsed class
        // loading mechanism
        transformThread = new TransformDelegate(true);
        Thread t = new Thread(transformThread);
        t.setName("transformThread");
        t.start();
    }
    public String getOutput(){
        return transformThread.getOutput();
    }
    public synchronized void wakeUp() {
        notifyAll();
    }
    class TransformDelegate implements Runnable {
        private boolean isRunning, isWaiting;
        private String stylesheetURL, documentURL;
        private String outPut;
        public TransformDelegate(boolean arg) {
            isRunning = arg;
            isWaiting = true;
        }
        public synchronized void run() {
            while(isRunning){
                while(isWaiting){
                    try {
                        wait();
                    } catch (InterruptedException e){}
                }
                transform();
                isWaiting = true;
                TransformApplet.this.wakeUp();
            }
        }

        public void setStylesheetURL(String arg){
            stylesheetURL = arg;
        }
        public void setDocumentURL(String arg) {
            documentURL = arg;
        }
        public String getStylesheetURL(){
            return stylesheetURL;
        }
        public String getDocumentURL() {
            return documentURL;
        }
        public void setWaiting(boolean arg) {
            isWaiting = arg;
        }
        public void destroy() {
            isRunning = false;
        }
        public synchronized void wakeUp() {
            notifyAll();
        }
        public String getOutput(){
            return outPut;
        }

        public void transform(){
            String xslURL = getStylesheetURL();
            String docURL = getDocumentURL();
            // Initialise the output stream
            StringWriter sout = new StringWriter();
            PrintWriter out = new PrintWriter(sout);
            // Check that the parameters are valid
            try {
                if (xslURL == null || docURL == null) {
                    out.println("<h1>Transformation error</h1>");
                    out.println("The parameters <b><tt>stylesheetURL</tt></b> "+
                                "and <b><tt>source</tt></b> must be specified");
                } else {
                    Transformer t = tf.newTransformer(new StreamSource(xslURL));
                    t.setErrorListener(new AppletErrorListener());

                    final long start = System.currentTimeMillis();

                    t.transform(new StreamSource(docURL),
                                new StreamResult(out));

                    final long done = System.currentTimeMillis() - start;
                    out.println("<!-- transformed by XSLTC in " + done
                                + "msecs -->");
                }
                // Now close up the sink, and return the HTML output in the
                // StringWrite object as a string.
                out.close();
                System.err.println("Transformation complete!");
                System.err.println(sout.toString());
                outPut = sout.toString();
                sout.close();
            } catch (RuntimeException e) {
                out.println("<h1>RTE</h1>");
                out.close();
                outPut = sout.toString();
            } catch (Exception e) {
                out.println("<h1>exception</h1>");
                out.println(e.toString());
                out.close();
                outPut = sout.toString();
            }
        }
    }
}
