Package chrriis.dj.nativeswing.swtimpl

Source Code of chrriis.dj.nativeswing.swtimpl.WebBrowserObject$InitializationListener

/*
* Christopher Deckers (chrriis@nextencia.net)
* http://www.nextencia.net
*
* See the file "readme.txt" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
package chrriis.dj.nativeswing.swtimpl;

import java.awt.Color;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;

import javax.swing.SwingUtilities;
import javax.swing.event.EventListenerList;

import chrriis.common.ObjectRegistry;
import chrriis.common.Utils;
import chrriis.common.WebServer;
import chrriis.common.WebServer.HTTPData;
import chrriis.common.WebServer.HTTPRequest;
import chrriis.common.WebServer.WebServerContent;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserAdapter;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserCommandEvent;
import chrriis.dj.nativeswing.swtimpl.components.WebBrowserListener;

/**
* A helper class to simplify the development of native components that leverage a web browser plugin (like the JFlashPlayer).
* @author Christopher Deckers
*/
public abstract class WebBrowserObject {

  private final JWebBrowser webBrowser;
  private volatile int instanceID;

  public WebBrowserObject(JWebBrowser webBrowser) {
    this.webBrowser = webBrowser;
    webBrowser.getNativeComponent().setBackground(Color.WHITE);
    webBrowser.setDefaultPopupMenuRegistered(false);
    webBrowser.setBarsVisible(false);
    webBrowser.addWebBrowserListener(new WebBrowserAdapter() {
      @Override
      public void commandReceived(WebBrowserCommandEvent e) {
        if("[Chrriis]WB_setLoaded".equals(e.getCommand())) {
          Object[] listeners = listenerList.getListenerList();
          for(int i=listeners.length-2; i>=0; i-=2) {
            if(listeners[i] == InitializationListener.class) {
              ((InitializationListener)listeners[i + 1]).objectInitialized();
            }
          }
        }
      }
    });
  }

  private volatile String resourcePath;

  public String getLoadedResource() {
    return "".equals(resourcePath)? null: resourcePath;
  }

  public boolean hasContent() {
    return resourcePath != null;
  }

  @Override
  protected void finalize() throws Throwable {
    ObjectRegistry.getInstance().remove(instanceID);
    super.finalize();
  }

  private volatile String backgroundColor;

  public void load(String resourcePath) {
    backgroundColor = getHexStringColor(webBrowser.getNativeComponent().getBackground());
    this.resourcePath = resourcePath;
    ObjectRegistry.getInstance().remove(instanceID);
    if(resourcePath == null) {
      if(!webBrowser.isNativePeerDisposed()) {
        webBrowser.setHTMLContent("");
      }
      return;
    }
    instanceID = ObjectRegistry.getInstance().add(this);
    String resourceLocation = WebServer.getDefaultWebServer().getDynamicContentURL(WebBrowserObject.class.getName(), String.valueOf(instanceID), "html");
    final AtomicBoolean result = new AtomicBoolean();
    InitializationListener initializationListener = new InitializationListener() {
      public void objectInitialized() {
        removeInitializationListener(this);
        result.set(true);
      }
    };
    addInitializationListener(initializationListener);
    webBrowser.navigate(resourceLocation);
    webBrowser.getNativeComponent().runSync(new LocalMessage() {
      @Override
      public Object run(Object[] args) {
        InitializationListener initializationListener = (InitializationListener)args[0];
        final AtomicBoolean result = (AtomicBoolean)args[1];
        EventDispatchUtils.sleepWithEventDispatch(new EventDispatchUtils.Condition() {
          public boolean getValue() {
            return result.get();
          }
        }, 4000);
        removeInitializationListener(initializationListener);
        return null;
      }
    }, initializationListener, result);
  }

  public String getLocalFileURL(File localFile) {
    try {
      return localFile.toURI().toURL().toExternalForm();
    } catch(Exception e) {
    }
    return WebServer.getDefaultWebServer().getResourcePathURL(localFile.getParent(), localFile.getName());
  }

  public static String getEmbeddedObjectJavascriptName() {
    return "myEmbeddedObject";
  }

  private static final String LS = Utils.LINE_SEPARATOR;

