Tests in Equinox initialize OK osgi
authorJaroslav Tulach <jaroslav.tulach@netbeans.org>
Sat, 04 Jan 2014 16:18:56 +0100
branchosgi
changeset 391ab693b8dc2e0
parent 390 186c98dc8550
child 392 4d0a8c9e0d11
Tests in Equinox initialize OK
ko-osgi-test/pom.xml
ko-osgi-test/src/main/java/org/netbeans/html/ko/osgi/test/KnockoutEquinoxTCKImpl.java
ko-osgi-test/src/test/java/org/netbeans/html/ko/osgi/test/KnockoutEquinoxIT.java
ko-osgi-test/src/test/java/org/netbeans/html/ko/osgi/test/KnockoutEquinoxTest.java
     1.1 --- a/ko-osgi-test/pom.xml	Sat Jan 04 08:11:47 2014 +0100
     1.2 +++ b/ko-osgi-test/pom.xml	Sat Jan 04 16:18:56 2014 +0100
     1.3 @@ -6,8 +6,9 @@
     1.4          <artifactId>pom</artifactId>
     1.5          <version>0.7-SNAPSHOT</version>
     1.6      </parent>
     1.7 +    <name>KO Tests in an OSGi Container</name>
     1.8      <artifactId>ko-osgi-test</artifactId>
     1.9 -    <packaging>jar</packaging>
    1.10 +    <packaging>bundle</packaging>
    1.11      <description>Runs the TCK for Knockout in an OSGi Container</description>
    1.12      <properties>
    1.13          <netbeans.compile.on.save>none</netbeans.compile.on.save>
    1.14 @@ -15,6 +16,10 @@
    1.15      <build>
    1.16          <plugins>
    1.17              <plugin>
    1.18 +                <groupId>org.apache.felix</groupId>
    1.19 +                <artifactId>maven-bundle-plugin</artifactId>
    1.20 +            </plugin>
    1.21 +            <plugin>
    1.22                  <groupId>org.apache.maven.plugins</groupId>
    1.23                  <artifactId>maven-compiler-plugin</artifactId>
    1.24                  <version>2.3.2</version>
    1.25 @@ -23,6 +28,23 @@
    1.26                      <target>1.7</target>
    1.27                  </configuration>
    1.28              </plugin>
    1.29 +            <plugin>
    1.30 +                <artifactId>maven-failsafe-plugin</artifactId>
    1.31 +                <version>2.16</version>
    1.32 +                <configuration>
    1.33 +                    <additionalClasspathElements>
    1.34 +                        <additionalClasspathElement>${project.build.directory}/${project.build.finalName}.jar</additionalClasspathElement>
    1.35 +                    </additionalClasspathElements>
    1.36 +                </configuration>
    1.37 +                <executions>
    1.38 +                    <execution>
    1.39 +                        <goals>
    1.40 +                            <goal>integration-test</goal>
    1.41 +                            <goal>verify</goal>
    1.42 +                        </goals>
    1.43 +                    </execution>
    1.44 +                </executions>
    1.45 +            </plugin>
    1.46          </plugins>
    1.47      </build>
    1.48      <dependencies>
    1.49 @@ -51,7 +73,6 @@
    1.50              <groupId>${project.groupId}</groupId>
    1.51              <artifactId>net.java.html.json.tck</artifactId>
    1.52              <version>${project.version}</version>
    1.53 -            <scope>test</scope>
    1.54          </dependency>
    1.55          <dependency>
    1.56              <groupId>org.netbeans.api</groupId>
    1.57 @@ -66,6 +87,11 @@
    1.58          </dependency>
    1.59          <dependency>
    1.60              <groupId>${project.groupId}</groupId>
    1.61 +            <artifactId>ko-fx</artifactId>
    1.62 +            <version>${project.version}</version>
    1.63 +        </dependency>
    1.64 +        <dependency>
    1.65 +            <groupId>${project.groupId}</groupId>
    1.66              <artifactId>net.java.html.boot.fx</artifactId>
    1.67              <version>${project.version}</version>
    1.68              <scope>test</scope>
    1.69 @@ -99,13 +125,6 @@
    1.70              <groupId>org.eclipse</groupId>
    1.71              <artifactId>org.eclipse.osgi</artifactId>
    1.72              <version>3.8.0.v20120529-1548</version>
    1.73 -            <scope>test</scope>
    1.74 -        </dependency>
    1.75 -        <dependency>
    1.76 -            <groupId>${project.groupId}</groupId>
    1.77 -            <artifactId>ko-fx</artifactId>
    1.78 -            <version>${project.version}</version>
    1.79 -            <scope>test</scope>
    1.80          </dependency>
    1.81      </dependencies>
    1.82  </project>
    1.83 \ No newline at end of file
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/ko-osgi-test/src/main/java/org/netbeans/html/ko/osgi/test/KnockoutEquinoxTCKImpl.java	Sat Jan 04 16:18:56 2014 +0100
     2.3 @@ -0,0 +1,174 @@
     2.4 +/**
     2.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     2.6 + *
     2.7 + * Copyright 2013-2013 Oracle and/or its affiliates. All rights reserved.
     2.8 + *
     2.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    2.10 + * Other names may be trademarks of their respective owners.
    2.11 + *
    2.12 + * The contents of this file are subject to the terms of either the GNU
    2.13 + * General Public License Version 2 only ("GPL") or the Common
    2.14 + * Development and Distribution License("CDDL") (collectively, the
    2.15 + * "License"). You may not use this file except in compliance with the
    2.16 + * License. You can obtain a copy of the License at
    2.17 + * http://www.netbeans.org/cddl-gplv2.html
    2.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    2.19 + * specific language governing permissions and limitations under the
    2.20 + * License.  When distributing the software, include this License Header
    2.21 + * Notice in each file and include the License file at
    2.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    2.23 + * particular file as subject to the "Classpath" exception as provided
    2.24 + * by Oracle in the GPL Version 2 section of the License file that
    2.25 + * accompanied this code. If applicable, add the following below the
    2.26 + * License Header, with the fields enclosed by brackets [] replaced by
    2.27 + * your own identifying information:
    2.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    2.29 + *
    2.30 + * Contributor(s):
    2.31 + *
    2.32 + * The Original Software is NetBeans. The Initial Developer of the Original
    2.33 + * Software is Oracle. Portions Copyright 2013-2013 Oracle. All Rights Reserved.
    2.34 + *
    2.35 + * If you wish your version of this file to be governed by only the CDDL
    2.36 + * or only the GPL Version 2, indicate your decision by adding
    2.37 + * "[Contributor] elects to include this software in this distribution
    2.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    2.39 + * single choice of license, a recipient has the option to distribute
    2.40 + * your version of this file under either the CDDL, the GPL Version 2 or
    2.41 + * to extend the choice of license to its licensees as provided above.
    2.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    2.43 + * Version 2 license, then the option applies only if the new code is
    2.44 + * made subject to such option by the copyright holder.
    2.45 + */
    2.46 +package org.netbeans.html.ko.osgi.test;
    2.47 +
    2.48 +import java.io.BufferedReader;
    2.49 +import java.io.IOException;
    2.50 +import java.io.InputStreamReader;
    2.51 +import java.lang.reflect.Method;
    2.52 +import java.net.URI;
    2.53 +import java.net.URISyntaxException;
    2.54 +import java.net.URL;
    2.55 +import java.net.URLConnection;
    2.56 +import java.util.Map;
    2.57 +import java.util.concurrent.Callable;
    2.58 +import java.util.logging.Level;
    2.59 +import java.util.logging.Logger;
    2.60 +import net.java.html.BrwsrCtx;
    2.61 +import net.java.html.js.JavaScriptBody;
    2.62 +import org.apidesign.html.boot.spi.Fn;
    2.63 +import org.apidesign.html.context.spi.Contexts;
    2.64 +import org.apidesign.html.json.spi.Technology;
    2.65 +import org.apidesign.html.json.spi.Transfer;
    2.66 +import org.apidesign.html.json.tck.KnockoutTCK;
    2.67 +import org.json.JSONException;
    2.68 +import org.json.JSONObject;
    2.69 +import org.openide.util.lookup.ServiceProvider;
    2.70 +
    2.71 +/**
    2.72 + *
    2.73 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    2.74 + */
    2.75 +@ServiceProvider(service = KnockoutTCK.class)
    2.76 +public class KnockoutEquinoxTCKImpl extends KnockoutTCK implements Callable<Class[]> {
    2.77 +    
    2.78 +    private static Class<?> browserClass;
    2.79 +    private static Fn.Presenter browserContext;
    2.80 +
    2.81 +    @Override
    2.82 +    public Class[] call() throws Exception {
    2.83 +        return testClasses();
    2.84 +    }
    2.85 +
    2.86 +    public static void initialized() throws Exception {
    2.87 +        Class<?> classpathClass = ClassLoader.getSystemClassLoader().loadClass(
    2.88 +            "org.netbeans.html.ko.osgi.test.KnockoutEquinoxIT"
    2.89 +        );
    2.90 +        Method m = classpathClass.getMethod("initialized", Class.class);
    2.91 +        m.invoke(null, KnockoutEquinoxTCKImpl.class);
    2.92 +        browserContext = Fn.activePresenter();
    2.93 +    }
    2.94 +    
    2.95 +    @Override
    2.96 +    public BrwsrCtx createContext() {
    2.97 +        try {
    2.98 +            Object fx = Class.forName("org.netbeans.html.kofx.FXContext").getConstructor(Fn.Presenter.class).newInstance(browserContext);
    2.99 +            Contexts.Builder cb = Contexts.newBuilder().
   2.100 +                register(Technology.class, (Technology)fx, 10).
   2.101 +                register(Transfer.class, (Transfer)fx, 10);
   2.102 +//        if (fx.areWebSocketsSupported()) {
   2.103 +//            cb.register(WSTransfer.class, fx, 10);
   2.104 +//        }
   2.105 +            return cb.build();
   2.106 +        } catch (Exception ex) {
   2.107 +            throw new IllegalStateException(ex);
   2.108 +        }
   2.109 +    }
   2.110 +
   2.111 +    @Override
   2.112 +    public Object createJSON(Map<String, Object> values) {
   2.113 +        JSONObject json = new JSONObject();
   2.114 +        for (Map.Entry<String, Object> entry : values.entrySet()) {
   2.115 +            try {
   2.116 +                json.put(entry.getKey(), entry.getValue());
   2.117 +            } catch (JSONException ex) {
   2.118 +                throw new IllegalStateException(ex);
   2.119 +            }
   2.120 +        }
   2.121 +        return json;
   2.122 +    }
   2.123 +
   2.124 +    @Override
   2.125 +    @JavaScriptBody(args = { "s", "args" }, body = ""
   2.126 +        + "var f = new Function(s); "
   2.127 +        + "return f.apply(null, args);"
   2.128 +    )
   2.129 +    public native Object executeScript(String script, Object[] arguments);
   2.130 +
   2.131 +    @JavaScriptBody(args = {  }, body = 
   2.132 +          "var h;"
   2.133 +        + "if (!!window && !!window.location && !!window.location.href)\n"
   2.134 +        + "  h = window.location.href;\n"
   2.135 +        + "else "
   2.136 +        + "  h = null;"
   2.137 +        + "return h;\n"
   2.138 +    )
   2.139 +    private static native String findBaseURL();
   2.140 +    
   2.141 +    @Override
   2.142 +    public URI prepareURL(String content, String mimeType, String[] parameters) {
   2.143 +        try {
   2.144 +            final URL baseURL = new URL(findBaseURL());
   2.145 +            StringBuilder sb = new StringBuilder();
   2.146 +            sb.append("/dynamic?mimeType=").append(mimeType);
   2.147 +            for (int i = 0; i < parameters.length; i++) {
   2.148 +                sb.append("&param" + i).append("=").append(parameters[i]);
   2.149 +            }
   2.150 +            String mangle = content.replace("\n", "%0a")
   2.151 +                .replace("\"", "\\\"").replace(" ", "%20");
   2.152 +            sb.append("&content=").append(mangle);
   2.153 +
   2.154 +            URL query = new URL(baseURL, sb.toString());
   2.155 +            URLConnection c = query.openConnection();
   2.156 +            BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
   2.157 +            URI connectTo = new URI(br.readLine());
   2.158 +            return connectTo;
   2.159 +        } catch (IOException ex) {
   2.160 +            throw new IllegalStateException(ex);
   2.161 +        } catch (URISyntaxException ex) {
   2.162 +            throw new IllegalStateException(ex);
   2.163 +        }
   2.164 +    }
   2.165 +
   2.166 +    @Override
   2.167 +    public boolean canFailWebSocketTest() {
   2.168 +        try {
   2.169 +            Class.forName("java.util.function.Function");
   2.170 +            return false;
   2.171 +        } catch (ClassNotFoundException ex) {
   2.172 +            // running on JDK7, FX WebView WebSocket impl does not work
   2.173 +            return true;
   2.174 +        }
   2.175 +    }
   2.176 +
   2.177 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/ko-osgi-test/src/test/java/org/netbeans/html/ko/osgi/test/KnockoutEquinoxIT.java	Sat Jan 04 16:18:56 2014 +0100
     3.3 @@ -0,0 +1,266 @@
     3.4 +/**
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2013-2013 Oracle and/or its affiliates. All rights reserved.
     3.8 + *
     3.9 + * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    3.10 + * Other names may be trademarks of their respective owners.
    3.11 + *
    3.12 + * The contents of this file are subject to the terms of either the GNU
    3.13 + * General Public License Version 2 only ("GPL") or the Common
    3.14 + * Development and Distribution License("CDDL") (collectively, the
    3.15 + * "License"). You may not use this file except in compliance with the
    3.16 + * License. You can obtain a copy of the License at
    3.17 + * http://www.netbeans.org/cddl-gplv2.html
    3.18 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    3.19 + * specific language governing permissions and limitations under the
    3.20 + * License.  When distributing the software, include this License Header
    3.21 + * Notice in each file and include the License file at
    3.22 + * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    3.23 + * particular file as subject to the "Classpath" exception as provided
    3.24 + * by Oracle in the GPL Version 2 section of the License file that
    3.25 + * accompanied this code. If applicable, add the following below the
    3.26 + * License Header, with the fields enclosed by brackets [] replaced by
    3.27 + * your own identifying information:
    3.28 + * "Portions Copyrighted [year] [name of copyright owner]"
    3.29 + *
    3.30 + * Contributor(s):
    3.31 + *
    3.32 + * The Original Software is NetBeans. The Initial Developer of the Original
    3.33 + * Software is Oracle. Portions Copyright 2013-2013 Oracle. All Rights Reserved.
    3.34 + *
    3.35 + * If you wish your version of this file to be governed by only the CDDL
    3.36 + * or only the GPL Version 2, indicate your decision by adding
    3.37 + * "[Contributor] elects to include this software in this distribution
    3.38 + * under the [CDDL or GPL Version 2] license." If you do not indicate a
    3.39 + * single choice of license, a recipient has the option to distribute
    3.40 + * your version of this file under either the CDDL, the GPL Version 2 or
    3.41 + * to extend the choice of license to its licensees as provided above.
    3.42 + * However, if you add GPL Version 2 code and therefore, elected the GPL
    3.43 + * Version 2 license, then the option applies only if the new code is
    3.44 + * made subject to such option by the copyright holder.
    3.45 + */
    3.46 +package org.netbeans.html.ko.osgi.test;
    3.47 +
    3.48 +import java.io.BufferedReader;
    3.49 +import java.io.File;
    3.50 +import java.io.IOException;
    3.51 +import java.io.InputStreamReader;
    3.52 +import java.lang.annotation.Annotation;
    3.53 +import java.lang.reflect.Method;
    3.54 +import java.net.URI;
    3.55 +import java.net.URISyntaxException;
    3.56 +import java.net.URL;
    3.57 +import java.net.URLConnection;
    3.58 +import java.util.ArrayList;
    3.59 +import java.util.HashMap;
    3.60 +import java.util.List;
    3.61 +import java.util.Map;
    3.62 +import java.util.ServiceLoader;
    3.63 +import java.util.concurrent.Callable;
    3.64 +import java.util.concurrent.Executors;
    3.65 +import java.util.jar.JarFile;
    3.66 +import java.util.logging.Level;
    3.67 +import java.util.logging.Logger;
    3.68 +import net.java.html.BrwsrCtx;
    3.69 +import net.java.html.boot.BrowserBuilder;
    3.70 +import net.java.html.js.JavaScriptBody;
    3.71 +import org.apidesign.html.boot.spi.Fn;
    3.72 +import org.apidesign.html.context.spi.Contexts;
    3.73 +import org.apidesign.html.json.spi.Technology;
    3.74 +import org.apidesign.html.json.spi.Transfer;
    3.75 +import org.apidesign.html.json.tck.KOTest;
    3.76 +import org.apidesign.html.json.tck.KnockoutTCK;
    3.77 +import org.json.JSONException;
    3.78 +import org.json.JSONObject;
    3.79 +import org.netbeans.html.boot.impl.FnContext;
    3.80 +import org.netbeans.html.kofx.FXContext;
    3.81 +import org.openide.util.lookup.ServiceProvider;
    3.82 +import org.osgi.framework.Bundle;
    3.83 +import org.osgi.framework.BundleException;
    3.84 +import org.osgi.framework.Constants;
    3.85 +import org.osgi.framework.launch.Framework;
    3.86 +import org.osgi.framework.launch.FrameworkFactory;
    3.87 +import static org.testng.Assert.assertNotNull;
    3.88 +import static org.testng.Assert.fail;
    3.89 +import static org.testng.Assert.fail;
    3.90 +import org.testng.annotations.AfterClass;
    3.91 +import org.testng.annotations.Factory;
    3.92 +
    3.93 +/**
    3.94 + *
    3.95 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    3.96 + */
    3.97 +public class KnockoutEquinoxIT {
    3.98 +    private static final Logger LOG = Logger.getLogger(KnockoutEquinoxIT.class.getName());
    3.99 +    private static Framework framework;
   3.100 +    private static File dir;
   3.101 +    static Framework framework() throws Exception {
   3.102 +        if (framework != null) {
   3.103 +            return framework;
   3.104 +        }
   3.105 +        for (FrameworkFactory ff : ServiceLoader.load(FrameworkFactory.class)) {
   3.106 +            
   3.107 +            String basedir = System.getProperty("basedir");
   3.108 +            assertNotNull("basedir preperty provided", basedir);
   3.109 +            File target = new File(basedir, "target");
   3.110 +            dir = new File(target, "osgi");
   3.111 +            dir.mkdirs();
   3.112 +            
   3.113 +            Map<String,String> config = new HashMap<>();
   3.114 +            config.put(Constants.FRAMEWORK_STORAGE, dir.getPath());
   3.115 +            config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "true");
   3.116 +            config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "sun.misc,"
   3.117 +                + "javafx.application,"
   3.118 +                + "javafx.beans.property,"
   3.119 +                + "javafx.beans.value,"
   3.120 +                + "javafx.collections,"
   3.121 +                + "javafx.concurrent,"
   3.122 +                + "javafx.event,"
   3.123 +                + "javafx.geometry,"
   3.124 +                + "javafx.scene,"
   3.125 +                + "javafx.scene.control,"
   3.126 +                + "javafx.scene.layout,"
   3.127 +                + "javafx.scene.text,"
   3.128 +                + "javafx.scene.web,"
   3.129 +                + "javafx.stage,"
   3.130 +                + "javafx.util,"
   3.131 +                + "netscape.javascript"
   3.132 +            );
   3.133 +            framework = ff.newFramework(config);
   3.134 +            framework.init();
   3.135 +            loadClassPathBundles(framework);
   3.136 +            framework.start();
   3.137 +            for (Bundle b : framework.getBundleContext().getBundles()) {
   3.138 +                try {
   3.139 +                    b.start();
   3.140 +                    LOG.log(Level.INFO, "Started {0}", b.getSymbolicName());
   3.141 +                } catch (BundleException ex) {
   3.142 +                    LOG.log(Level.WARNING, "Cannot start bundle " + b.getSymbolicName(), ex);
   3.143 +                }
   3.144 +            }
   3.145 +            return framework;
   3.146 +        }
   3.147 +        fail("No OSGi framework in the path");
   3.148 +        return null;
   3.149 +    }
   3.150 +    
   3.151 +    @AfterClass public static void cleanUp() throws Exception {
   3.152 +        if (framework != null) framework.stop();
   3.153 +        clearUpDir(dir);
   3.154 +    }
   3.155 +    private static void clearUpDir(File dir) {
   3.156 +        if (dir.isDirectory()) {
   3.157 +            for (File f : dir.listFiles()) {
   3.158 +                clearUpDir(f);
   3.159 +            }
   3.160 +        }
   3.161 +        dir.delete();
   3.162 +    }
   3.163 +    
   3.164 +    
   3.165 +
   3.166 +    private static void loadClassPathBundles(Framework f) throws IOException, BundleException {
   3.167 +        for (String jar : System.getProperty("java.class.path").split(File.pathSeparator)) {
   3.168 +            File file = new File(jar);
   3.169 +            if (!file.isFile()) {
   3.170 +                LOG.info("Not loading " + file);
   3.171 +                continue;
   3.172 +            }
   3.173 +            JarFile jf = new JarFile(file);
   3.174 +            final String name = jf.getManifest().getMainAttributes().getValue("Bundle-SymbolicName");
   3.175 +            jf.close();
   3.176 +            if (name != null) {
   3.177 +                if (name.contains("org.eclipse.osgi")) {
   3.178 +                    continue;
   3.179 +                }
   3.180 +                if (name.contains("testng")) {
   3.181 +                    continue;
   3.182 +                }
   3.183 +                final String path = "reference:" + file.toURI().toString();
   3.184 +                Bundle b = f.getBundleContext().installBundle(path);
   3.185 +            }
   3.186 +        }
   3.187 +    }
   3.188 +    
   3.189 +    private static Class<?> loadAClass(Class<?> c) throws Exception {
   3.190 +        for (Bundle b : framework().getBundleContext().getBundles()) {
   3.191 +            try {
   3.192 +                Class<?> osgiClass = b.loadClass(c.getName());
   3.193 +                if (
   3.194 +                    osgiClass != null && 
   3.195 +                    osgiClass.getClassLoader() != ClassLoader.getSystemClassLoader()
   3.196 +                ) {
   3.197 +                    return osgiClass;
   3.198 +                }
   3.199 +            } catch (ClassNotFoundException cnfe) {
   3.200 +                // go on
   3.201 +            }
   3.202 +        }
   3.203 +        fail("Cannot load " + c + " from the OSGi container!");
   3.204 +        return null;
   3.205 +    }
   3.206 +    
   3.207 +    private static Class<?> browserClass;
   3.208 +    private static Fn.Presenter browserContext;
   3.209 +    
   3.210 +    @Factory public static Object[] compatibilityTests() throws Exception {
   3.211 +        Class<?> tck = loadAClass(KnockoutTCK.class);
   3.212 +        Class<?> peer = loadAClass(KnockoutEquinoxTCKImpl.class);
   3.213 +        // initialize the TCK
   3.214 +        Callable<Class[]> inst = (Callable<Class[]>) peer.newInstance();
   3.215 +        
   3.216 +        Class[] arr = inst.call();
   3.217 +        for (int i = 0; i < arr.length; i++) {
   3.218 +            if (arr[i].getClassLoader() == ClassLoader.getSystemClassLoader()) {
   3.219 +                fail("Should be an OSGi class: " + arr[i]);
   3.220 +            }
   3.221 +        }
   3.222 +        
   3.223 +        URI uri = DynamicHTTP.initServer();
   3.224 +
   3.225 +        
   3.226 +        final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(peer).
   3.227 +            loadPage(uri.toString()).
   3.228 +            invoke("initialized");
   3.229 +        
   3.230 +        Executors.newSingleThreadExecutor().submit(new Runnable() {
   3.231 +            @Override
   3.232 +            public void run() {
   3.233 +                bb.showAndWait();
   3.234 +            }
   3.235 +        });
   3.236 +        
   3.237 +        ClassLoader l = getClassLoader();
   3.238 +        List<Object> res = new ArrayList<Object>();
   3.239 +        for (int i = 0; i < arr.length; i++) {
   3.240 +            Class<?> c = Class.forName(arr[i].getName(), true, l);
   3.241 +            seekKOTests(c, res);
   3.242 +        }
   3.243 +        return res.toArray();
   3.244 +    }
   3.245 +
   3.246 +    private static void seekKOTests(Class<?> c, List<Object> res) throws SecurityException, ClassNotFoundException {
   3.247 +        Class<? extends Annotation> koTest =
   3.248 +            c.getClassLoader().loadClass(KOTest.class.getName()).
   3.249 +            asSubclass(Annotation.class);
   3.250 +        for (Method m : c.getMethods()) {
   3.251 +            if (m.getAnnotation(koTest) != null) {
   3.252 +                res.add(new KOFx(browserContext, m));
   3.253 +            }
   3.254 +        }
   3.255 +    }
   3.256 +
   3.257 +    static synchronized ClassLoader getClassLoader() throws InterruptedException {
   3.258 +        while (browserClass == null) {
   3.259 +            KnockoutEquinoxIT.class.wait();
   3.260 +        }
   3.261 +        return browserClass.getClassLoader();
   3.262 +    }
   3.263 +    
   3.264 +    public static synchronized void initialized(Class<?> browserCls) throws Exception {
   3.265 +        browserClass = browserCls;
   3.266 +        browserContext = FnContext.currentPresenter();
   3.267 +        KnockoutEquinoxIT.class.notifyAll();
   3.268 +    }
   3.269 +}
     4.1 --- a/ko-osgi-test/src/test/java/org/netbeans/html/ko/osgi/test/KnockoutEquinoxTest.java	Sat Jan 04 08:11:47 2014 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,347 +0,0 @@
     4.4 -/**
     4.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 - *
     4.7 - * Copyright 2013-2013 Oracle and/or its affiliates. All rights reserved.
     4.8 - *
     4.9 - * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    4.10 - * Other names may be trademarks of their respective owners.
    4.11 - *
    4.12 - * The contents of this file are subject to the terms of either the GNU
    4.13 - * General Public License Version 2 only ("GPL") or the Common
    4.14 - * Development and Distribution License("CDDL") (collectively, the
    4.15 - * "License"). You may not use this file except in compliance with the
    4.16 - * License. You can obtain a copy of the License at
    4.17 - * http://www.netbeans.org/cddl-gplv2.html
    4.18 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    4.19 - * specific language governing permissions and limitations under the
    4.20 - * License.  When distributing the software, include this License Header
    4.21 - * Notice in each file and include the License file at
    4.22 - * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    4.23 - * particular file as subject to the "Classpath" exception as provided
    4.24 - * by Oracle in the GPL Version 2 section of the License file that
    4.25 - * accompanied this code. If applicable, add the following below the
    4.26 - * License Header, with the fields enclosed by brackets [] replaced by
    4.27 - * your own identifying information:
    4.28 - * "Portions Copyrighted [year] [name of copyright owner]"
    4.29 - *
    4.30 - * Contributor(s):
    4.31 - *
    4.32 - * The Original Software is NetBeans. The Initial Developer of the Original
    4.33 - * Software is Oracle. Portions Copyright 2013-2013 Oracle. All Rights Reserved.
    4.34 - *
    4.35 - * If you wish your version of this file to be governed by only the CDDL
    4.36 - * or only the GPL Version 2, indicate your decision by adding
    4.37 - * "[Contributor] elects to include this software in this distribution
    4.38 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
    4.39 - * single choice of license, a recipient has the option to distribute
    4.40 - * your version of this file under either the CDDL, the GPL Version 2 or
    4.41 - * to extend the choice of license to its licensees as provided above.
    4.42 - * However, if you add GPL Version 2 code and therefore, elected the GPL
    4.43 - * Version 2 license, then the option applies only if the new code is
    4.44 - * made subject to such option by the copyright holder.
    4.45 - */
    4.46 -package org.netbeans.html.ko.osgi.test;
    4.47 -
    4.48 -import java.io.BufferedReader;
    4.49 -import java.io.File;
    4.50 -import java.io.IOException;
    4.51 -import java.io.InputStreamReader;
    4.52 -import java.lang.annotation.Annotation;
    4.53 -import java.lang.reflect.Method;
    4.54 -import java.net.URI;
    4.55 -import java.net.URISyntaxException;
    4.56 -import java.net.URL;
    4.57 -import java.net.URLConnection;
    4.58 -import java.util.ArrayList;
    4.59 -import java.util.HashMap;
    4.60 -import java.util.List;
    4.61 -import java.util.Map;
    4.62 -import java.util.ServiceLoader;
    4.63 -import java.util.concurrent.Callable;
    4.64 -import java.util.concurrent.Executors;
    4.65 -import java.util.jar.JarFile;
    4.66 -import java.util.logging.Level;
    4.67 -import java.util.logging.Logger;
    4.68 -import net.java.html.BrwsrCtx;
    4.69 -import net.java.html.boot.BrowserBuilder;
    4.70 -import net.java.html.js.JavaScriptBody;
    4.71 -import org.apidesign.html.boot.spi.Fn;
    4.72 -import org.apidesign.html.context.spi.Contexts;
    4.73 -import org.apidesign.html.json.spi.Technology;
    4.74 -import org.apidesign.html.json.spi.Transfer;
    4.75 -import org.apidesign.html.json.tck.KOTest;
    4.76 -import org.apidesign.html.json.tck.KnockoutTCK;
    4.77 -import org.json.JSONException;
    4.78 -import org.json.JSONObject;
    4.79 -import org.netbeans.html.boot.impl.FnContext;
    4.80 -import org.netbeans.html.kofx.FXContext;
    4.81 -import org.openide.util.lookup.ServiceProvider;
    4.82 -import org.osgi.framework.Bundle;
    4.83 -import org.osgi.framework.BundleException;
    4.84 -import org.osgi.framework.Constants;
    4.85 -import org.osgi.framework.launch.Framework;
    4.86 -import org.osgi.framework.launch.FrameworkFactory;
    4.87 -import static org.testng.Assert.fail;
    4.88 -import org.testng.annotations.AfterClass;
    4.89 -import org.testng.annotations.Factory;
    4.90 -
    4.91 -/**
    4.92 - *
    4.93 - * @author Jaroslav Tulach <jtulach@netbeans.org>
    4.94 - */
    4.95 -@ServiceProvider(service = KnockoutTCK.class)
    4.96 -public class KnockoutEquinoxTest extends KnockoutTCK {
    4.97 -    private static final Logger LOG = Logger.getLogger(KnockoutEquinoxTest.class.getName());
    4.98 -    private static Framework framework;
    4.99 -    private static File dir;
   4.100 -    static Framework framework() throws Exception {
   4.101 -        if (framework != null) {
   4.102 -            return framework;
   4.103 -        }
   4.104 -        for (FrameworkFactory ff : ServiceLoader.load(FrameworkFactory.class)) {
   4.105 -            Map<String,String> config = new HashMap<>();
   4.106 -            dir = File.createTempFile("osgi", "tmp");
   4.107 -            dir.delete();
   4.108 -            dir.mkdirs();
   4.109 -            config.put(Constants.FRAMEWORK_STORAGE, dir.getPath());
   4.110 -            config.put(Constants.FRAMEWORK_STORAGE_CLEAN, "true");
   4.111 -            config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "sun.misc,"
   4.112 -                + "javafx.application,"
   4.113 -                + "javafx.beans.property,"
   4.114 -                + "javafx.beans.value,"
   4.115 -                + "javafx.collections,"
   4.116 -                + "javafx.concurrent,"
   4.117 -                + "javafx.event,"
   4.118 -                + "javafx.geometry,"
   4.119 -                + "javafx.scene,"
   4.120 -                + "javafx.scene.control,"
   4.121 -                + "javafx.scene.layout,"
   4.122 -                + "javafx.scene.text,"
   4.123 -                + "javafx.scene.web,"
   4.124 -                + "javafx.stage,"
   4.125 -                + "javafx.util,"
   4.126 -                + "netscape.javascript"
   4.127 -            );
   4.128 -            framework = ff.newFramework(config);
   4.129 -            framework.init();
   4.130 -            loadClassPathBundles(framework);
   4.131 -            framework.start();
   4.132 -            for (Bundle b : framework.getBundleContext().getBundles()) {
   4.133 -                try {
   4.134 -                    b.start();
   4.135 -                    LOG.log(Level.INFO, "Started {0}", b.getSymbolicName());
   4.136 -                } catch (BundleException ex) {
   4.137 -                    LOG.log(Level.WARNING, "Cannot start bundle " + b.getSymbolicName(), ex);
   4.138 -                }
   4.139 -            }
   4.140 -            return framework;
   4.141 -        }
   4.142 -        fail("No OSGi framework in the path");
   4.143 -        return null;
   4.144 -    }
   4.145 -    
   4.146 -    @AfterClass public static void cleanUp() throws Exception {
   4.147 -        if (framework != null) framework.stop();
   4.148 -        clearUpDir(dir);
   4.149 -    }
   4.150 -    private static void clearUpDir(File dir) {
   4.151 -        if (dir.isDirectory()) {
   4.152 -            for (File f : dir.listFiles()) {
   4.153 -                clearUpDir(f);
   4.154 -            }
   4.155 -        }
   4.156 -        dir.delete();
   4.157 -    }
   4.158 -    
   4.159 -    
   4.160 -
   4.161 -    private static void loadClassPathBundles(Framework f) throws IOException, BundleException {
   4.162 -        for (String jar : System.getProperty("java.class.path").split(File.pathSeparator)) {
   4.163 -            File file = new File(jar);
   4.164 -            if (!file.isFile()) {
   4.165 -                LOG.info("Not loading " + file);
   4.166 -                continue;
   4.167 -            }
   4.168 -            JarFile jf = new JarFile(file);
   4.169 -            final String name = jf.getManifest().getMainAttributes().getValue("Bundle-SymbolicName");
   4.170 -            jf.close();
   4.171 -            if (name != null) {
   4.172 -                if (name.contains("org.eclipse.osgi")) {
   4.173 -                    continue;
   4.174 -                }
   4.175 -                if (name.contains("testng")) {
   4.176 -                    continue;
   4.177 -                }
   4.178 -                final String path = "reference:" + file.toURI().toString();
   4.179 -                Bundle b = f.getBundleContext().installBundle(path);
   4.180 -            }
   4.181 -        }
   4.182 -    }
   4.183 -    
   4.184 -    private static Class<?> loadAClass(Class<?> c) throws Exception {
   4.185 -        for (Bundle b : framework().getBundleContext().getBundles()) {
   4.186 -            try {
   4.187 -                Class<?> osgiClass = b.loadClass(c.getName());
   4.188 -                if (
   4.189 -                    osgiClass != null && 
   4.190 -                    osgiClass.getClassLoader() != ClassLoader.getSystemClassLoader()
   4.191 -                ) {
   4.192 -                    return osgiClass;
   4.193 -                }
   4.194 -            } catch (ClassNotFoundException cnfe) {
   4.195 -                // go on
   4.196 -            }
   4.197 -        }
   4.198 -        fail("Cannot load " + c + " from the OSGi container!");
   4.199 -        return null;
   4.200 -    }
   4.201 -    
   4.202 -    private static Class<?> browserClass;
   4.203 -    private static Fn.Presenter browserContext;
   4.204 -    
   4.205 -    @Factory public static Object[] compatibilityTests() throws Exception {
   4.206 -        Class<?> tck = loadAClass(KnockoutTCK.class);
   4.207 -        Class<?> peer = loadAClass(KnockoutEquinoxTest.class);
   4.208 -        // initialize the TCK
   4.209 -        Callable<Class[]> inst = (Callable<Class[]>) peer.newInstance();
   4.210 -        
   4.211 -        Class[] arr = inst.call();
   4.212 -        for (int i = 0; i < arr.length; i++) {
   4.213 -            if (arr[i].getClassLoader() == ClassLoader.getSystemClassLoader()) {
   4.214 -                fail("Should be an OSGi class: " + arr[i]);
   4.215 -            }
   4.216 -        }
   4.217 -        
   4.218 -        URI uri = DynamicHTTP.initServer();
   4.219 -
   4.220 -        
   4.221 -        final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(peer).
   4.222 -            loadPage(uri.toString()).
   4.223 -            invoke("initialized");
   4.224 -        
   4.225 -        Executors.newSingleThreadExecutor().submit(new Runnable() {
   4.226 -            @Override
   4.227 -            public void run() {
   4.228 -                bb.showAndWait();
   4.229 -            }
   4.230 -        });
   4.231 -        
   4.232 -        ClassLoader l = getClassLoader();
   4.233 -        List<Object> res = new ArrayList<Object>();
   4.234 -        for (int i = 0; i < arr.length; i++) {
   4.235 -            Class<?> c = Class.forName(arr[i].getName(), true, l);
   4.236 -            seekKOTests(c, res);
   4.237 -        }
   4.238 -        return res.toArray();
   4.239 -    }
   4.240 -
   4.241 -    private static void seekKOTests(Class<?> c, List<Object> res) throws SecurityException, ClassNotFoundException {
   4.242 -        Class<? extends Annotation> koTest =
   4.243 -            c.getClassLoader().loadClass(KOTest.class.getName()).
   4.244 -            asSubclass(Annotation.class);
   4.245 -        for (Method m : c.getMethods()) {
   4.246 -            if (m.getAnnotation(koTest) != null) {
   4.247 -                res.add(new KOFx(browserContext, m));
   4.248 -            }
   4.249 -        }
   4.250 -    }
   4.251 -
   4.252 -    static synchronized ClassLoader getClassLoader() throws InterruptedException {
   4.253 -        while (browserClass == null) {
   4.254 -            KnockoutEquinoxTest.class.wait();
   4.255 -        }
   4.256 -        return browserClass.getClassLoader();
   4.257 -    }
   4.258 -    
   4.259 -    public static synchronized void initialized(Class<?> browserCls) throws Exception {
   4.260 -        browserClass = browserCls;
   4.261 -        browserContext = FnContext.currentPresenter();
   4.262 -        KnockoutEquinoxTest.class.notifyAll();
   4.263 -    }
   4.264 -    
   4.265 -    public static void initialized() throws Exception {
   4.266 -        Class<?> classpathClass = ClassLoader.getSystemClassLoader().loadClass(KnockoutEquinoxTest.class.getName());
   4.267 -        Method m = classpathClass.getMethod("initialized", Class.class);
   4.268 -        m.invoke(null, KnockoutEquinoxTest.class);
   4.269 -        browserContext = FnContext.currentPresenter();
   4.270 -    }
   4.271 -
   4.272 -    @Override
   4.273 -    public BrwsrCtx createContext() {
   4.274 -        FXContext fx = new FXContext(browserContext);
   4.275 -        Contexts.Builder cb = Contexts.newBuilder().
   4.276 -            register(Technology.class, fx, 10).
   4.277 -            register(Transfer.class, fx, 10);
   4.278 -//        if (fx.areWebSocketsSupported()) {
   4.279 -//            cb.register(WSTransfer.class, fx, 10);
   4.280 -//        }
   4.281 -        return cb.build();
   4.282 -    }
   4.283 -
   4.284 -    @Override
   4.285 -    public Object createJSON(Map<String, Object> values) {
   4.286 -        JSONObject json = new JSONObject();
   4.287 -        for (Map.Entry<String, Object> entry : values.entrySet()) {
   4.288 -            try {
   4.289 -                json.put(entry.getKey(), entry.getValue());
   4.290 -            } catch (JSONException ex) {
   4.291 -                throw new IllegalStateException(ex);
   4.292 -            }
   4.293 -        }
   4.294 -        return json;
   4.295 -    }
   4.296 -
   4.297 -    @Override
   4.298 -    @JavaScriptBody(args = { "s", "args" }, body = ""
   4.299 -        + "var f = new Function(s); "
   4.300 -        + "return f.apply(null, args);"
   4.301 -    )
   4.302 -    public native Object executeScript(String script, Object[] arguments);
   4.303 -
   4.304 -    @JavaScriptBody(args = {  }, body = 
   4.305 -          "var h;"
   4.306 -        + "if (!!window && !!window.location && !!window.location.href)\n"
   4.307 -        + "  h = window.location.href;\n"
   4.308 -        + "else "
   4.309 -        + "  h = null;"
   4.310 -        + "return h;\n"
   4.311 -    )
   4.312 -    private static native String findBaseURL();
   4.313 -    
   4.314 -    @Override
   4.315 -    public URI prepareURL(String content, String mimeType, String[] parameters) {
   4.316 -        try {
   4.317 -            final URL baseURL = new URL(findBaseURL());
   4.318 -            StringBuilder sb = new StringBuilder();
   4.319 -            sb.append("/dynamic?mimeType=").append(mimeType);
   4.320 -            for (int i = 0; i < parameters.length; i++) {
   4.321 -                sb.append("&param" + i).append("=").append(parameters[i]);
   4.322 -            }
   4.323 -            String mangle = content.replace("\n", "%0a")
   4.324 -                .replace("\"", "\\\"").replace(" ", "%20");
   4.325 -            sb.append("&content=").append(mangle);
   4.326 -
   4.327 -            URL query = new URL(baseURL, sb.toString());
   4.328 -            URLConnection c = query.openConnection();
   4.329 -            BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
   4.330 -            URI connectTo = new URI(br.readLine());
   4.331 -            return connectTo;
   4.332 -        } catch (IOException ex) {
   4.333 -            throw new IllegalStateException(ex);
   4.334 -        } catch (URISyntaxException ex) {
   4.335 -            throw new IllegalStateException(ex);
   4.336 -        }
   4.337 -    }
   4.338 -
   4.339 -    @Override
   4.340 -    public boolean canFailWebSocketTest() {
   4.341 -        try {
   4.342 -            Class.forName("java.util.function.Function");
   4.343 -            return false;
   4.344 -        } catch (ClassNotFoundException ex) {
   4.345 -            // running on JDK7, FX WebView WebSocket impl does not work
   4.346 -            return true;
   4.347 -        }
   4.348 -    }
   4.349 -    
   4.350 -}