# HG changeset patch # User Jaroslav Tulach # Date 1368437973 -7200 # Node ID b6fd8b9ccc7a4532966c03abddc40a4b3f379354 # Parent 4fdc25a60e66759b476071ea0a4325c05c61702b First sketch of the Knockout4J archetype diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/pom.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,88 @@ + + + 4.0.0 + + html + org.apidesign + 0.3-SNAPSHOT + + org.apidesign.html + knockout4j-archetype + 0.3-SNAPSHOT + jar + Knockout 4 Java Maven Archetype + + HTML page with Knockout.js bindings driven by application model + written in Java. Use your favorite language to code. Use + HTML as a lightweight rendering toolkit. Deploy using JavaFX or + bck2brwsr virtual machine. + + + + + src/main/resources + true + + **/pom.xml + + + + src/main/resources + false + + **/pom.xml + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.6 + + \ + 1.6 + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + test + + test + + integration-test + + + ${project.build.directory}/knockout4j-archetype-${project.version}.jar + + false + + + + + + + + + + org.testng + testng + test + + + diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/java/org/apidesign/html/archetype/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/java/org/apidesign/html/archetype/package-info.java Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,21 @@ +/** + * HTML via Java(tm) Language Bindings + * Copyright (C) 2013 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. apidesign.org + * designates this particular file as subject to the + * "Classpath" exception as provided by apidesign.org + * in the License file that accompanied this code. + * + * 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://wiki.apidesign.org/wiki/GPLwithClassPathException + */ +package org.apidesign.html.archetype; diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/META-INF/maven/archetype-metadata.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,37 @@ + + + + + src/main/java + + **/App.java + + + + src/main/resources + + **/*.xhtml + **/*.html + + + + src/test/java + + **/*Test.java + + + + + + nbactions*.xml + + + + assembly + + fxbrwsr-assembly.xml + bck2brwsr-assembly.xml + + + + \ No newline at end of file diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/nbactions-bck2brwsr.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/nbactions-bck2brwsr.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,10 @@ + + + + run + + process-classes + bck2brwsr:brwsr + + + diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/nbactions-fxbrwsr.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/nbactions-fxbrwsr.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,20 @@ + + + + run + + process-classes + bck2brwsr:brwsr + + + + debug + + process-classes + bck2brwsr:brwsr + + + maven + + + diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/nbactions.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/nbactions.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,20 @@ + + + + run + + process-classes + bck2brwsr:brwsr + + + + debug + + process-classes + bck2brwsr:brwsr + + + maven + + + diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/pom.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/pom.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,265 @@ + + + 4.0.0 + + \${groupId} + \${artifactId} + \${version} + jar + + \${artifactId} + + + + java.net + Java.net + https://maven.java.net/content/repositories/releases/ + + true + + + + netbeans + NetBeans + http://bits.netbeans.org/maven2/ + + + + + java.net + Java.net + https://maven.java.net/content/repositories/releases/ + + true + + + + + + UTF-8 + ${project.version} + ${bck2brwsr.version} + MINIMAL + org/apidesign/html/demo/twitter/index.html + + + + + org.apidesign.bck2brwsr + bck2brwsr-maven-plugin + \${bck2brwsr.version} + + + + brwsr + + + + + \${brwsr.startpage} + \${brwsr} + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.14.1 + + + \${brwsr} + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + lib/ + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + + + + + + + org.testng + testng + 6.5.2 + test + + + org.apidesign.bck2brwsr + vmtest + \${bck2brwsr.version} + test + + + org.apidesign.html + net.java.html.json + \${net.java.html.version} + jar + + + + + fxbrwsr + + true + + + fxbrwsr + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + org.apidesign.bck2brwsr.launcher.FXBrwsrLauncher + true + lib/ + + + \${brwsr.startpage} + + + + + + maven-assembly-plugin + 2.4 + + + distro-assembly + package + + single + + + + src/main/assembly/fxbrwsr.xml + + + + + + + + + + org.apidesign.html + ko-fx + \${net.java.html.version} + + + org.apidesign.bck2brwsr + launcher.fx + \${bck2brwsr.version} + runtime + + + + + bck2brwsr + + + brwsr + bck2brwsr + + + + + + org.apidesign.bck2brwsr + bck2brwsr-maven-plugin + + + + j2js + + + + + \${project.build.directory}/bck2brwsr.js + \${bck2brwsr.obfuscationlevel} + + + + org.apache.maven.plugins + maven-compiler-plugin + + + netbeans.ignore.jdk.bootclasspath + + + + + maven-assembly-plugin + 2.4 + + + distro-assembly + package + + single + + + + src/main/assembly/bck2brwsr.xml + + + + + + + + + + org.apidesign.bck2brwsr + emul + \${bck2brwsr.version} + rt + + + org.apidesign.html + ko-bck2brwsr + \${net.java.html.version} + runtime + + + org.apidesign.bck2brwsr + launcher.http + \${bck2brwsr.version} + test + + + + + diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/src/main/assembly/bck2brwsr.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/src/main/assembly/bck2brwsr.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,43 @@ + + + + bck2brwsr + + zip + + public_html + + + false + runtime + lib + + *:jar + *:rt + + + + + + ${project.build.directory}/classes/org/apidesign/html/demo/twitter/ + + **/* + + + **/*.class + + / + + + + + ${project.build.directory}/${project.build.finalName}.jar + / + + + ${project.build.directory}/bck2brwsr.js + / + + + \ No newline at end of file diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/src/main/assembly/fxbrwsr.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/src/main/assembly/fxbrwsr.xml Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,23 @@ + + + + fxbrwsr + + zip + + ${project.build.finalName}-fxbrwsr + + + false + runtime + lib + + + + + ${project.build.directory}/${project.build.finalName}.jar + / + + + \ No newline at end of file diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/src/main/java/App.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/src/main/java/App.java Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,88 @@ +package ${package}; + +import java.util.List; +import org.apidesign.bck2brwsr.htmlpage.api.*; +import static org.apidesign.bck2brwsr.htmlpage.api.OnEvent.*; +import org.apidesign.bck2brwsr.htmlpage.api.Page; +import org.apidesign.bck2brwsr.htmlpage.api.Property; +import org.apidesign.bck2brwsr.htmlpage.api.ComputedProperty; + +/** This is the controller class for associated index.html page. The Index + * is autogenerated by parsing the index.html page. It fields represent individual + * elements annotated by "id" in the page. + */ +@Page(xhtml="index.html", className="Index", properties={ + @Property(name="name", type=String.class), + @Property(name="messages", type=String.class, array=true), +}) +public class App { + static { + Index model = new Index(); + model.setName("World"); + model.applyBindings(); + } + + /** + * @param m the model of the index page creates in static initializer + */ + @On(event = CLICK, id="hello") + static void hello(Index m) { + display(m.getHelloMessage(), m); + m.getMessages().add(m.getHelloMessage()); + } + + /** Reacts when mouse moves over the canvas. + * + * @param m the model of the page + * @param x property "x" extracted from the event generated by the browser + * @param y property "y" from the mouse event + */ + @On(event = MOUSE_MOVE, id="canvas") + static void clearPoint(Index m, int x, int y) { + GraphicsContext g = m.canvas.getContext(); + boolean even = (x + y) % 2 == 0; + if (even) { + g.setFillStyle("blue"); + } else { + g.setFillStyle("red"); + } + g.clearRect(0, 0, 1000, 1000); + g.setFont("italic 40px Calibri"); + g.fillText(m.getHelloMessage(), 10, 40); + } + + /** Callback function called by the KnockOut/Java binding on elements + * representing href's with individual messages being their data. + * + * @param data the data associated with the element + * @param m the model of the page + */ + @OnFunction + static void display(String data, Index m) { + GraphicsContext g = m.canvas.getContext(); + g.clearRect(0, 0, 1000, 1000); + g.setFillStyle("black"); + g.setFont("italic 40px Calibri"); + g.fillText(data, 10, 40); + } + + /** Callback function. + * + * @param data data associated with the actual element on the page + * @param m the model of the page + */ + @OnFunction + static void remove(String data, Index m) { + m.getMessages().remove(data); + } + + @ComputedProperty + static String helloMessage(String name) { + return "Hello " + name + "!"; + } + + @ComputedProperty + static boolean noMessages(List messages) { + return messages.isEmpty(); + } +} diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/src/main/resources/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/src/main/resources/index.html Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,31 @@ + + + + + Bck2Brwsr's Hello World + + +