  protected static WebServerContent getWebServerContent(HTTPRequest httpRequest) {
    String resourcePath = httpRequest.getResourcePath();
    int index = resourcePath.indexOf('/');
    final int instanceID = Integer.parseInt(resourcePath.substring(0, index));
    final WebBrowserObject webBrowserObject = (WebBrowserObject)ObjectRegistry.getInstance().get(instanceID);
    if(webBrowserObject == null) {
      return null;
    }
    resourcePath = resourcePath.substring(index + 1);
    String type = resourcePath;
    if("html".equals(type)) {
      final WebBrowserObject component = (WebBrowserObject)ObjectRegistry.getInstance().get(instanceID);
      if(component == null) {
        return new WebServerContent() {
          @Override
          public InputStream getInputStream() {
            return getInputStream("<html><body></body></html>");
          }
        };
      }
      return new WebServerContent() {
        @Override
        public InputStream getInputStream() {
          String javascriptDefinitions = component.getJavascriptDefinitions();
          javascriptDefinitions = javascriptDefinitions == null? "": javascriptDefinitions + LS;
          String additionalHeadDefinitions = component.getAdditionalHeadDefinitions();
          additionalHeadDefinitions = additionalHeadDefinitions == null? "": additionalHeadDefinitions + LS;
          String content =
            "<html>" + LS +
            "  <head>" + LS +
            "    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>" + LS +
            "    <script language=\"JavaScript\" type=\"text/javascript\">" + LS +
            "      <!--" + LS +
            "      var sendCommand = " + JWebBrowser.COMMAND_FUNCTION + ";" + LS +
            "      function postCommand(command) {" + LS +
            "        var elements = new Array();" + LS +
            "        for(var i=1; i<arguments.length; i++) {" + LS +
            "          var element = document.createElement('input');" + LS +
            "          element.type='text';" + LS +
            "          element.name='j_arg' + (i-1);" + LS +
            "          element.value=arguments[i];" + LS +
            "          document.createElement('j_arg' + (i-1));" + LS +
            "          elements[i-1] = element;" + LS +
            "          document.j_form.appendChild(element);" + LS +
            "        }" + LS +
            "        document.j_form.j_command.value = command;" + LS +
            "        document.j_form.submit();" + LS +
            "        for(var i=0; i<elements.length; i++) {" + LS +
            "          document.j_form.removeChild(elements[i]);" + LS +
            "        }" + LS +
            "      }" + LS +
            "      function getEmbeddedObject() {" + LS +
            "        var movieName = \"" + getEmbeddedObjectJavascriptName() + "\";" + LS +
            "        if(window.document[movieName]) {" + LS +
            "          return window.document[movieName];" + LS +
            "        }" + LS +
            "        if(navigator.appName.indexOf(\"Microsoft Internet\") == -1) {" + LS +
            "          if(document.embeds && document.embeds[movieName]) {" + LS +
            "            return document.embeds[movieName];" + LS +
            "          }" + LS +
            "        } else {" + LS +
            "          return document.getElementById(movieName);" + LS +
            "        }" + LS +
            "      }" + LS +
            javascriptDefinitions +
            "      //-->" + LS +
            "    </script>" + LS +
            "    <style type=\"text/css\">" + LS +
            "      html { background-color: " + webBrowserObject.backgroundColor + "; }" + LS +
            "      html, object, embed, div, body, table { width: 100%; height: 100%; min-height: 100%; margin: 0; padding: 0; overflow: hidden; text-align: center; }" + LS +
            "      object, embed, div { position: absolute; left:0; top:0;}" + LS +
            "      td { vertical-align: middle; }" + LS +
            "    </style>" + LS +
            additionalHeadDefinitions +
            "  </head>" + LS +
            "  <body height=\"*\">" + LS +
            "    <iframe style=\"display:none;\" name=\"j_iframe\"></iframe>" + LS +
            "    <form style=\"display:none;\" name=\"j_form\" action=\"" + WebServer.getDefaultWebServer().getDynamicContentURL(WebBrowserObject.class.getName(), "postCommand/" + instanceID) + "\" method=\"POST\" target=\"j_iframe\">" + LS +
            "      <input name=\"j_command\" type=\"text\"></input>" + LS +
            "    </form>" + LS +
            "    <script src=\"" + WebServer.getDefaultWebServer().getDynamicContentURL(WebBrowserObject.class.getName(), String.valueOf(instanceID), "js") + "\"></script>" + LS +
            "  </body>" + LS +
            "</html>" + LS;
          return getInputStream(content);
        }
      };
    }
    if("js".equals(type)) {
      String url = webBrowserObject.resourcePath;
      // local files may have some security restrictions depending on the plugin, so let's ask the plugin for a valid URL.
      File file = Utils.getLocalFile(url);
      if(file != null) {
        url = webBrowserObject.getLocalFileURL(file);
      }
      final String escapedURL = Utils.escapeXML(url);
      final String encodedURL = Utils.encodeURL(url);
      return new WebServerContent() {
        @Override
        public String getContentType() {
          return getDefaultMimeType(".js");
        }
        @Override
        public InputStream getInputStream() {
          ObjectHTMLConfiguration objectHtmlConfiguration = webBrowserObject.getObjectHtmlConfiguration();
          StringBuilder objectParameters = new StringBuilder();
          StringBuilder embedParameters = new StringBuilder();
          Map<String, String> parameters = objectHtmlConfiguration.getHTMLParameters();
          HashMap<String, String> htmlParameters = parameters == null? new HashMap<String, String>(): new HashMap<String, String>(parameters);
          String windowsParamName = objectHtmlConfiguration.getWindowsParamName();
          String paramName = objectHtmlConfiguration.getParamName();
          htmlParameters.remove("width");
          htmlParameters.remove("height");
          htmlParameters.remove("type");
          htmlParameters.remove("name");
          if(windowsParamName != null) {
            htmlParameters.remove(windowsParamName);
          }
          if(paramName != null) {
            htmlParameters.remove(paramName);
          }
          for(Entry<String, String> param: htmlParameters.entrySet()) {
            String name = Utils.escapeXML(param.getKey());
            String value = Utils.escapeXML(param.getValue());
            embedParameters.append(' ').append(name).append("=\"").append(value).append("\"");
            objectParameters.append("window.document.write('  <param name=\"").append(name).append("\" value=\"").append(value).append("\"/>');" + LS);
          }
          String version = objectHtmlConfiguration.getVersion();
          String versionParameter = version != null? " version=\"" + version + "\"": "";
          String embeddedObjectJavascriptName = getEmbeddedObjectJavascriptName();
          String content =
            "<!--" + LS +
            "window.document.write('<object classid=\"clsid:" + objectHtmlConfiguration.getWindowsClassID() + "\" id=\"" + embeddedObjectJavascriptName + "\" codebase=\"" + objectHtmlConfiguration.getWindowsInstallationURL() + "\" events=\"true\">');" + LS +
            (windowsParamName == null? "": "window.document.write('  <param name=\"" + windowsParamName + "\" value=\"' + decodeURIComponent('" + encodedURL + "') + '\"/>');" + LS) +
            objectParameters +
            "window.document.write('  <embed" + embedParameters + " name=\"" + embeddedObjectJavascriptName + "\"" + (paramName == null? "": " " + paramName + "=\"" + escapedURL + "\"") + " type=\"" + objectHtmlConfiguration.getMimeType() + "\" pluginspage=\"" + objectHtmlConfiguration.getInstallationURL() + "\"" + versionParameter+ ">');" + LS +
            "window.document.write('  </embed>');" + LS +
            "window.document.write('</object>');" + LS +
            "var embeddedObject = getEmbeddedObject();" + LS +
            "embeddedObject.style.width = '100%';" + LS +
            "embeddedObject.style.height = '100%';" + LS +
            "sendCommand('[Chrriis]WB_setLoaded');" + LS +
            "window.document.attachEvent(\"onkeydown\", function() {" + LS +
            "  switch (event.keyCode) {" + LS +
                 // F5
            "    case 116 :" + LS +
            "      event.returnValue = false;" + LS +
            "      event.keyCode = 0;" + LS +
            "      break;" + LS +
            "  }" + LS +
            "});" + LS +
            "//-->" + LS;
          return getInputStream(content);
        }
      };
    }
    if("postCommand".equals(type)) {
      HTTPData postData = httpRequest.getHTTPPostDataArray()[0];
      Map<String, String> headerMap = postData.getHeaderMap();
      int size = headerMap.size();
      final String command = headerMap.get("j_command");
      final String[] arguments = new String[size - 1];
      for(int i=0; i<arguments.length; i++) {
        arguments[i] = headerMap.get("j_arg" + i);
      }
      SwingUtilities.invokeLater(new Runnable() {
        public void run() {
          WebBrowserListener[] webBrowserListeners = webBrowserObject.webBrowser.getWebBrowserListeners();
          WebBrowserCommandEvent e = null;
          for(int i=webBrowserListeners.length-1; i>= 0; i--) {
            if(e == null) {
              e = new WebBrowserCommandEvent(webBrowserObject.webBrowser, command, arguments);
            }
            webBrowserListeners[i].commandReceived(e);
          }
        }
      });
      return new WebServerContent() {
        @Override
        public InputStream getInputStream() {
          String content =
            "<html>" + LS +
            "  <body>" + LS +
            "    Command sent successfully." + LS +
            "  </body>" + LS +
            "</html>" + LS;
          return getInputStream(content);
        }
      };
    }
    final String resource = resourcePath;
    return new WebServerContent() {
      @Override
      public InputStream getInputStream() {
        try {
          String url = webBrowserObject.resourcePath;
          // local files may have some security restrictions depending on the plugin, so let's ask the plugin for a valid URL.
          File file = Utils.getLocalFile(url);
          if(file != null) {
            url = webBrowserObject.getLocalFileURL(file);
          }
          url = url.substring(0, url.lastIndexOf('/')) + "/" + resource;
          return new URL(url).openStream();
        } catch (Exception e) {
        }
        return null;
      }
    };
  }

