ru.codeinside.gses.vaadin.client.VAppletIntegration.java Source code

Java tutorial

Introduction

Here is the source code for ru.codeinside.gses.vaadin.client.VAppletIntegration.java

Source

/*
 * 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/.
 * Copyright (c) 2013, MPL CodeInside http://codeinside.ru
 */

package ru.codeinside.gses.vaadin.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.ui.HTML;
import com.vaadin.terminal.gwt.client.ApplicationConfiguration;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.ValueMap;

/**
 * Client side applet integration widget which communicates with the server.
 *
 *
 * @author Sami Ekblad
 *
 */
public class VAppletIntegration extends HTML implements Paintable {

    protected static final String PARAM_APP_SESSION = "appSession";
    protected static final String PARAM_APP_URL = "appUrl";
    protected static final String PARAM_APP_DEBUG = "appDebug";
    protected static final String PARAM_PAINTABLE_ID = "paintableId";
    protected static final String PARAM_APPLET_ID = "appletId";
    protected static final String PARAM_ACTION_URL = "actionUrl";

    /** Client-server communication attributes. */
    public static final String ATTR_APPLET_SESSION = "appletSession";
    public static final String ATTR_APPLET_CLASS = "appletClass";
    public static final String ATTR_APPLET_ARCHIVES = "appletArchives";
    public static final String ATTR_APPLET_PARAM_NAMES = "appletParamNames";
    public static final String ATTR_APPLET_PARAM_VALUES = "appletParamValues";
    public static final String ATTR_APPLET_CODEBASE = "appletCodebase";
    public static final String ATTR_APPLET_NAME = "appletName";
    public static final String ATTR_APPLET_ACTION = "action";

    public static final String ATTR_CMD = "cmd";
    public static final String ATTR_CMD_PARAMS = "cmdParams";

    /** Set the CSS class name to allow styling. */
    public static final String CLASSNAME = "v-applet";

    /** The client side widget identifier */
    protected String paintableId;

    /** Reference to the server connection object. */
    protected ApplicationConnection client;

    /** Generated applet id. Unique across the application. */
    private String appletId;

    /** Applet name. Initially same as appletId, but can be set by application */
    private String appletName;

    /** Has the applet been initialized. Applet is initialized only once. */
    private boolean appletInitialized;
    private String appletClass;
    private String[] archives = new String[] {};
    private Map<String, String> appletParameters;
    private String appletSession;
    private String height = "0";
    private String width = "0";
    private String codebase;
    private String action;

    /**
     * The constructor should first call super() to initialize the component and
     * then handle any initialization relevant to Vaadin.
     */
    public VAppletIntegration() {

        // The content will be changed in update function
        setHTML("");

        // Temporary applet id. Should not be needed.
        appletId = CLASSNAME;
        appletName = null;

        // This method call of the Paintable interface sets the component
        // style name in DOM tree
        setStyleName(CLASSNAME);

    }

    /**
     * Called whenever an update is received from the server
     */
    public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
        // This call should be made first.
        // It handles sizes, captions, tooltips, etc. automatically.
        if (client.updateComponent(this, uidl, true)) {
            // If client.updateComponent returns true there has been no changes
            // and we do not need to update anything.
            return;
        }

        // Save reference to server connection object to be able to send
        // user interaction later
        this.client = client;

        // Export client reference for applet use
        exportClientUpdateVariable(client);

        // Save the client side identifier (paintable id) for the widget
        paintableId = uidl.getId();

        appletId = CLASSNAME + paintableId;
        if (appletName == null) {
            appletName = appletId;
        }

