ko-osgi-test/src/main/java/org/netbeans/html/ko/osgi/test/KnockoutEquinoxTCKImpl.java
author Jaroslav Tulach <jtulach@netbeans.org>
Tue, 26 Aug 2014 18:13:30 +0200
changeset 838 bdc3d696dd4a
parent 790 30f20d9c0986
child 886 88d62267a0b5
permissions -rw-r--r--
During the API review process (bug 246133) the reviewers decided that in order to include html4j to NetBeans Platform, we need to stop using org.apidesign namespace and switch to NetBeans one. Repackaging all SPI packages into org.netbeans.html.smthng.spi.
jaroslav@370
     1
/**
jaroslav@370
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jaroslav@370
     3
 *
jaroslav@551
     4
 * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
jaroslav@370
     5
 *
jaroslav@370
     6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
jaroslav@370
     7
 * Other names may be trademarks of their respective owners.
jaroslav@370
     8
 *
jaroslav@370
     9
 * The contents of this file are subject to the terms of either the GNU
jaroslav@370
    10
 * General Public License Version 2 only ("GPL") or the Common
jaroslav@370
    11
 * Development and Distribution License("CDDL") (collectively, the
jaroslav@370
    12
 * "License"). You may not use this file except in compliance with the
jaroslav@370
    13
 * License. You can obtain a copy of the License at
jaroslav@370
    14
 * http://www.netbeans.org/cddl-gplv2.html
jaroslav@370
    15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jaroslav@370
    16
 * specific language governing permissions and limitations under the
jaroslav@370
    17
 * License.  When distributing the software, include this License Header
jaroslav@370
    18
 * Notice in each file and include the License file at
jaroslav@370
    19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
jaroslav@370
    20
 * particular file as subject to the "Classpath" exception as provided
jaroslav@370
    21
 * by Oracle in the GPL Version 2 section of the License file that
jaroslav@370
    22
 * accompanied this code. If applicable, add the following below the
jaroslav@370
    23
 * License Header, with the fields enclosed by brackets [] replaced by
jaroslav@370
    24
 * your own identifying information:
jaroslav@370
    25
 * "Portions Copyrighted [year] [name of copyright owner]"
jaroslav@370
    26
 *
jaroslav@370
    27
 * Contributor(s):
jaroslav@370
    28
 *
jaroslav@370
    29
 * The Original Software is NetBeans. The Initial Developer of the Original
jaroslav@551
    30
 * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
jaroslav@370
    31
 *
jaroslav@370
    32
 * If you wish your version of this file to be governed by only the CDDL
jaroslav@370
    33
 * or only the GPL Version 2, indicate your decision by adding
jaroslav@370
    34
 * "[Contributor] elects to include this software in this distribution
jaroslav@370
    35
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
jaroslav@370
    36
 * single choice of license, a recipient has the option to distribute
jaroslav@370
    37
 * your version of this file under either the CDDL, the GPL Version 2 or
jaroslav@370
    38
 * to extend the choice of license to its licensees as provided above.
jaroslav@370
    39
 * However, if you add GPL Version 2 code and therefore, elected the GPL
jaroslav@370
    40
 * Version 2 license, then the option applies only if the new code is
jaroslav@370
    41
 * made subject to such option by the copyright holder.
jaroslav@370
    42
 */
jaroslav@370
    43
package org.netbeans.html.ko.osgi.test;
jaroslav@370
    44
jaroslav@371
    45
import java.io.BufferedReader;
jaroslav@370
    46
import java.io.IOException;
jaroslav@371
    47
import java.io.InputStreamReader;
jaroslav@444
    48
import java.lang.reflect.Constructor;
jaroslav@371
    49
import java.lang.reflect.Method;
jaroslav@371
    50
import java.net.URI;
jaroslav@371
    51
import java.net.URISyntaxException;
jaroslav@371
    52
import java.net.URL;
jaroslav@371
    53
import java.net.URLConnection;
jaroslav@370
    54
import java.util.Map;
jaroslav@371
    55
import java.util.concurrent.Callable;
jaroslav@574
    56
import java.util.concurrent.Executor;
jaroslav@396
    57
import java.util.concurrent.Executors;
jaroslav@370
    58
import net.java.html.BrwsrCtx;
jaroslav@396
    59
import net.java.html.boot.BrowserBuilder;
jaroslav@371
    60
import net.java.html.js.JavaScriptBody;
jtulach@838
    61
import org.netbeans.html.boot.spi.Fn;
jtulach@838
    62
import org.netbeans.html.context.spi.Contexts;
jtulach@838
    63
import org.netbeans.html.json.spi.Technology;
jtulach@838
    64
import org.netbeans.html.json.spi.Transfer;
jtulach@838
    65