  public static class ObjectHTMLConfiguration {

    private String windowsClassID;

    public void setWindowsClassID(String windowsClassID) {
      this.windowsClassID = windowsClassID;
    }

    public String getWindowsClassID() {
      return windowsClassID;
    }

    private String windowsInstallationURL;

    public String getWindowsInstallationURL() {
      return windowsInstallationURL;
    }

    public void setWindowsInstallationURL(String windowsInstallationURL) {
      this.windowsInstallationURL = windowsInstallationURL;
    }

    private String installationURL;

    public String getInstallationURL() {
      return installationURL;
    }

    public void setInstallationURL(String installationURL) {
      this.installationURL = installationURL;
    }

    private String version;

    public String getVersion() {
      return version;
    }

    public void setVersion(String version) {
      this.version = version;
    }

    private String windowsParamName;

    public String getWindowsParamName() {
      return windowsParamName;
    }

    public void setWindowsParamName(String windowsParamName) {
      this.windowsParamName = windowsParamName;
    }

    private String paramName;

    public String getParamName() {
      return paramName;
    }

    public void setParamName(String paramName) {
      this.paramName = paramName;
    }

    private Map<String, String> htmlParameters;

    public Map<String, String> getHTMLParameters() {
      return htmlParameters;
    }

    public void setHTMLParameters(Map<String, String> htmlParameters) {
      this.htmlParameters = htmlParameters;
    }

