# HG changeset patch # User Jaroslav Tulach # Date 1420978832 -3600 # Node ID 97cb2c5aa4fcbe782dcfa2251d2dbca64222ba19 # Parent 0d2acba8bcfd26499af6b6ac2c3c9bdaef469c1d# Parent 223aedca178da7d67e4582b0a2793c06dee2fa49 Merging recent post 0.13 fixes into trunk diff -r 0d2acba8bcfd -r 97cb2c5aa4fc javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/JSONTest.java --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/JSONTest.java Sat Jan 10 19:38:00 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,393 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.bck2brwsr.htmlpage; - -import java.util.Iterator; -import org.apidesign.bck2brwsr.core.JavaScriptBody; -import org.apidesign.bck2brwsr.htmlpage.api.OnReceive; -import org.apidesign.bck2brwsr.htmlpage.api.Page; -import org.apidesign.bck2brwsr.htmlpage.api.Property; -import org.apidesign.bck2brwsr.vmtest.BrwsrTest; -import org.apidesign.bck2brwsr.vmtest.Http; -import org.apidesign.bck2brwsr.vmtest.VMTest; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; -import org.testng.annotations.Test; -import static org.testng.Assert.*; -import org.testng.annotations.Factory; - -/** Need to verify that models produce reasonable JSON objects. - * - * @author Jaroslav Tulach - */ -@Page(xhtml = "Empty.html", className = "JSONik", properties = { - @Property(name = "fetched", type = PersonImpl.class), - @Property(name = "fetchedCount", type = int.class), - @Property(name = "fetchedSex", type = Sex.class, array = true) -}) -public class JSONTest { - private JSONik js; - private Integer orig; - - @Test public void personToString() throws JSONException { - Person p = new Person(); - p.setSex(Sex.MALE); - p.setFirstName("Jarda"); - p.setLastName("Tulach"); - - JSONTokener t = new JSONTokener(p.toString()); - JSONObject o; - try { - o = new JSONObject(t); - } catch (JSONException ex) { - throw new AssertionError("Can't parse " + p.toString(), ex); - } - - Iterator it = o.sortedKeys(); - assertEquals(it.next(), "firstName"); - assertEquals(it.next(), "lastName"); - assertEquals(it.next(), "sex"); - - assertEquals(o.getString("firstName"), "Jarda"); - assertEquals(o.getString("lastName"), "Tulach"); - assertEquals(o.getString("sex"), "MALE"); - } - - @BrwsrTest public void toJSONInABrowser() throws Throwable { - Person p = new Person(); - p.setSex(Sex.MALE); - p.setFirstName("Jarda"); - p.setLastName("Tulach"); - - Object json; - try { - json = parseJSON(p.toString()); - } catch (Throwable ex) { - throw new IllegalStateException("Can't parse " + p).initCause(ex); - } - - Person p2 = new Person(json); - - assert p2.getFirstName().equals(p.getFirstName()) : - "Should be the same: " + p.getFirstName() + " != " + p2.getFirstName(); - } - - @Test public void personWithWildCharactersAndNulls() throws JSONException { - Person p = new Person(); - p.setFirstName("'\"\n"); - p.setLastName("\t\r\u0002"); - - JSONTokener t = new JSONTokener(p.toString()); - JSONObject o; - try { - o = new JSONObject(t); - } catch (JSONException ex) { - throw new AssertionError("Can't parse " + p.toString(), ex); - } - - Iterator it = o.sortedKeys(); - assertEquals(it.next(), "firstName"); - assertEquals(it.next(), "lastName"); - assertEquals(it.next(), "sex"); - - assertEquals(o.getString("firstName"), p.getFirstName()); - assertEquals(o.getString("lastName"), p.getLastName()); - assertEquals(o.get("sex"), JSONObject.NULL); - } - - @Test public void personsInArray() throws JSONException { - Person p1 = new Person(); - p1.setFirstName("One"); - - Person p2 = new Person(); - p2.setFirstName("Two"); - - People arr = new People(); - arr.getInfo().add(p1); - arr.getInfo().add(p2); - arr.getNicknames().add("Prvn\u00ed k\u016f\u0148"); - final String n2 = "Druh\u00fd hlem\u00fd\u017e\u010f, star\u0161\u00ed"; - arr.getNicknames().add(n2); - arr.getAge().add(33); - arr.getAge().add(73); - - - final String json = arr.toString(); - - JSONTokener t = new JSONTokener(json); - JSONObject o; - try { - o = new JSONObject(t); - } catch (JSONException ex) { - throw new AssertionError("Can't parse " + json, ex); - } - - assertEquals(o.getJSONArray("info").getJSONObject(0).getString("firstName"), "One"); - assertEquals(o.getJSONArray("nicknames").getString(1), n2); - assertEquals(o.getJSONArray("age").getInt(1), 73); - } - - - @OnReceive(url="/{url}") - static void fetch(Person p, JSONik model) { - model.setFetched(p); - } - - @OnReceive(url="/{url}") - static void fetchArray(Person[] p, JSONik model) { - model.setFetchedCount(p.length); - model.setFetched(p[0]); - } - - @OnReceive(url="/{url}") - static void fetchPeople(People p, JSONik model) { - model.setFetchedCount(p.getInfo().size()); - model.setFetched(p.getInfo().get(0)); - } - - @OnReceive(url="/{url}") - static void fetchPeopleAge(People p, JSONik model) { - int sum = 0; - for (int a : p.getAge()) { - sum += a; - } - model.setFetchedCount(sum); - } - - @Http(@Http.Resource( - content = "{'firstName': 'Sitar', 'sex': 'MALE'}", - path="/person33.json", - mimeType = "application/json" - )) - @BrwsrTest public void loadAndParseJSON() throws InterruptedException { - try { throw new Exception(); } catch (Exception ex) { - } - if (js == null) { - js = new JSONik(); - js.applyBindings(); - - js.fetch("person33.json"); - } - - Person p = js.getFetched(); - if (p == null) { - throw new InterruptedException(); - } - - assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName(); - assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex(); - } - - @OnReceive(url="/{url}?callme={me}", jsonp = "me") - static void fetchViaJSONP(Person p, JSONik model) { - model.setFetched(p); - } - - @Http(@Http.Resource( - content = "$0({'firstName': 'Mitar', 'sex': 'MALE'})", - path="/person22.json", - mimeType = "application/javascript", - parameters = { "callme" } - )) - @BrwsrTest public void loadAndParseJSONP() throws InterruptedException { - - if (js == null) { - orig = scriptElements(); - assert orig > 0 : "There should be some scripts on the page"; - - js = new JSONik(); - js.applyBindings(); - - js.fetchViaJSONP("person22.json"); - } - - Person p = js.getFetched(); - if (p == null) { - throw new InterruptedException(); - } - - assert "Mitar".equals(p.getFirstName()) : "Unexpected: " + p.getFirstName(); - assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex(); - - int now = scriptElements(); - - assert orig == now : "The set of elements is unchanged. Delta: " + (now - orig); - } - - @JavaScriptBody(args = { }, body = "return window.document.getElementsByTagName('script').length;") - private static native int scriptElements(); - - @JavaScriptBody(args = { "s" }, body = "return window.JSON.parse(s);") - private static native Object parseJSON(String s); - - @Http(@Http.Resource( - content = "{'firstName': 'Sitar', 'sex': 'MALE'}", - path="/person15.json", - mimeType = "application/json" - )) - @BrwsrTest public void loadAndParseJSONSentToArray() throws InterruptedException { - if (js == null) { - js = new JSONik(); - js.applyBindings(); - - js.fetchArray("person15.json"); - } - - Person p = js.getFetched(); - if (p == null) { - throw new InterruptedException(); - } - - assert p != null : "We should get our person back: " + p; - assert "Sitar".equals(p.getFirstName()) : "Expecting Sitar: " + p.getFirstName(); - assert Sex.MALE.equals(p.getSex()) : "Expecting MALE: " + p.getSex(); - } - - @Http(@Http.Resource( - content = "[{'firstName': 'Gitar', 'sex': 'FEMALE'}]", - path="/person5.json", - mimeType = "application/json" - )) - @BrwsrTest public void loadAndParseJSONArraySingle() throws InterruptedException { - if (js == null) { - js = new JSONik(); - js.applyBindings(); - - js.fetch("person5.json"); - } - - Person p = js.getFetched(); - if (p == null) { - throw new InterruptedException(); - } - - assert p != null : "We should get our person back: " + p; - assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName(); - assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex(); - } - -// @Http(@Http.Resource( -// content = "{'info':[{'firstName': 'Gitar', 'sex': 'FEMALE'}]}", -// path="/people.json", -// mimeType = "application/json" -// )) -// @BrwsrTest public void loadAndParseArrayInPeople() throws InterruptedException { -// if (js == null) { -// js = new JSONik(); -// js.applyBindings(); -// -// js.fetchPeople("people.json"); -// } -// -// if (0 == js.getFetchedCount()) { -// throw new InterruptedException(); -// } -// -// assert js.getFetchedCount() == 1 : "One person loaded: " + js.getFetchedCount(); -// -// Person p = js.getFetched(); -// -// assert p != null : "We should get our person back: " + p; -// assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName(); -// assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex(); -// } - - @Http(@Http.Resource( - content = "{'age':[1, 2, 3]}", - path="/people8.json", - mimeType = "application/json" - )) - @BrwsrTest public void loadAndParseArrayOfIntegers() throws InterruptedException { - if (js == null) { - js = new JSONik(); - js.applyBindings(); - - js.fetchPeopleAge("people8.json"); - } - - if (0 == js.getFetchedCount()) { - throw new InterruptedException(); - } - - assert js.getFetchedCount() == 6 : "1 + 2 + 3 is " + js.getFetchedCount(); - } - - @OnReceive(url="/{url}") - static void fetchPeopleSex(People p, JSONik model) { - model.setFetchedCount(1); - model.getFetchedSex().addAll(p.getSex()); - } - - - @Http(@Http.Resource( - content = "{'sex':['FEMALE', 'MALE', 'MALE']}", - path="/people11.json", - mimeType = "application/json" - )) - @BrwsrTest public void loadAndParseArrayOfEnums() throws InterruptedException { - if (js == null) { - js = new JSONik(); - js.applyBindings(); - - js.fetchPeopleSex("people11.json"); - } - - if (0 == js.getFetchedCount()) { - throw new InterruptedException(); - } - - assert js.getFetchedCount() == 1 : "Loaded"; - - assert js.getFetchedSex().size() == 3 : "Three values " + js.getFetchedSex(); - assert js.getFetchedSex().get(0) == Sex.FEMALE : "Female first " + js.getFetchedSex(); - assert js.getFetchedSex().get(1) == Sex.MALE : "male 2nd " + js.getFetchedSex(); - assert js.getFetchedSex().get(2) == Sex.MALE : "male 3rd " + js.getFetchedSex(); - } - - @Http(@Http.Resource( - content = "[{'firstName': 'Gitar', 'sex': 'FEMALE'}," - + "{'firstName': 'Peter', 'sex': 'MALE'}" - + "]", - path="/person13.json", - mimeType = "application/json" - )) - @BrwsrTest public void loadAndParseJSONArray() throws InterruptedException { - if (js == null) { - js = new JSONik(); - js.applyBindings(); - js.fetchArray("person13.json"); - } - - - Person p = js.getFetched(); - if (p == null) { - throw new InterruptedException(); - } - - assert js.getFetchedCount() == 2 : "We got two values: " + js.getFetchedCount(); - assert p != null : "We should get our person back: " + p; - assert "Gitar".equals(p.getFirstName()) : "Expecting Gitar: " + p.getFirstName(); - assert Sex.FEMALE.equals(p.getSex()) : "Expecting FEMALE: " + p.getSex(); - } - - @Factory public static Object[] create() { - return VMTest.create(JSONTest.class); - } - -} diff -r 0d2acba8bcfd -r 97cb2c5aa4fc rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java --- a/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java Sat Jan 10 19:38:00 2015 +0100 +++ b/rt/aot/src/main/java/org/apidesign/bck2brwsr/aot/Bck2BrwsrJars.java Sun Jan 11 13:20:32 2015 +0100 @@ -96,8 +96,35 @@ public static Bck2Brwsr configureFrom( Bck2Brwsr c, File jar, final ClassLoader classpath ) throws IOException { + return configureFrom(c, jar, classpath, true); + } + + /** Creates new compiler pre-configured from the content of + * provided JAR file. The compiler will compile all classes. + * The system understands OSGi manifest entries and NetBeans + * module system manifest entries and will export + * all packages that are exported in the JAR file. The system + * also recognizes META-INF/services and makes sure the class names + * are not mangled. + * + * @param c the compiler to {@link Bck2Brwsr#addClasses(java.lang.String...) add classes}, + * {@link Bck2Brwsr#addResources(java.lang.String...) add resources} and + * {@link Bck2Brwsr#addExported(java.lang.String...) exported objects} to. + * Can be null - in such case an + * {@link Bck2Brwsr#newCompiler() empty compiler} is constructed. + * @param jar the file to process + * @param classpath additional resources to make available during + * compilation, but not include them in the generated JavaScript + * @param ignoreBootClassPath should we ignore classes on bootclasspath? + * @return newly configured compiler + * @throws IOException if something goes wrong + * @since 0.14 + */ + public static Bck2Brwsr configureFrom( + Bck2Brwsr c, File jar, final ClassLoader classpath, final boolean ignoreBootClassPath + ) throws IOException { if (jar.isDirectory()) { - return configureDir(c, jar, classpath); + return configureDir(ignoreBootClassPath, c, jar, classpath); } final JarFile jf = new JarFile(jar); final List classes = new ArrayList<>(); @@ -105,7 +132,7 @@ Set exported = new HashSet<>(); class JarRes extends EmulationResources implements Bck2Brwsr.Resources { JarRes() { - super(classpath, classes); + super(ignoreBootClassPath, classpath, classes); } @Override public InputStream get(String resource) throws IOException { @@ -236,8 +263,10 @@ private final Map converted = new HashMap<>(); private final BytecodeProcessor proc; private final ClassLoader cp; + private final boolean ignoreBootClassPath; - protected EmulationResources(ClassLoader cp, List classes) { + protected EmulationResources(boolean ignoreBootClassPath, ClassLoader cp, List classes) { + this.ignoreBootClassPath = ignoreBootClassPath; this.classes = classes; this.cp = cp != null ? cp : Bck2BrwsrJars.class.getClassLoader(); BytecodeProcessor p; @@ -273,7 +302,7 @@ LOG.log(Level.FINE, "Cannot find {0}", name); return null; } - if (u.toExternalForm().contains("/rt.jar!")) { + if (ignoreBootClassPath && u.toExternalForm().contains("/rt.jar!")) { LOG.log(Level.WARNING, "No bootdelegation for {0}", name); return null; } @@ -307,12 +336,12 @@ } } - private static Bck2Brwsr configureDir(Bck2Brwsr c, final File dir, ClassLoader cp) throws IOException { + private static Bck2Brwsr configureDir(final boolean ignoreBootClassPath, Bck2Brwsr c, final File dir, ClassLoader cp) throws IOException { List arr = new ArrayList<>(); List classes = new ArrayList<>(); class DirRes extends EmulationResources { public DirRes(ClassLoader cp, List classes) { - super(cp, classes); + super(ignoreBootClassPath, cp, classes); } @Override diff -r 0d2acba8bcfd -r 97cb2c5aa4fc rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AOTLibrary.java --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AOTLibrary.java Sat Jan 10 19:38:00 2015 +0100 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AOTLibrary.java Sun Jan 11 13:20:32 2015 +0100 @@ -78,7 +78,10 @@ @Parameter private String[] aotDeps; - + + @Parameter(defaultValue = "true") + private boolean ignoreBootClassPath; + @Override public void execute() throws MojoExecutionException, MojoFailureException { URLClassLoader loader; @@ -161,7 +164,7 @@ continue; } getLog().info("Generating bck2brwsr for " + a.getFile()); - Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile(), loader); + Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile(), loader, ignoreBootClassPath); if (exports != null) { for (String e : exports) { c = c.addExported(e.replace('.', '/')); @@ -197,7 +200,7 @@ } private Bck2Brwsr configureMain(URLClassLoader loader) throws IOException { - Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar, loader); + Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar, loader, ignoreBootClassPath); if (exports != null) { for (String e : exports) { c = c.addExported(e.replace('.', '/')); diff -r 0d2acba8bcfd -r 97cb2c5aa4fc rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java Sat Jan 10 19:38:00 2015 +0100 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/AheadOfTime.java Sun Jan 11 13:20:32 2015 +0100 @@ -85,6 +85,9 @@ @Parameter(defaultValue = "true") private boolean generateAotLibraries; + @Parameter(defaultValue = "true") + private boolean ignoreBootClassPath; + /** * The obfuscation level for the generated JavaScript file. * @@ -131,7 +134,7 @@ getLog().info("Skipping " + mainJavaScript + " as it already exists."); } else { getLog().info("Generating " + mainJavaScript); - Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar, loader); + Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, mainJar, loader, ignoreBootClassPath); if (exports != null) { for (String e : exports) { c = c.addExported(e.replace('.', '/')); @@ -201,7 +204,7 @@ } getLog().info("Generating " + js); Writer w = new OutputStreamWriter(new FileOutputStream(js), "UTF-8"); - Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile(), loader); + Bck2Brwsr c = Bck2BrwsrJars.configureFrom(null, a.getFile(), loader, ignoreBootClassPath); c. obfuscation(obfuscation). generate(w); diff -r 0d2acba8bcfd -r 97cb2c5aa4fc rt/vm/pom.xml --- a/rt/vm/pom.xml Sat Jan 10 19:38:00 2015 +0100 +++ b/rt/vm/pom.xml Sun Jan 11 13:20:32 2015 +0100 @@ -105,7 +105,7 @@ com.google.javascript closure-compiler - r2388 + v20141215 compile