        // Create the Java applet using HTML
        if (!appletInitialized) {

            // Applet class
            if (!uidl.hasAttribute(ATTR_APPLET_CLASS)) {
                VConsole.log("Missing attribute " + ATTR_APPLET_CLASS);
                return;
            }
            appletClass = uidl.getStringAttribute(ATTR_APPLET_CLASS);

            // Applet session
            if (!uidl.hasAttribute(ATTR_APPLET_SESSION)) {
                VConsole.log("Missing attribute " + ATTR_APPLET_SESSION);
                return;
            }
            appletSession = uidl.getStringAttribute(ATTR_APPLET_SESSION);

            // Applet name (default to id)
            if (uidl.hasAttribute(ATTR_APPLET_NAME)) {
                appletName = uidl.getStringAttribute(ATTR_APPLET_NAME);
            }
            if (appletName == null) {
                appletName = appletId;
            }

            // Applet archives
            if (!uidl.hasAttribute(ATTR_APPLET_ARCHIVES)) {
                VConsole.log("Missing attribute " + ATTR_APPLET_ARCHIVES);
                return;
            }

            // Allow overriding of the default codebase
            if (uidl.hasAttribute(ATTR_APPLET_CODEBASE)) {
                codebase = uidl.getStringAttribute(ATTR_APPLET_CODEBASE);
            }

            // Width and height if provided
            if (uidl.hasAttribute("width")) {
                setWidth(uidl.getStringAttribute("width"));
            } else {
                setWidth("0");
            }

            if (uidl.hasAttribute("height")) {
                setHeight(uidl.getStringAttribute("height"));
            } else {
                setHeight("0");
            }

            if (uidl.hasVariable(ATTR_APPLET_ACTION)) {
                action = client.translateVaadinUri(uidl.getStringVariable(ATTR_APPLET_ACTION));
            } else {
                action = "";
            }

            archives = uidl.getStringArrayAttribute(ATTR_APPLET_ARCHIVES);

            // Applet appletParameters
            appletParameters = getDefaultIntegrationParameters();
            if (uidl.hasAttribute(ATTR_APPLET_PARAM_NAMES)) {
                ValueMap map = uidl.getMapAttribute(ATTR_APPLET_PARAM_NAMES);
                Set<String> keys = map.getKeySet();
                for (String key : keys) {
                    appletParameters.put(key, map.getString(key));
                }
            }

            // Create the HTML
            setHTML(getAppletHTML());
            appletInitialized = true;
        }