import org.netbeans.html.json.tck.KnockoutTCK;
jaroslav@371
    66
import org.json.JSONException;
jaroslav@371
    67
import org.json.JSONObject;
jaroslav@371
    68
import org.openide.util.lookup.ServiceProvider;
jaroslav@396
    69
import org.osgi.framework.Bundle;
jaroslav@396
    70
import org.osgi.framework.BundleContext;
jaroslav@396
    71
import org.osgi.framework.FrameworkUtil;
jaroslav@370
    72
jaroslav@370
    73
/**
jaroslav@370
    74
 *
jtulach@790
    75
 * @author Jaroslav Tulach
jaroslav@370
    76
 */
jaroslav@371
    77
@ServiceProvider(service = KnockoutTCK.class)
jaroslav@391
    78
public class KnockoutEquinoxTCKImpl extends KnockoutTCK implements Callable<Class[]> {
jaroslav@371
    79
    
jaroslav@371
    80
    private static Fn.Presenter browserContext;
jaroslav@371
    81
jaroslav@396
    82
    public static Class loadOSGiClass(String name, BundleContext ctx) throws Exception {
jaroslav@396
    83
        for (Bundle b : ctx.getBundles()) {
jaroslav@396
    84
            try {
jaroslav@396
    85
                Class<?> osgiClass = b.loadClass(name);
jaroslav@396
    86
                if (osgiClass != null && osgiClass.getClassLoader() != ClassLoader.getSystemClassLoader()) {
jaroslav@396
    87
                    return osgiClass;
jaroslav@396
    88
                }
jaroslav@396
    89
            } catch (ClassNotFoundException cnfe) {
jaroslav@396
    90
                // go on
jaroslav@396
    91
            }
jaroslav@396
    92
        }
jaroslav@396
    93
        throw new IllegalStateException("Cannot load " + name + " from the OSGi container!");
jaroslav@396
    94
    }
jaroslav@396
    95
jaroslav@391
    96
    @Override
jaroslav@391
    97
    public Class[] call() throws Exception {
jaroslav@391
    98
        return testClasses();
jaroslav@371
    99
    }
jaroslav@396
   100
    
jaroslav@396
   101
    public static void start(URI server) throws Exception {
jaroslav@396
   102
        final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(KnockoutEquinoxTCKImpl.class).
jaroslav@396
   103
            loadPage(server.toString()).
jaroslav@396
   104
            invoke("initialized");
jaroslav@396
   105
jaroslav@396
   106
        Executors.newSingleThreadExecutor().submit(new Runnable() {
jaroslav@396
   107
            @Override
jaroslav@396
   108
            public void run() {
jaroslav@396
   109
                try {
jaroslav@396
   110
                    final ClassLoader osgiClassLoader = BrowserBuilder.class.getClassLoader();
jtulach@771
   111
                    bb.classloader(osgiClassLoader);
jaroslav@396
   112
                    bb.showAndWait();
jaroslav@396
   113
                } catch (Throwable t) {
jaroslav@396
   114
                    t.printStackTrace();
jaroslav@396
   115
                }
jaroslav@396
   116
            }
jaroslav@396
   117
        });
jaroslav@396
   118
    }
jaroslav@371
   119
jaroslav@391
   120
    public static void initialized() throws Exception {
jaroslav@398
   121
        Bundle bundle = FrameworkUtil.getBundle(KnockoutEquinoxTCKImpl.class);
jaroslav@398
   122
        if (bundle == null) {
jaroslav@398
   123
            throw new IllegalStateException(
jaroslav@398
   124
                "Should be loaded from a bundle. But was: " + KnockoutEquinoxTCKImpl.class.getClassLoader()
jaroslav@398
   125
            );
jaroslav@398
   126
        }
jaroslav@391
   127
        Class<?> classpathClass = ClassLoader.getSystemClassLoader().loadClass(
jaroslav@391
   128
            "org.netbeans.html.ko.osgi.test.KnockoutEquinoxIT"
jaroslav@391
   129
        );
jaroslav@396
   130
        Method m = classpathClass.getMethod("initialized", Class.class, Object.class);
jaroslav@391
   131
        browserContext = Fn.activePresenter();
jaroslav@396
   132
        m.invoke(null, KnockoutEquinoxTCKImpl.class, browserContext);
jaroslav@371
   133
    }
jaroslav@371
   134
    
jaroslav@371
   135
    @Override
jaroslav@371
   136
    public BrwsrCtx createContext() {
jaroslav@391
   137
        try {
jaroslav@396
   138
            Class<?> fxCls = loadOSGiClass(
jaroslav@444
   139
                "org.netbeans.html.ko4j.FXContext",
jaroslav@396
   140
                FrameworkUtil.getBundle(KnockoutEquinoxTCKImpl.class).getBundleContext()
jaroslav@396
   141
            );
jaroslav@444
   142
            final Constructor<?> cnstr = fxCls.getConstructor(Fn.Presenter.class);
jaroslav@444
   143
            cnstr.setAccessible(true);
jaroslav@444
   144
            Object fx = cnstr.newInstance(browserContext);
jaroslav@391
   145
            Contexts.Builder cb = Contexts.newBuilder().
jaroslav@391
   146
                register(Technology.class, (Technology)fx, 10).
jaroslav@574
   147
                register(Transfer.class, (Transfer)fx, 10).
jaroslav@574
   148
                register(Executor.class, (Executor)browserContext, 10);
jaroslav@371
   149
//        if (fx.areWebSocketsSupported()) {
jaroslav@371
   150
//            cb.register(WSTransfer.class, fx, 10);
jaroslav@371
   151
//        }
jaroslav@391
   152
            return cb.build();
jaroslav@391
   153
        } catch (Exception ex) {
jaroslav@391
   154
            throw new IllegalStateException(ex);
jaroslav@391
   155
        }
jaroslav@371
   156
    }
jaroslav@371
   157
jaroslav@371
   158
    @Override
jaroslav@371
   159
    public Object createJSON(Map<String, Object> values) {
jaroslav@371
   160
        JSONObject json = new JSONObject();
jaroslav@371
   161
        for (Map.Entry<String, Object> entry : values.entrySet()) {
jaroslav@371
   162
            try {
jaroslav@371
   163
                json.put(entry.getKey(), entry.getValue());
jaroslav@371
   164
            } catch (JSONException ex) {
jaroslav@371
   165
                throw new IllegalStateException(ex);
jaroslav@371
   166
            }
jaroslav@371
   167
        }
jaroslav@371
   168
        return json;
jaroslav@371
   169
    }
jaroslav@371
   170
jaroslav@371
   171
    @Override
jaroslav@371
   172
    @JavaScriptBody(args = { "s", "args" }, body = ""
jaroslav@371
   173
        + "var f = new Function(s); "
jaroslav@371
   174
        + "return f.apply(null, args);"
jaroslav@371
   175
    )
jaroslav@371
   176
    public native Object executeScript(String script, Object[] arguments);
jaroslav@371
   177
jaroslav@371
   178
    @JavaScriptBody(args = {  }, body = 
jaroslav@371
   179
          "var h;"
jaroslav@371
   180
        + "if (!!window && !!window.location && !!window.location.href)\n"
jaroslav@371
   181
        + "  h = window.location.href;\n"
jaroslav@371
   182
        + "else "
jaroslav@371
   183
        + "  h = null;"
jaroslav@371
   184
        + "return h;\n"
jaroslav@371
   185
    )
jaroslav@371
   186
    private static native String findBaseURL();
jaroslav@371
   187
    
jaroslav@371
   188
    @Override
jaroslav@371
   189
    public URI prepareURL(String content, String mimeType, String[] parameters) {
jaroslav@371
   190
        try {
jaroslav@371
   191
            final URL baseURL = new URL(findBaseURL());
jaroslav@371
   192
            StringBuilder sb = new StringBuilder();
jaroslav@371
   193
            sb.append("/dynamic?mimeType=").append(mimeType);
jaroslav@371
   194
            for (int i = 0; i < parameters.length; i++) {
jaroslav@371
   195
                sb.append("&param" + i).append("=").append(parameters[i]);
jaroslav@371
   196
            }
jaroslav@371
   197
            String mangle = content.replace("\n", "%0a")
jaroslav@371
   198
                .replace("\"", "\\\"").replace(" ", "%20");
jaroslav@371
   199
            sb.append("&content=").append(mangle);
jaroslav@371
   200
jaroslav@371
   201
            URL query = new URL(baseURL, sb.toString());
jaroslav@371
   202
            URLConnection c = query.openConnection();
jaroslav@371
   203
            BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
jaroslav@371
   204
            URI connectTo = new URI(br.readLine());
jaroslav@371
   205
            return connectTo;
jaroslav@371
   206
        } catch (IOException ex) {
jaroslav@371
   207
            throw new IllegalStateException(ex);
jaroslav@371
   208
        } catch (URISyntaxException ex) {
jaroslav@371
   209
            throw new IllegalStateException(ex);
jaroslav@371
   210
        }
jaroslav@371
   211
    }
jaroslav@371
   212
jaroslav@371
   213
    @Override
jaroslav@371
   214
    public boolean canFailWebSocketTest() {
jtulach@623
   215
        return true;
jaroslav@371
   216
    }
jaroslav@391
   217
jaroslav@370
   218
}