Package client.net.sf.saxon.ce

Source Code of client.net.sf.saxon.ce.SaxonceApi

package client.net.sf.saxon.ce;

import java.util.logging.Logger;

import client.net.sf.saxon.ce.dom.XMLDOM;
import client.net.sf.saxon.ce.om.DocumentInfo;
import client.net.sf.saxon.ce.trans.XPathException;
import client.net.sf.saxon.ce.tree.util.URI;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Node;
import com.google.gwt.logging.client.LogConfiguration;
import com.google.gwt.user.client.Window;

/**
* A class to provide static utiltiy functions for the JavaScript API. All API
* functions must be registered within the JSNI <code>register</code> method.
* Notes: GWT-Exporter not needed here because registering static methods is
* quite straightforwards using JSNI, plus the Eclipse plug-in provides features
* such as auto-complete which makes defining function signatures simpler.
*/
public class SaxonceApi {

  private static boolean processorWasJsInitiated = false;

  public static void setProcessorWasJsInitiated() {
    processorWasJsInitiated = true;
  }

  /**
   * @return boolean to indicated to logging and other code that the
   *         XSLTProcessor was initiated from the JavaScript API
   */
  public static boolean doThrowJsExceptions() {
    return processorWasJsInitiated && (handler == null);
  }

  // API
  public static JavaScriptObject requestXML(String URI) throws Exception {

    try {
      String pageHref = Window.Location.getHref();
      String absSourceURI = (new URI(pageHref).resolve(URI)).toString();
      return createAsyncDoc(absSourceURI);
    } catch (Exception e) {
      // re-throw exception back to calling JavaScript
      throw (e);
    }
  }

  /**
   * Returns a DocumentInfo object that wraps a XML DOM document.
   *
   * If the JavaScript object passed as a parameter is not a DOM document, but
   * simply a place-holder, then the Document is first fetched synchronously
   * before wrapping.
   *
   * @param obj
   *            the DOM document or a place-holder
   * @param config
   *            The Saxon-CE configuration
   * @return a DocumentInfo object
   */
  public static DocumentInfo getDocSynchronously(JavaScriptObject obj,
      Configuration config) throws XPathException {
    String absSourceURI = getAsyncUri(obj);
    Document doc;
    try {
      if (absSourceURI != null) {
        try {
          String xml = XMLDOM.makeHTTPRequest(absSourceURI);
          doc = (Document) XMLDOM.parseXML(xml);
        } catch (Exception e) {
          throw new XPathException(
              "Synchronous HTTP GET failed for: " + absSourceURI);
        }
      } else {
        doc = (Document) obj;
      }
      // check there's a document element
      if (doc.getDocumentElement() == null) {
        throw new XPathException("no document element");
      }
    } catch (Exception e) {
      throw new XPathException("Error resolving document: "
          + e.getMessage());
    }
    return (DocumentInfo) config.wrapXMLDocument(doc, absSourceURI);
  }

  /**
   * Registers static methods of this SaxonApi class and the LogController
   * class as static methods for use in the JavaScript API, within the Saxonce
   * namespace. This method must be called when the Saxonce GWT module is
   * first loaded.
   */
  public static native void register() /*-{
    $wnd.Saxon = {};
    $wnd.Saxon.requestXML = $entry(function(url) {
      return @client.net.sf.saxon.ce.SaxonceApi::requestXML(Ljava/lang/String;)(url)
    });
    $wnd.Saxon.parseXML = $entry(function(text) {
      return @client.net.sf.saxon.ce.dom.XMLDOM::parseXML(Ljava/lang/String;)(text)
    });
    $wnd.Saxon.serializeXML = $entry(function(node) {
      return @client.net.sf.saxon.ce.dom.XMLDOM::serializeXML(Lcom/google/gwt/dom/client/Node;)(node)
    });
    $wnd.Saxon.setErrorHandler = $entry(function(handler) {
      return @client.net.sf.saxon.ce.SaxonceApi::setErrorHandler(Lcom/google/gwt/core/client/JavaScriptObject;)(handler)
    });
    $wnd.Saxon.setLogLevel = $entry(function(level) {
      return @client.net.sf.saxon.ce.LogController::setLogLevel(Ljava/lang/String;)(level)
    });
    $wnd.Saxon.getLogLevel = $entry(function() {
      return @client.net.sf.saxon.ce.LogController::getLogLevel()()
    });
    $wnd.Saxon.newXSLT20Processor = function(doc) {
      var sp = new $wnd.Saxonce.XSLT20Processor(doc);
      sp.setThis(sp);
      return sp;
    };
    $wnd.Saxon.getErrorHandler = $entry(function() {
      return @client.net.sf.saxon.ce.SaxonceApi::getErrorHandler()()
    });
    $wnd.Saxon.run = $entry(function(cmd) {
      return @client.net.sf.saxon.ce.SaxonceApi::runCommand(Lcom/google/gwt/core/client/JavaScriptObject;)(cmd)
    });
    $wnd.Saxon.getVersion = $entry(function() {
      return @client.net.sf.saxon.ce.Version::getProductVersion()()
    });
  }-*/;

  /**
   * Factory method for JavaScript API to create new XSLT20Processor Converts
   * this to new Saxonce.XSLT20Processor(doc)
   */
  public static native JavaScriptObject newXSLT20Processor(
      JavaScriptObject doc) /*-{
    return @client.net.sf.saxon.ce.XSLT20Processor::new(Lcom/google/gwt/core/client/JavaScriptObject;)(doc);
  }-*/;

  private static JavaScriptObject handler = null;

  /**
   * API call to set the function used by <code>initCallback()</code> to make
   * a JavaScript callback when a logging event occurs
   *
   * @param handlerFunction
   *            - An instance of a JavaScript function
   */
  public static void setErrorHandler(JavaScriptObject handlerFunction) {
    handler = handlerFunction;
  }