        // Execute the command
        String cmd = null;
        String[] cmdParams = null;
        if (uidl.hasAttribute(ATTR_CMD)) {
            cmd = uidl.getStringAttribute(ATTR_CMD);
        }
        if (uidl.hasAttribute(ATTR_CMD_PARAMS)) {
            cmdParams = uidl.getStringArrayAttribute(ATTR_CMD_PARAMS);
        }
        if (cmd != null) {
            execute(cmd, cmdParams);
        }
    }

    private native static void exportClientUpdateVariable(ApplicationConnection client) /*-{
                                                                                        var c = client;
                                                                                        $wnd.vaadin.appletUpdateBooleanVariable = function(pid, variableName, newValue, immediate) {
                                                                                        c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;ZZ)(pid, variableName, newValue, immediate);
                                                                                        };
                                                                                        $wnd.vaadin.appletUpdateIntVariable = function(pid, variableName, newValue, immediate) {
                                                                                        c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;IZ)(pid, variableName, newValue, immediate);
                                                                                        };
                                                                                        $wnd.vaadin.appletUpdateDoubleVariable = function(pid, variableName, newValue, immediate) {
                                                                                        c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;DZ)(pid, variableName, newValue, immediate);
                                                                                        };
                                                                                        $wnd.vaadin.appletUpdateStringVariable = function(pid, variableName, newValue, immediate) {
                                                                                        c.@com.vaadin.terminal.gwt.client.ApplicationConnection::updateVariable(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)(pid, variableName, newValue, immediate);
                                                                                        };
                                                                                        }-*/;

    /**
     * Execute a command in applet using AbstractVaadinApplet.execute method.
     * Note that this requires that the applet has a method called "execute"
     *
     * @param cmd
     * @param cmdParams
     */
    public void execute(String cmd, String[] cmdParams) {
        VConsole.log("Applet command: " + getAppletId() + ",'" + cmd + "','" + cmdParams + "'");
        if (cmdParams != null && cmdParams.length > 0) {
            internalAppletExecute(getAppletId(), cmd, cmdParams);
        } else {
            internalAppletExecute(getAppletId(), cmd);
        }
    }

    /**
     * This is the internal method that invokes the execute method in applet.
     * Note that this requires that the applet has a method called "execute"
     *
     * @param id
     * @param cmd
     */
    private native void internalAppletExecute(String id, String cmd)
    /*-{
       if ($doc.applets[id]) {
        $doc.applets[id].execute(cmd);
    }
    }-*/;

    /**
     * This is the internal method that invokes the execute method in applet.
     * Note that this requires that the applet has a method called "execute"
     * with string parameters.
     *
     * @param id
     * @param cmd
     * @param cmdParams
     */
    private native void internalAppletExecute(String id, String cmd, String[] cmdParams)
    /*-{
       if ($doc.applets[id]) {
        $doc.applets[id].execute(cmd,cmdParams);
    }
    }-*/;

    /**
     * Get paintable id of this widget.
     *
     * @return
     */
    protected String getPaintableId() {
        return paintableId;
    }

    /**
     * Get applet HTML needed to initalize applet.
     *
     * Note: the default implementation does not return anything.
     *
     * @return String containing the APPLET tag needed to initialize the Java
     *         applet.
     */
    protected String getAppletHTML() {

        // Compose dependency JAR files
        List<String> archives = getArchives();
        String archiveAttribute = "";
        if (archives != null) {
            boolean first = true;
            for (String a : archives) {
                if (!first) {
                    archiveAttribute += ",";
                } else {
                    first = false;
                }
                archiveAttribute += a;
            }
        }

        // Compose applet appletParameters
        Map<String, String> appletParams = getAppletParameters();
        String appletParamStr = "";
        if (appletParams != null) {
            for (String name : appletParams.keySet()) {
                appletParamStr += "<param name=\"" + name + "\" value=\"" + appletParams.get(name) + "\" />";
            }
        }

        return "<applet mayscript=\"true\" code=\"" + "" + getAppletClass() + "" + "\" codebase=\"" + getCodebase()
                + "\" width=\"" + getWidth() + "\" height=\"" + getHeight() + "\" id=\"" + getAppletId()
                + "\" name=\"" + getAppletName() + "\" archive=\"" + archiveAttribute + "\">" + appletParamStr
                + "</applet>";
    }

    /**
     * Get codebase of this applet. By default the code base points to
     * GWT.getModuleBaseURL().
     *
     * @return
     */
    private String getCodebase() {
        return codebase == null ? GWT.getModuleBaseURL() : codebase;
    }

    protected String getHeight() {
        return height;
    }

    protected String getWidth() {
        return width;
    }

    @Override
    public void setWidth(String w) {
        super.setWidth(w);
        width = w;
    }

    @Override
    public void setHeight(String h) {
        super.setHeight(h);
        height = h;
    }

    /**
     * Get appletParameters for the applet as a Map.
     *
     * @return
     */
    protected Map<String, String> getAppletParameters() {
        return appletParameters;
    }

    /**
     * Get id for this applet.
     *
     * @return
     */
    protected String getAppletId() {
        return appletId;
    }

    /**
     * Get name for this applet.
     *
     * @return
     */
    protected String getAppletName() {
        return appletName;
    }

    /**
     * Get list of archives needed to run the applet.
     *
     * @return
     */
    protected List<String> getArchives() {
        ArrayList<String> res = new ArrayList<String>();
        for (int i = 0; i < archives.length; i++) {
            res.add(archives[i]);
        }
        return res;
    }

    /**
     * Get name of the applet class.
     *
     * @return
     */
    protected String getAppletClass() {
        return appletClass;
    }

    /**
     * Get default appletParameters for the applet.
     *
     * @return
     */
    private Map<String, String> getDefaultIntegrationParameters() {
        Map<String, String> res = new HashMap<String, String>();

        // Add default appletParameters
        res.put(PARAM_APPLET_ID, "" + getAppletId());
        res.put(PARAM_PAINTABLE_ID, "" + getPaintableId());

        String sessionId = appletSession;
        if (sessionId == null) {
            sessionId = Cookies.getCookie("JSESSIONID");
        }
        res.put(PARAM_APP_SESSION, "JSESSIONID=" + sessionId);
        res.put(PARAM_APP_DEBUG, ApplicationConfiguration.isDebugMode() ? "true" : "false");
        res.put(PARAM_APP_URL, GWT.getHostPageBaseURL());

        String prefix = client.getAppUri();
        if (prefix == null) {
            prefix = "";
        }
        res.put(PARAM_ACTION_URL, GWT.getHostPageBaseURL() + action.substring(prefix.length()));
        return res;
    }

}