ch.unifr.pai.twice.widgets.mpproxy.client.ProxyBody.java Source code

Java tutorial

Introduction

Here is the source code for ch.unifr.pai.twice.widgets.mpproxy.client.ProxyBody.java

Source

package ch.unifr.pai.twice.widgets.mpproxy.client;

/*
 * Copyright 2013 Oliver Schmid
 * Licensed 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.
 */
import java.util.ArrayList;
import java.util.List;

import ch.unifr.pai.twice.multipointer.client.widgets.MultiFocusTextBox;
import ch.unifr.pai.twice.widgets.mpproxy.client.navig.Navigation;
import ch.unifr.pai.twice.widgets.mpproxy.shared.Rewriter;
import ch.unifr.pai.twice.widgets.mpproxy.shared.URLParser;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.AnchorElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

/**
 * Standard (non-multi pointer proxy)
 * 
 * @author Oliver Schmid
 * 
 */
public class ProxyBody {

    private static String[] attributesToManipulate = { "src", "href", "action" };
    private final ScreenShotDistributor screenShot = new ScreenShotDistributor();
    private static Navigation navigation = GWT.create(Navigation.class);

    protected static List<MultiFocusTextBox> replacements = new ArrayList<MultiFocusTextBox>();

    /**
     * Register required listeners and set up the basic objects
     */
    public void initialize() {
        Event.addNativePreviewHandler(new NativePreviewHandler() {

            /**
             * Rewrites the URLs on mouse down if somebody clicks on an anchor element
             * 
             * @see com.google.gwt.user.client.Event.NativePreviewHandler#onPreviewNativeEvent(com.google.gwt.user.client.Event.NativePreviewEvent)
             */
            @Override
            public void onPreviewNativeEvent(NativePreviewEvent event) {
                if (event.getTypeInt() == Event.ONMOUSEDOWN) {
                    EventTarget t = event.getNativeEvent().getEventTarget();
                    Element e = (Element) Element.as(t);
                    if (e != null && e.getTagName().equalsIgnoreCase("a"))
                        rewriteUrls(e);

                }
            }
        });
        Storage s = Storage.getSessionStorageIfSupported();
        if (s != null) {
            RootPanel.get().add(new Label("Multicursor: " + s.getItem("ch.unifr.pai.mice.deviceType")));
        }
        publishInterfaces();
        rewriteUrls((Element) Document.get().getDocumentElement());
        addDomChangeEvents();
        // screenShot.start();
        if (!isParentFrame()) {
            Element e = DOM.getElementById("miceNavigation");
            if (e != null)
                e.removeFromParent();
        }
    }

    /**
     * Client side logic to rewrite a given URL
     * 
     * @param e
     */
    private static void rewriteUrls(Element e) {
        URLParser parser = new URLParser(Window.Location.getHref(),
                Rewriter.getServletPath(Window.Location.getHref()));
        if (parser.getServletPath() != null && !parser.getServletPath().isEmpty()
                && parser.getProxyBasePath() != null && !parser.getProxyBasePath().isEmpty())
            rewriteUrl(e, parser.getServletPath(), parser.getProxyBasePath());
    }

    /**
     * Client side logic to rewrite a given URL
     * 
     * @param element
     * @param servletPath
     * @param proxyPath
     */
    public static void rewriteUrl(com.google.gwt.dom.client.Element element, String servletPath, String proxyPath) {
        NodeList<Node> nodes = element.getChildNodes();
        for (int i = 0; i < nodes.getLength(); i++) {
            Node n = nodes.getItem(i);
            if (com.google.gwt.dom.client.Element.is(n)) {
                com.google.gwt.dom.client.Element e = com.google.gwt.dom.client.Element.as(n);
                if (e != null && e.getTagName() != null && e.getTagName().equalsIgnoreCase("a")) {
                    AnchorElement anchor = AnchorElement.as(e);
                    if (anchor.getHref() != null && !anchor.getHref().isEmpty())
                        anchor.removeAttribute("onmousedown");
                }
                for (String att : attributesToManipulate) {
                    String value = e.getAttribute(att);
                    if (value != null && !value.startsWith(servletPath) && value.matches("((http)|/).*")) {
                        String transformed = Rewriter.translateCleanUrl(value, servletPath, proxyPath);
                        if (!transformed.equals(value))
                            e.setAttribute(att, transformed);
                    }
                }
                rewriteUrl(e, servletPath, proxyPath);
            }
        }
    }

    /**
     * If something in the DOM has changed, call the different handlers and replace the standard widgets
     * 
     * @param evt
     */
    public static void onDomChanged(Event evt) {
        if (Element.is(evt.getEventTarget())) {
            Element e = (Element) Element.as(evt.getEventTarget());
            rewriteUrls(e);
            for (DOMChangeHandler h : domChangeHandler)
                h.onDomChanged(evt);
            for (MultiFocusTextBox b : replacements)
                b.refreshDisplay();
        }
    }

    private static List<DOMChangeHandler> domChangeHandler = new ArrayList<DOMChangeHandler>();

    /**
     * Add a dom change handler
     * 
     * @param handler
     */
    public static void addDOMChangeHandler(DOMChangeHandler handler) {
        domChangeHandler.add(handler);
    }

    /**
     * Add a listener for dom change events
     */
    private native void addDomChangeEvents() /*-{
                                             $wnd.document.addEventListener('DOMSubtreeModified', @ch.unifr.pai.twice.widgets.mpproxy.client.ProxyBody::onDomChanged(Lcom/google/gwt/user/client/Event;), false);
                                             }-*/;

    /**
     * @return true if this is the parent frame
     */
    private native boolean isParentFrame() /*-{
                                           return $wnd.location == $wnd.parent.location;
                                           }-*/;

    /**
     * Set up the JS-callable signature as a global JS function.
     * 
     */
    private native void publishInterfaces() /*-{
                                            $wnd.backInHistory = @com.google.gwt.user.client.History::back();
                                            $wnd.forwardInHistory = @com.google.gwt.user.client.History::forward();
                                            $wnd.reloadFrame = @com.google.gwt.user.client.Window.Location::reload();
                                            }-*/;

}