  /**
   * Public API function - but also used internally Return the function object
   * thats the error handler. This is the external error handler (set by a
   * hosting editor for example) of if there is none then the error handler
   * set using <code>setErrorHandler()
   */
  public static JavaScriptObject getErrorHandler() {
    return handler;
  }

  public static void setAnyExternalErrorHandler() {
    logHandlerExternal = callExternalErrorHandler(
        Version.getProductTitle(), "INIT");
  }

  private static boolean logHandlerExternal = false;

  public static boolean isLogHandlerExternal() {
    return logHandlerExternal;
  }

  private static native boolean callExternalErrorHandler(String message,
      String level) /*-{
    if ($wnd.external) {
      try {
        $wnd.external.saxonErrorHandler(message, level);
        return true;
      } catch (e) {
        return false;
      }
    } else {
      return false;
    }
  }-*/;

  /**
   * Calls back into the JavaScript calling code to allow logging of errors
   * and events from within JavaScript
   *
   * @param message
   *            - The error message
   * @param errorType
   *            - The error type - can be any type used by GWT-Logging
   */
  public static void makeCallback(String message, String errorType,
      String milliseconds) {
    JavaScriptObject currentHandler = getErrorHandler();
    setErrorMessage(message);
    if (currentHandler == null && !isLogHandlerExternal())
      return;

    if (!callbackErrorReported) {
      boolean success = false;

      if (currentHandler != null) {
        JavaScriptObject evt = createEventObject(message, errorType,
            milliseconds);
        success = initCallback(currentHandler, evt);
        logAnyCallbackError(success, "JS");
      }

      if (isLogHandlerExternal()) {
        success = callExternalErrorHandler(message, errorType);
        logAnyCallbackError(success, "Ext");
      }

    }
  }

  public static void logAnyCallbackError(boolean success, String name) {
    if (LogConfiguration.loggingIsEnabled() && !success) {
      callbackErrorReported = true; // prevent recursion
      Logger.getLogger("HandlerCallback").severe(
          "Exception on " + name + " errorHandler callback");
    }
  }

  static boolean callbackErrorReported = false;

  /**
   * Creates an event object for use in the JavaScript API callback
   *
   * @param message
   *            The event message
   * @param errorType
   *            The event type e.g. FINE
   * @return the event object
   */
  private static native JavaScriptObject createEventObject(String message,
      String errorType, String milliseconds) /*-{
    var eventObj = {}
    eventObj.message = message;
    eventObj.level = errorType;
    eventObj.time = milliseconds;
    return eventObj;
  }-*/;

  private static native boolean initCallback(JavaScriptObject handlerFn,
      JavaScriptObject eventObj) /*-{
    try {
      handlerFn.call(this, eventObj);
      return true;
    } catch (e) {
      return false;
    }
  }-*/;

  private static native void setErrorMessage(String msg) /*-{
    if ($wnd.Saxon) {
      $wnd.Saxon.message = msg;
    } else {
      $wnd.SaxonMessage = msg;
    }
  }-*/;

  public static native JavaScriptObject createAsyncDoc(String URI) /*-{
    var docObj = {}
    docObj.asyncUri = URI;
    return docObj;
  }-*/;

  public static native String getAsyncUri(JavaScriptObject obj) /*-{
    if (obj.asyncUri) {
      return obj.asyncUri;
    } else {
      return null;
    }
  }-*/;

  public static native JavaScriptObject runCommand(JavaScriptObject cmd) /*-{
    var proc = $wnd.Saxon.newXSLT20Processor();
    var methodVal = null;
    var sourceVal = null;
    var sourceDoc = null;
    var result = null;
    for ( var p in cmd) {
      if (cmd.hasOwnProperty(p)) {
        var pValue = cmd[p];
        switch (p) {
        case "baseOutputURI":
          proc.setBaseOutputURI(pValue);
          break;
        case "initialMode":
          proc.setInitialMode(pValue);
          break;
        case "initialTemplate":
          proc.setInitialTemplate(pValue);
          break;
        case "stylesheet":
          if (typeof pValue == 'string' || pValue instanceof String) {
            try {
              var s = $wnd.Saxon.requestXML(pValue);
              proc.importStylesheet(s);
            } catch (e) {
              throw "Saxon.run error: on importing stylesheet "
                  + pValue;
            }
          } else {
            proc.importStylesheet(pValue); //assume Document or RequestDocument
          }
          break;
        case "logLevel":
          $wnd.Saxon.setLogLevel(pValue);
          break;
        case "errorHandler":
          $wnd.Saxon.setErrorHandler(pValue);
          break;
        case "method":
          methodVal = pValue;
          break;
        case "success":
          proc.setSuccess(pValue);
          break;
        case "source":
          if (typeof pValue == 'string' || pValue instanceof String) {
            sourceDoc = $wnd.Saxon.requestXML(pValue);
          } else {
            sourceDoc = pValue;
          }
          break;
        case "parameters":
          for ( var x in pValue) {
            if (pValue.hasOwnProperty(x)) {
              proc.setParameter(null, x, pValue[x]);
            }
          }
          break;
        } //switch
      } //if
    } // for

    if (methodVal == "transformToFragment") {
      proc.transformToFragment(sourceDoc, null);
    } else if (methodVal == "transformToHTMLFragment") {
      proc.transformToHTMLFragment(sourceDoc, null);
    } else if (methodVal == "transformToDocument") {
      proc.transformToDocument(sourceDoc);
    } else {
      proc.updateHTMLDocument(sourceDoc, null);
    }
    return proc;
  }-*/;

}

// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
// This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.
TOP

Related Classes of client.net.sf.saxon.ce.SaxonceApi

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.