    private String mimeType;

    public String getMimeType() {
      return mimeType;
    }

    public void setMimeType(String mimeType) {
      this.mimeType = mimeType;
    }

  }

  protected abstract ObjectHTMLConfiguration getObjectHtmlConfiguration();

  protected String getJavascriptDefinitions() {
    return null;
  }

  protected String getAdditionalHeadDefinitions() {
    return null;
  }

  private static interface InitializationListener extends EventListener {
    public void objectInitialized();
  }

  private EventListenerList listenerList = new EventListenerList();

  private void addInitializationListener(InitializationListener listener) {
    listenerList.add(InitializationListener.class, listener);
  }

  private void removeInitializationListener(InitializationListener listener) {
    listenerList.remove(InitializationListener.class, listener);
  }

//  private InitializationListener[] getInitializationListeners() {
//    return listenerList.getListeners(InitializationListener.class);
//  }

  /**
   * Set the value of a property of the object (a String, number, boolean, or array).
   */
  public void setObjectProperty(String property, Object value) {
    webBrowser.executeJavascript("try {getEmbeddedObject()." + property + " = " + JWebBrowser.convertJavaObjectToJavascript(value) + ";} catch(exxxxx) {}");
  }

  /**
   * @return The value, potentially a String, Number, boolean.
   */
  public Object getObjectProperty(String property) {
    return webBrowser.executeJavascriptWithResult("return getEmbeddedObject()." + property);
  }

  /**
   * Invoke a function on the object, with optional arguments (Strings, numbers, booleans, or array).
   */
  public void invokeObjectFunction(String functionName, Object... args) {
    webBrowser.executeJavascript("try {getEmbeddedObject()." + JWebBrowser.createJavascriptFunctionCall(functionName, args) + ";} catch(exxxxx) {}");
  }

  /**
   * Invoke a function on the object and waits for a result, with optional arguments (Strings, numbers, booleans, or array).
   * @return The value, potentially a String, Number, boolean.
   */
  public Object invokeObjectFunctionWithResult(String functionName, Object... args) {
    return webBrowser.executeJavascriptWithResult("return getEmbeddedObject()." + JWebBrowser.createJavascriptFunctionCall(functionName, args));
  }

  /**
   * Set the background color of the object, which by default is the color of the native component.
   * @param background The background to set.
   */
  public void setBackground(Color background) {
    backgroundColor = getHexStringColor(background);
    webBrowser.executeJavascript("document.bgColor = '" + backgroundColor + "';");
  }

  private static String getHexStringColor(Color background) {
    String backgroundColor = Integer.toHexString(background.getRGB() & 0xFFFFFF).toUpperCase(Locale.ENGLISH);
    backgroundColor = '#' + "000000".substring(backgroundColor.length()) + backgroundColor;
    return backgroundColor;
  }

}
TOP

Related Classes of chrriis.dj.nativeswing.swtimpl.WebBrowserObject$InitializationListener

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.
y>