Loading Bck2Brwsr's Hello World...

+ Your name: + +

+ + +

+ + +
No message displayed yet.
+ + + + + + diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/src/test/java/AppTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/src/test/java/AppTest.java Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,26 @@ +package ${package}; + +import static org.testng.Assert.*; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** Demonstrating POJO testing of HTML page model. Runs in good old HotSpot + * as it does not reference any HTML elements or browser functionality. Just + * operates on the page model. + * + * @author Jaroslav Tulach + */ +public class AppTest { + private Index model; + + + @BeforeMethod + public void initModel() { + model = new Index().applyBindings(); + } + + @Test public void testHelloMessage() { + model.setName("Joe"); + assertEquals(model.getHelloMessage(), "Hello Joe!", "Cleared after pressing +"); + } +} diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/src/test/java/InconsistencyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/src/test/java/InconsistencyTest.java Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,40 @@ +package ${package}; + +import org.apidesign.bck2brwsr.vmtest.Compare; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** Bck2brwsr cares about compatibility with real Java. Whatever API is + * supported by bck2brwsr, it needs to behave the same way as when running + * in HotSpot VM. + *

+ * There can be bugs, however. To help us fix them, we kindly ask you to + * write an "inconsistency" test. A test that compares behavior of the API + * between real VM and bck2brwsr VM. This class is skeleton of such test. + * + * @author Jaroslav Tulach + */ +public class InconsistencyTest { + /** A method to demonstrate inconsistency between bck2brwsr and HotSpot. + * Make calls to an API that behaves strangely, return some result at + * the end. No need to use any assert. + * + * @return value to compare between HotSpot and bck2brwsr + */ + @Compare + public int checkStringHashCode() throws Exception { + return "Is string hashCode the same?".hashCode(); + } + + /** Factory method that creates a three tests for each method annotated with + * {@link org.apidesign.bck2brwsr.vmtest.Compare}. One executes the code in + * HotSpot, one in Rhino and the last one compares the results. + * + * @see org.apidesign.bck2brwsr.vmtest.VMTest + */ + @Factory + public static Object[] create() { + return VMTest.create(InconsistencyTest.class); + } + +} diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/main/resources/archetype-resources/src/test/java/IntegrationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/main/resources/archetype-resources/src/test/java/IntegrationTest.java Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,46 @@ +package ${package}; + +import org.apidesign.bck2brwsr.htmlpage.api.OnEvent; +import org.apidesign.bck2brwsr.vmtest.BrwsrTest; +import org.apidesign.bck2brwsr.vmtest.HtmlFragment; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** Sometimes it is useful to run tests inside of the real browser. + * To do that just annotate your method with {@link org.apidesign.bck2brwsr.vmtest.BrwsrTest} + * and that is it. If your code references elements on the HTML page, + * you can pass in an {@link org.apidesign.bck2brwsr.vmtest.HtmlFragment} which + * will be made available on the page before your test starts. + * + * @author Jaroslav Tulach + */ +public class IntegrationTest { + + /** Write to testing code here. Use assert (but not TestNG's + * Assert, as TestNG is not compiled with target 1.6 yet). + */ + @HtmlFragment( + "

Loading Bck2Brwsr's Hello World...

\n" + + "Your name: \n" + + "\n" + + "

\n" + + " \n" + + "

\n" + ) + @BrwsrTest + public void modifyValueAssertChangeInModel() { + Index m = new Index(); + m.setName("Joe Hacker"); + m.applyBindings(); + assert "Joe Hacker".equals(m.input.getValue()) : "Value is really Joe Hacker: " + m.input.getValue(); + m.input.setValue("Happy Joe"); + m.triggerEvent(m.input, OnEvent.CHANGE); + assert "Happy Joe".equals(m.getName()) : "Name property updated to Happy Joe: " + m.getName(); + } + + @Factory + public static Object[] create() { + return VMTest.create(IntegrationTest.class); + } + +} diff -r 4fdc25a60e66 -r b6fd8b9ccc7a ko-archetype/src/test/java/org/apidesign/html/archetype/ArchetypeVersionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ko-archetype/src/test/java/org/apidesign/html/archetype/ArchetypeVersionTest.java Mon May 13 11:39:33 2013 +0200 @@ -0,0 +1,98 @@ +/** + * HTML via Java(tm) Language Bindings + * Copyright (C) 2013 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. apidesign.org + * designates this particular file as subject to the + * "Classpath" exception as provided by apidesign.org + * in the License file that accompanied this code. + * + * 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://wiki.apidesign.org/wiki/GPLwithClassPathException + */ +package org.apidesign.html.archetype; + +import java.net.URL; +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; +import org.testng.annotations.Test; +import static org.testng.Assert.*; +import org.testng.annotations.BeforeClass; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; + +/** + * + * @author Jaroslav Tulach + */ +public class ArchetypeVersionTest { + private String version; + + public ArchetypeVersionTest() { + } + + @BeforeClass public void readCurrentVersion() throws Exception { + final ClassLoader l = ArchetypeVersionTest.class.getClassLoader(); + URL u = l.getResource("META-INF/maven/org.apidesign.html/knockout4j-archetype/pom.xml"); + assertNotNull(u, "Own pom found: " + System.getProperty("java.class.path")); + + final XPathFactory fact = XPathFactory.newInstance(); + fact.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + + XPathExpression xp = fact.newXPath().compile("project/version/text()"); + + Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(u.openStream()); + version = xp.evaluate(dom); + + assertFalse(version.isEmpty(), "There should be some version string"); + } + + + @Test public void testComparePomDepsVersions() throws Exception { + final ClassLoader l = ArchetypeVersionTest.class.getClassLoader(); + URL r = l.getResource("archetype-resources/pom.xml"); + assertNotNull(r, "Archetype pom found"); + + final XPathFactory fact = XPathFactory.newInstance(); + XPathExpression xp2 = fact.newXPath().compile( + "//properties/net.java.html.version/text()" + ); + + Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(r.openStream()); + String arch = (String) xp2.evaluate(dom, XPathConstants.STRING); + + assertEquals(arch, version, "net.java.html.json dependency needs to be on latest version"); + } + + @Test public void testNbActions() throws Exception { + final ClassLoader l = ArchetypeVersionTest.class.getClassLoader(); + URL r = l.getResource("archetype-resources/nbactions.xml"); + assertNotNull(r, "Archetype nb file found"); + + final XPathFactory fact = XPathFactory.newInstance(); + XPathExpression xp2 = fact.newXPath().compile( + "//goal/text()" + ); + + Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(r.openStream()); + NodeList goals = (NodeList) xp2.evaluate(dom, XPathConstants.NODESET); + + for (int i = 0; i < goals.getLength(); i++) { + String s = goals.item(i).getTextContent(); + if (s.contains("apidesign")) { + assertFalse(s.matches(".*apidesign.*[0-9].*"), "No numbers: " + s); + } + } + } +}